From 35df5441d3e2789663532c948731aff3a1e04728 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax Date: Mon, 14 Jun 2010 12:04:49 +0200 Subject: [PATCH 001/239] llmediaplugins first step --- linden/doc/LICENSE-logos.txt | 23 + linden/doc/contributions.txt | 7 +- linden/etc/message.xml | 16 + linden/indra/CMakeLists.txt | 10 +- linden/indra/cmake/00-Common.cmake | 4 +- linden/indra/cmake/FindNDOF.cmake | 39 + linden/indra/cmake/GStreamer010Plugin.cmake | 39 + linden/indra/cmake/Glui.cmake | 28 + linden/indra/cmake/Glut.cmake | 19 + linden/indra/cmake/LLAudio.cmake | 2 - linden/indra/cmake/LLMedia.cmake | 13 - linden/indra/cmake/LLPlugin.cmake | 8 + linden/indra/cmake/MediaPluginBase.cmake | 8 + linden/indra/cmake/Mozlib.cmake | 47 - linden/indra/cmake/NDOF.cmake | 32 +- linden/indra/cmake/OPENAL.cmake | 13 +- linden/indra/cmake/OPENAL.cmake.imp | 115 + linden/indra/cmake/PluginAPI.cmake | 16 + linden/indra/cmake/QuickTimePlugin.cmake | 46 + linden/indra/cmake/WebKitLibPlugin.cmake | 55 + ...findra%2fcmake%2fCopyWinLibs.cmake.rej.txt | 257 ++ linden/indra/llaudio/CMakeLists.txt | 43 +- linden/indra/llaudio/listener.cpp | 153 -- linden/indra/llaudio/listener.h | 80 - linden/indra/llaudio/listener_ds3d.h | 76 - linden/indra/llaudio/listener_fmod.cpp | 143 -- linden/indra/llaudio/listener_fmod.h | 67 - linden/indra/llaudio/llaudiodecodemgr.cpp | 62 +- .../{audioengine.cpp => llaudioengine.cpp} | 303 +-- .../{audioengine.h => llaudioengine.h} | 57 +- ...engine_fmod.cpp => llaudioengine_fmod.cpp} | 361 +-- ...udioengine_fmod.h => llaudioengine_fmod.h} | 42 +- ...ne_openal.cpp => llaudioengine_openal.cpp} | 38 +- ...engine_openal.h => llaudioengine_openal.h} | 8 +- linden/indra/llaudio/lllistener.cpp | 142 ++ linden/indra/llaudio/lllistener.h | 78 + linden/indra/llaudio/lllistener_ds3d.h | 74 + linden/indra/llaudio/lllistener_fmod.cpp | 131 + linden/indra/llaudio/lllistener_fmod.h | 64 + ...tener_openal.cpp => lllistener_openal.cpp} | 13 +- ...{listener_openal.h => lllistener_openal.h} | 8 +- linden/indra/llaudio/llstreamingaudio.h | 56 + .../indra/llaudio/llstreamingaudio_fmod.cpp | 362 +++ linden/indra/llaudio/llstreamingaudio_fmod.h | 68 + .../{vorbisdecode.cpp => llvorbisdecode.cpp} | 0 .../{vorbisdecode.h => llvorbisdecode.h} | 0 linden/indra/llaudio/llvorbisencode.cpp | 505 ++++ .../{vorbisencode.h => llvorbisencode.h} | 11 + .../indra/llaudio/{windgen.h => llwindgen.h} | 0 linden/indra/llcommon/CMakeLists.txt | 2 + linden/indra/llcommon/llerrorcontrol.h | 1 + linden/indra/llcommon/llprocesslauncher.cpp | 346 +++ linden/indra/llcommon/llprocesslauncher.h | 86 + linden/indra/llinventory/llparcel.cpp | 125 + linden/indra/llinventory/llparcel.h | 25 + linden/indra/llmath/CMakeLists.txt | 1 + linden/indra/llmath/llmath.h | 10 +- linden/indra/llmath/llvolume.cpp | 8 +- linden/indra/llmath/llvolume.h | 10 +- linden/indra/llmath/v3math.h | 4 +- linden/indra/llmedia/CMakeLists.txt | 79 - linden/indra/llmedia/llgstplaythread.cpp | 54 - linden/indra/llmedia/llgstplaythread.h | 62 - linden/indra/llmedia/llmediabase.h | 265 -- linden/indra/llmedia/llmediaemitter.h | 104 - linden/indra/llmedia/llmediaimplcommon.cpp | 552 ----- linden/indra/llmedia/llmediaimplcommon.h | 164 -- linden/indra/llmedia/llmediaimplexample1.cpp | 231 -- linden/indra/llmedia/llmediaimplexample2.cpp | 198 -- linden/indra/llmedia/llmediaimplfactory.cpp | 105 - linden/indra/llmedia/llmediaimplfactory.h | 100 - linden/indra/llmedia/llmediaimplgstreamer.h | 164 -- linden/indra/llmedia/llmediaimplllmozlib.cpp | 624 ----- linden/indra/llmedia/llmediaimplllmozlib.h | 127 - linden/indra/llmedia/llmediaimplquicktime.cpp | 657 ----- linden/indra/llmedia/llmediaimplquicktime.h | 112 - linden/indra/llmedia/llmediamanager.cpp | 295 --- linden/indra/llmedia/llmediamanager.h | 127 - linden/indra/llmedia/llmediaobserver.h | 116 - linden/indra/llmessage/tests/commtest.h | 83 + linden/indra/llmessage/tests/llcurl_stub.cpp | 100 + .../tests/llhttpclientadapter_test.cpp | 170 ++ .../lltemplatemessagedispatcher_test.cpp | 165 ++ .../tests/lltesthttpclientadapter.cpp | 67 + .../llmessage/tests/lltesthttpclientadapter.h | 63 + .../llmessage/tests/lltestmessagesender.cpp | 44 + .../llmessage/tests/lltestmessagesender.h | 57 + .../tests/lltrustedmessageservice_test.cpp | 146 ++ linden/indra/llmessage/tests/networkio.h | 116 + .../llmessage/tests/test_llsdmessage_peer.py | 153 ++ linden/indra/llplugin/CMakeLists.txt | 55 + linden/indra/llplugin/llpluginclassmedia.cpp | 1162 +++++++++ linden/indra/llplugin/llpluginclassmedia.h | 352 +++ .../indra/llplugin/llpluginclassmediaowner.h | 82 + linden/indra/llplugin/llplugininstance.cpp | 172 ++ linden/indra/llplugin/llplugininstance.h | 104 + linden/indra/llplugin/llpluginmessage.cpp | 442 ++++ linden/indra/llplugin/llpluginmessage.h | 142 ++ .../indra/llplugin/llpluginmessageclasses.h | 57 + linden/indra/llplugin/llpluginmessagepipe.cpp | 316 +++ linden/indra/llplugin/llpluginmessagepipe.h | 92 + .../indra/llplugin/llpluginprocesschild.cpp | 490 ++++ linden/indra/llplugin/llpluginprocesschild.h | 112 + .../indra/llplugin/llpluginprocessparent.cpp | 714 ++++++ linden/indra/llplugin/llpluginprocessparent.h | 169 ++ .../indra/llplugin/llpluginsharedmemory.cpp | 506 ++++ linden/indra/llplugin/llpluginsharedmemory.h | 130 + linden/indra/llplugin/slplugin/CMakeLists.txt | 55 + linden/indra/llplugin/slplugin/slplugin.cpp | 288 +++ .../llplugin/slplugin/slplugin_info.plist | 12 + linden/indra/llui/CMakeLists.txt | 15 +- linden/indra/llui/llbutton.cpp | 5 + linden/indra/llui/llbutton.h | 3 +- linden/indra/llui/llfloater.cpp | 8 +- linden/indra/llui/llfocusmgr.cpp | 84 +- linden/indra/llui/llfocusmgr.h | 49 +- linden/indra/llui/lliconctrl.cpp | 6 + linden/indra/llui/lliconctrl.h | 2 + linden/indra/llui/llmultisliderctrl.cpp | 3 - linden/indra/llui/llpanel.cpp | 19 +- linden/indra/llui/llpanel.h | 3 + linden/indra/llui/llsliderctrl.cpp | 2 - linden/indra/llui/llspinctrl.cpp | 1 - linden/indra/llui/lltextparser.cpp | 48 +- linden/indra/llui/lltextparser.h | 7 +- linden/indra/llui/llui.cpp | 1 - linden/indra/llui/lluictrl.cpp | 55 +- linden/indra/llui/lluictrl.h | 26 +- linden/indra/llui/llview.cpp | 7 +- linden/indra/llui/llview.h | 14 +- linden/indra/llvfs/CMakeLists.txt | 2 +- linden/indra/llvfs/lldir.cpp | 6 + linden/indra/llvfs/lldir.h | 6 + linden/indra/llvfs/lldir_linux.cpp | 43 +- linden/indra/llvfs/lldir_linux.h | 3 + linden/indra/llvfs/lldir_mac.cpp | 15 + linden/indra/llvfs/lldir_mac.h | 3 + linden/indra/llvfs/lldir_solaris.cpp | 2 + linden/indra/llvfs/lldir_win32.cpp | 15 + linden/indra/llvfs/lldir_win32.h | 3 + linden/indra/llwindow/CMakeLists.txt | 14 +- linden/indra/media_plugins/CMakeLists.txt | 11 + .../indra/media_plugins/base/CMakeLists.txt | 41 + .../media_plugins/base/media_plugin_base.cpp | 155 ++ .../media_plugins/base/media_plugin_base.exp | 1 + .../media_plugins/base/media_plugin_base.h | 112 + .../media_plugins/example/CMakeLists.txt | 74 + .../example/media_plugin_example.cpp | 488 ++++ .../media_plugins/gstreamer010/CMakeLists.txt | 71 + .../gstreamer010/llmediaimplgstreamer.h} | 47 +- .../llmediaimplgstreamer_syms.cpp | 171 ++ .../gstreamer010/llmediaimplgstreamer_syms.h | 78 + .../llmediaimplgstreamer_syms_raw.inc | 51 + .../llmediaimplgstreamer_syms_rawv.inc | 5 + .../llmediaimplgstreamertriviallogging.h | 53 + .../llmediaimplgstreamervidplug.cpp | 252 +- .../llmediaimplgstreamervidplug.h | 13 +- .../media_plugin_gstreamer010.cpp | 1202 +++++++++ .../media_plugin_gstreamer010.cpp~ | 1219 +++++++++ .../media_plugins/quicktime/CMakeLists.txt | 83 + .../quicktime/media_plugin_quicktime.cpp | 985 ++++++++ .../indra/media_plugins/webkit/CMakeLists.txt | 82 + .../webkit/media_plugin_webkit.cpp | 932 +++++++ linden/indra/newview/CMakeLists.txt | 100 +- .../indra/newview/app_settings/settings.xml | 35 +- linden/indra/newview/chatbar_as_cmdline.cpp | 4 +- linden/indra/newview/floatervoicelicense.cpp | 4 +- linden/indra/newview/floatervoicelicense.h | 8 +- linden/indra/newview/llagent.cpp | 6 + linden/indra/newview/llappviewer.cpp | 20 +- linden/indra/newview/llappviewerlinux.cpp | 2 +- linden/indra/newview/llappviewermacosx.cpp | 4 +- .../indra/newview/llassetuploadresponders.cpp | 5 +- linden/indra/newview/llaudiosourcevo.h | 2 +- linden/indra/newview/llchatbar.cpp | 2 +- linden/indra/newview/llcommandhandler.cpp | 6 +- linden/indra/newview/llcommandhandler.h | 10 +- linden/indra/newview/llfirstuse.cpp | 4 +- linden/indra/newview/llfloaterabout.cpp | 27 +- linden/indra/newview/llfloateravatarinfo.cpp | 2 +- linden/indra/newview/llfloaterchat.cpp | 54 +- linden/indra/newview/llfloaterchat.h | 2 + linden/indra/newview/llfloaterclassified.cpp | 2 +- linden/indra/newview/llfloaterevent.cpp | 2 +- linden/indra/newview/llfloatergroupinfo.cpp | 2 +- linden/indra/newview/llfloaterhandler.cpp | 4 +- linden/indra/newview/llfloaterhandler.h | 2 +- linden/indra/newview/llfloaterhtmlsimple.cpp | 6 +- linden/indra/newview/llfloaterhud.cpp | 4 +- linden/indra/newview/llfloaterhud.h | 4 +- linden/indra/newview/llfloaterland.cpp | 12 + linden/indra/newview/llfloaterland.h | 3 + .../indra/newview/llfloatermediabrowser.cpp | 398 +++ ...aterhtmlhelp.h => llfloatermediabrowser.h} | 34 +- .../indra/newview/llfloaterobjectiminfo.cpp | 6 +- linden/indra/newview/llfloaterparcel.cpp | 2 +- linden/indra/newview/llfloaterpreference.cpp | 8 +- linden/indra/newview/llfloatertos.cpp | 33 +- linden/indra/newview/llfloatertos.h | 7 +- linden/indra/newview/llfloaterurlentry.cpp | 2 +- linden/indra/newview/llhoverview.cpp | 3 +- linden/indra/newview/llhoverview.h | 3 + linden/indra/newview/llhudview.cpp | 13 +- linden/indra/newview/llhudview.h | 2 +- linden/indra/newview/llimpanel.cpp | 2 +- linden/indra/newview/llloginhandler.cpp | 2 +- linden/indra/newview/llloginhandler.h | 2 +- linden/indra/newview/llmediactrl.cpp | 1201 +++++++++ linden/indra/newview/llmediactrl.h | 201 ++ linden/indra/newview/llmediaremotectrl.cpp | 57 +- linden/indra/newview/llmimetypes.cpp | 24 + linden/indra/newview/llmimetypes.h | 6 + linden/indra/newview/lloverlaybar.cpp | 17 +- linden/indra/newview/llpanelaudioprefs.cpp | 4 +- linden/indra/newview/llpanelavatar.cpp | 60 +- linden/indra/newview/llpanelavatar.h | 16 +- linden/indra/newview/llpanelclassified.cpp | 2 +- linden/indra/newview/llpaneldebug.cpp | 2 +- linden/indra/newview/llpaneldirfind.cpp | 42 +- linden/indra/newview/llpaneldirfind.h | 15 +- linden/indra/newview/llpaneldirgroups.cpp | 1 + linden/indra/newview/llpanelface.cpp | 33 +- linden/indra/newview/llpanellandaudio.cpp | 195 ++ .../llpanellandaudio.h} | 69 +- linden/indra/newview/llpanellandmedia.cpp | 292 ++- linden/indra/newview/llpanellandmedia.h | 25 +- linden/indra/newview/llpanellogin.cpp | 55 +- linden/indra/newview/llpanellogin.h | 8 +- linden/indra/newview/llpanelmediahud.cpp | 667 +++++ linden/indra/newview/llpanelmediahud.h | 110 + linden/indra/newview/llpanelpermissions.cpp | 2 +- linden/indra/newview/llpanelweb.cpp | 65 +- linden/indra/newview/llprefsvoice.cpp | 4 +- linden/indra/newview/llpreviewscript.cpp | 14 +- linden/indra/newview/llpreviewsound.cpp | 2 +- linden/indra/newview/llselectmgr.cpp | 11 +- linden/indra/newview/llstartup.cpp | 37 +- linden/indra/newview/llstatusbar.cpp | 2 +- linden/indra/newview/lltoolcomp.cpp | 4 - linden/indra/newview/lltoolcomp.h | 1 + linden/indra/newview/lltoolgun.cpp | 7 +- linden/indra/newview/lltoolgun.h | 2 + linden/indra/newview/lltoolmgr.cpp | 14 +- linden/indra/newview/lltoolmorph.cpp | 2 +- linden/indra/newview/lltoolpie.cpp | 208 +- linden/indra/newview/lltoolpie.h | 1 + linden/indra/newview/lltoolplacer.cpp | 2 +- linden/indra/newview/llurldispatcher.cpp | 22 +- linden/indra/newview/llurldispatcher.h | 6 +- linden/indra/newview/llvieweraudio.cpp | 3 +- linden/indra/newview/llviewercontrol.cpp | 19 +- linden/indra/newview/llviewergesture.cpp | 2 +- linden/indra/newview/llviewerimagelist.cpp | 2 +- linden/indra/newview/llviewerkeyboard.cpp | 2 +- linden/indra/newview/llviewermedia.cpp | 1390 +++++++---- linden/indra/newview/llviewermedia.h | 200 +- .../newview/llviewermedia_streamingaudio.cpp | 169 ++ .../newview/llviewermedia_streamingaudio.h | 69 + linden/indra/newview/llviewermediafocus.cpp | 359 +++ linden/indra/newview/llviewermediafocus.h | 91 + .../llviewermediaobserver.h} | 66 +- linden/indra/newview/llviewermenu.cpp | 34 +- linden/indra/newview/llviewermenufile.cpp | 2 +- linden/indra/newview/llviewermessage.cpp | 8 +- linden/indra/newview/llviewerobject.cpp | 2 +- linden/indra/newview/llviewerparcelmedia.cpp | 350 ++- linden/indra/newview/llviewerparcelmedia.h | 31 +- .../newview/llviewerparcelmediaautoplay.cpp | 2 +- .../newview/llviewerparcelmediaautoplay.h | 1 - linden/indra/newview/llviewerparcelmgr.cpp | 80 +- linden/indra/newview/llviewerparcelmgr.h | 5 + linden/indra/newview/llviewerregion.cpp | 6 +- linden/indra/newview/llviewertexteditor.cpp | 2 +- linden/indra/newview/llviewerwindow.cpp | 58 +- linden/indra/newview/llvoavatar.cpp | 17 +- linden/indra/newview/llvovolume.cpp | 2 +- linden/indra/newview/llweb.cpp | 2 +- .../newview/mozilla-powerpc-darwin-readme.txt | 71 - linden/indra/newview/pipeline.cpp | 2 +- .../skins/default/textures/textures.xml | 20 +- .../default/xui/en-us/floater_about_land.xml | 744 +++++- .../xui/en-us/floater_media_browser.xml | 21 +- .../skins/default/xui/en-us/mime_types.xml | 456 ---- .../default/xui/en-us/mime_types_linux.xml | 445 ++++ .../default/xui/en-us/mime_types_mac.xml | 445 ++++ .../default/xui/en-us/mime_types_windows.xml | 445 ++++ .../skins/default/xui/en-us/panel_bars.xml | 3 - .../skins/default/xui/en-us/panel_hud.xml | 4 + .../default/xui/en-us/panel_media_hud.xml | 68 + linden/indra/newview/viewer_manifest.py | 126 +- linden/indra/newview/viewer_manifest.py~ | 1176 +++++++++ .../test_apps/llplugintest/CMakeLists.txt | 378 +++ .../test_apps/llplugintest/bookmarks.txt | 28 + .../llplugintest/demo_media_plugin.cpp | 472 ++++ .../llplugintest/demo_media_plugin_2.cpp | 578 +++++ .../test_apps/llplugintest/demo_plugin.cpp | 220 ++ .../llplugintest/llmediaplugintest.cpp | 2179 +++++++++++++++++ .../llplugintest/llmediaplugintest.h | 201 ++ .../test_apps/llplugintest/media_mappings.txt | 3 + .../llplugintest/media_plugin_test.cpp | 511 ++++ .../llplugintest/media_simple_test.cpp | 460 ++++ .../test_apps/llplugintest/plugin_host.cpp | 92 + .../llplugintest/plugin_process_launcher.cpp | 197 ++ linden/install.xml | 23 +- 304 files changed, 30655 insertions(+), 7758 deletions(-) create mode 100644 linden/doc/LICENSE-logos.txt create mode 100644 linden/indra/cmake/FindNDOF.cmake create mode 100644 linden/indra/cmake/GStreamer010Plugin.cmake create mode 100644 linden/indra/cmake/Glui.cmake create mode 100644 linden/indra/cmake/Glut.cmake delete mode 100644 linden/indra/cmake/LLMedia.cmake create mode 100644 linden/indra/cmake/LLPlugin.cmake create mode 100644 linden/indra/cmake/MediaPluginBase.cmake create mode 100644 linden/indra/cmake/OPENAL.cmake.imp create mode 100644 linden/indra/cmake/PluginAPI.cmake create mode 100644 linden/indra/cmake/QuickTimePlugin.cmake create mode 100644 linden/indra/cmake/WebKitLibPlugin.cmake create mode 100644 linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt rename linden/indra/llaudio/{audioengine.cpp => llaudioengine.cpp} (85%) rename linden/indra/llaudio/{audioengine.h => llaudioengine.h} (92%) rename linden/indra/llaudio/{audioengine_fmod.cpp => llaudioengine_fmod.cpp} (71%) rename linden/indra/llaudio/{audioengine_fmod.h => llaudioengine_fmod.h} (77%) rename linden/indra/llaudio/{audioengine_openal.cpp => llaudioengine_openal.cpp} (93%) rename linden/indra/llaudio/{audioengine_openal.h => llaudioengine_openal.h} (95%) create mode 100644 linden/indra/llaudio/lllistener.cpp create mode 100644 linden/indra/llaudio/lllistener.h create mode 100644 linden/indra/llaudio/lllistener_ds3d.h create mode 100644 linden/indra/llaudio/lllistener_fmod.cpp create mode 100644 linden/indra/llaudio/lllistener_fmod.h rename linden/indra/llaudio/{listener_openal.cpp => lllistener_openal.cpp} (93%) rename linden/indra/llaudio/{listener_openal.h => lllistener_openal.h} (93%) create mode 100644 linden/indra/llaudio/llstreamingaudio.h create mode 100644 linden/indra/llaudio/llstreamingaudio_fmod.cpp create mode 100644 linden/indra/llaudio/llstreamingaudio_fmod.h rename linden/indra/llaudio/{vorbisdecode.cpp => llvorbisdecode.cpp} (100%) rename linden/indra/llaudio/{vorbisdecode.h => llvorbisdecode.h} (100%) create mode 100644 linden/indra/llaudio/llvorbisencode.cpp rename linden/indra/llaudio/{vorbisencode.h => llvorbisencode.h} (76%) rename linden/indra/llaudio/{windgen.h => llwindgen.h} (100%) create mode 100644 linden/indra/llcommon/llprocesslauncher.cpp create mode 100644 linden/indra/llcommon/llprocesslauncher.h delete mode 100644 linden/indra/llmedia/CMakeLists.txt delete mode 100644 linden/indra/llmedia/llgstplaythread.cpp delete mode 100644 linden/indra/llmedia/llgstplaythread.h delete mode 100644 linden/indra/llmedia/llmediabase.h delete mode 100644 linden/indra/llmedia/llmediaemitter.h delete mode 100644 linden/indra/llmedia/llmediaimplcommon.cpp delete mode 100644 linden/indra/llmedia/llmediaimplcommon.h delete mode 100644 linden/indra/llmedia/llmediaimplexample1.cpp delete mode 100644 linden/indra/llmedia/llmediaimplexample2.cpp delete mode 100644 linden/indra/llmedia/llmediaimplfactory.cpp delete mode 100644 linden/indra/llmedia/llmediaimplfactory.h delete mode 100644 linden/indra/llmedia/llmediaimplgstreamer.h delete mode 100644 linden/indra/llmedia/llmediaimplllmozlib.cpp delete mode 100644 linden/indra/llmedia/llmediaimplllmozlib.h delete mode 100644 linden/indra/llmedia/llmediaimplquicktime.cpp delete mode 100644 linden/indra/llmedia/llmediaimplquicktime.h delete mode 100644 linden/indra/llmedia/llmediamanager.cpp delete mode 100644 linden/indra/llmedia/llmediamanager.h delete mode 100644 linden/indra/llmedia/llmediaobserver.h create mode 100644 linden/indra/llmessage/tests/commtest.h create mode 100644 linden/indra/llmessage/tests/llcurl_stub.cpp create mode 100644 linden/indra/llmessage/tests/llhttpclientadapter_test.cpp create mode 100644 linden/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp create mode 100644 linden/indra/llmessage/tests/lltesthttpclientadapter.cpp create mode 100644 linden/indra/llmessage/tests/lltesthttpclientadapter.h create mode 100644 linden/indra/llmessage/tests/lltestmessagesender.cpp create mode 100644 linden/indra/llmessage/tests/lltestmessagesender.h create mode 100644 linden/indra/llmessage/tests/lltrustedmessageservice_test.cpp create mode 100644 linden/indra/llmessage/tests/networkio.h create mode 100644 linden/indra/llmessage/tests/test_llsdmessage_peer.py create mode 100644 linden/indra/llplugin/CMakeLists.txt create mode 100644 linden/indra/llplugin/llpluginclassmedia.cpp create mode 100644 linden/indra/llplugin/llpluginclassmedia.h create mode 100644 linden/indra/llplugin/llpluginclassmediaowner.h create mode 100644 linden/indra/llplugin/llplugininstance.cpp create mode 100644 linden/indra/llplugin/llplugininstance.h create mode 100644 linden/indra/llplugin/llpluginmessage.cpp create mode 100644 linden/indra/llplugin/llpluginmessage.h create mode 100644 linden/indra/llplugin/llpluginmessageclasses.h create mode 100644 linden/indra/llplugin/llpluginmessagepipe.cpp create mode 100644 linden/indra/llplugin/llpluginmessagepipe.h create mode 100644 linden/indra/llplugin/llpluginprocesschild.cpp create mode 100644 linden/indra/llplugin/llpluginprocesschild.h create mode 100644 linden/indra/llplugin/llpluginprocessparent.cpp create mode 100644 linden/indra/llplugin/llpluginprocessparent.h create mode 100644 linden/indra/llplugin/llpluginsharedmemory.cpp create mode 100644 linden/indra/llplugin/llpluginsharedmemory.h create mode 100644 linden/indra/llplugin/slplugin/CMakeLists.txt create mode 100644 linden/indra/llplugin/slplugin/slplugin.cpp create mode 100644 linden/indra/llplugin/slplugin/slplugin_info.plist create mode 100644 linden/indra/media_plugins/CMakeLists.txt create mode 100644 linden/indra/media_plugins/base/CMakeLists.txt create mode 100644 linden/indra/media_plugins/base/media_plugin_base.cpp create mode 100644 linden/indra/media_plugins/base/media_plugin_base.exp create mode 100644 linden/indra/media_plugins/base/media_plugin_base.h create mode 100644 linden/indra/media_plugins/example/CMakeLists.txt create mode 100644 linden/indra/media_plugins/example/media_plugin_example.cpp create mode 100644 linden/indra/media_plugins/gstreamer010/CMakeLists.txt rename linden/indra/{llmedia/llmediaimplregister.h => media_plugins/gstreamer010/llmediaimplgstreamer.h} (66%) create mode 100644 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp create mode 100644 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h create mode 100644 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc create mode 100644 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc create mode 100644 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h rename linden/indra/{llmedia => media_plugins/gstreamer010}/llmediaimplgstreamervidplug.cpp (61%) rename linden/indra/{llmedia => media_plugins/gstreamer010}/llmediaimplgstreamervidplug.h (93%) create mode 100644 linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp create mode 100755 linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ create mode 100644 linden/indra/media_plugins/quicktime/CMakeLists.txt create mode 100644 linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp create mode 100644 linden/indra/media_plugins/webkit/CMakeLists.txt create mode 100644 linden/indra/media_plugins/webkit/media_plugin_webkit.cpp create mode 100644 linden/indra/newview/llfloatermediabrowser.cpp rename linden/indra/newview/{llfloaterhtmlhelp.h => llfloatermediabrowser.h} (78%) create mode 100644 linden/indra/newview/llmediactrl.cpp create mode 100644 linden/indra/newview/llmediactrl.h create mode 100644 linden/indra/newview/llpanellandaudio.cpp rename linden/indra/{llmedia/llmediaimplexample2.h => newview/llpanellandaudio.h} (54%) create mode 100644 linden/indra/newview/llpanelmediahud.cpp create mode 100644 linden/indra/newview/llpanelmediahud.h create mode 100644 linden/indra/newview/llviewermedia_streamingaudio.cpp create mode 100644 linden/indra/newview/llviewermedia_streamingaudio.h create mode 100644 linden/indra/newview/llviewermediafocus.cpp create mode 100644 linden/indra/newview/llviewermediafocus.h rename linden/indra/{llmedia/llmediaimplexample1.h => newview/llviewermediaobserver.h} (56%) create mode 100644 linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/panel_hud.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/panel_media_hud.xml create mode 100755 linden/indra/newview/viewer_manifest.py~ create mode 100644 linden/indra/test_apps/llplugintest/CMakeLists.txt create mode 100644 linden/indra/test_apps/llplugintest/bookmarks.txt create mode 100644 linden/indra/test_apps/llplugintest/demo_media_plugin.cpp create mode 100644 linden/indra/test_apps/llplugintest/demo_media_plugin_2.cpp create mode 100644 linden/indra/test_apps/llplugintest/demo_plugin.cpp create mode 100644 linden/indra/test_apps/llplugintest/llmediaplugintest.cpp create mode 100644 linden/indra/test_apps/llplugintest/llmediaplugintest.h create mode 100644 linden/indra/test_apps/llplugintest/media_mappings.txt create mode 100644 linden/indra/test_apps/llplugintest/media_plugin_test.cpp create mode 100644 linden/indra/test_apps/llplugintest/media_simple_test.cpp create mode 100644 linden/indra/test_apps/llplugintest/plugin_host.cpp create mode 100644 linden/indra/test_apps/llplugintest/plugin_process_launcher.cpp mode change 100755 => 100644 linden/install.xml diff --git a/linden/doc/LICENSE-logos.txt b/linden/doc/LICENSE-logos.txt new file mode 100644 index 000000000..e63c48e54 --- /dev/null +++ b/linden/doc/LICENSE-logos.txt @@ -0,0 +1,23 @@ +COPYRIGHT AND PERMISSION NOTICE + +Second Life(TM) Viewer Artwork. Copyright (C) 2008 Linden Research, Inc. + +Linden Research, Inc. ("Linden Lab") licenses the Second Life viewer +artwork and other works in the files distributed with this Notice under +the Creative Commons Attribution-Share Alike 3.0 License, available at +http://creativecommons.org/licenses/by-sa/3.0/legalcode. For the license +summary, see http://creativecommons.org/licenses/by-sa/3.0/. + +Notwithstanding the foregoing, all of Linden Lab's trademarks, including +but not limited to the Second Life brand name and Second Life Eye-in-Hand +logo, are subject to our trademark policy at +http://secondlife.com/corporate/trademark/. + +If you distribute any copies or adaptations of the Second Life viewer +artwork or any other works in these files, you must include this Notice +and clearly identify any changes made to the original works. Include +this Notice and information where copyright notices are usually included, +for example, after your own copyright notice acknowledging your use of +the Second Life viewer artwork, in a text file distributed with your +program, in your application's About window, or on a credits page for +your work. diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index c3d5e5989..329fc2855 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -85,11 +85,6 @@ Alissa Sabre VWR-7087 VWR-7153 VWR-7168 -<<<<<<< HEAD -======= - VWR-7087 - VWR-7086 ->>>>>>> origin/next VWR-9190 VWR-10728 VWR-12620 @@ -558,6 +553,8 @@ TBBle Kurosawa VWR-1892 Teardrops Fall VWR-5366 +Techwolf Lupindo + SNOW-334 tenebrous pau VWR-247 Tharax Ferraris diff --git a/linden/etc/message.xml b/linden/etc/message.xml index dd149dd1b..6598344c8 100644 --- a/linden/etc/message.xml +++ b/linden/etc/message.xml @@ -377,7 +377,23 @@ trusted-sender true + + ParcelMediaURLFilter + + flavor + llsd + trusted-sender + false + + ParcelNavigateMedia + + flavor + llsd + trusted-sender + false + + ParcelObjectOwnersReply flavor diff --git a/linden/indra/CMakeLists.txt b/linden/indra/CMakeLists.txt index 8dca9d8a5..64e0079af 100644 --- a/linden/indra/CMakeLists.txt +++ b/linden/indra/CMakeLists.txt @@ -42,7 +42,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llimage) add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj) add_subdirectory(${LIBS_OPEN_PREFIX}llinventory) add_subdirectory(${LIBS_OPEN_PREFIX}llmath) -add_subdirectory(${LIBS_OPEN_PREFIX}llmedia) add_subdirectory(${LIBS_OPEN_PREFIX}llmessage) add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive) add_subdirectory(${LIBS_OPEN_PREFIX}llrender) @@ -59,8 +58,17 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) add_custom_target(viewer) if (VIEWER) add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) + add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) add_subdirectory(${LIBS_OPEN_PREFIX}llui) + # viewer media plugins + add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins) + + # llplugin testbed code (is this the right way to include it?) + if (NOT LINUX) + add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest) + endif (NOT LINUX) + if (LINUX) add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) add_dependencies(viewer linux-crash-logger-strip-target) diff --git a/linden/indra/cmake/00-Common.cmake b/linden/indra/cmake/00-Common.cmake index d1f379c79..d335cb061 100644 --- a/linden/indra/cmake/00-Common.cmake +++ b/linden/indra/cmake/00-Common.cmake @@ -9,9 +9,9 @@ include(Variables) set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1") set(CMAKE_CXX_FLAGS_RELEASE - "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DNDEBUG") + "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-DLL_RELEASE=1 -D_SECURE_SCL=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1") + "-DLL_RELEASE=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1") # Don't bother with a MinSizeRel build. diff --git a/linden/indra/cmake/FindNDOF.cmake b/linden/indra/cmake/FindNDOF.cmake new file mode 100644 index 000000000..f980e34b7 --- /dev/null +++ b/linden/indra/cmake/FindNDOF.cmake @@ -0,0 +1,39 @@ +# -*- cmake -*- + +# - Find NDOF +# Find the NDOF includes and library +# This module defines +# NDOF_INCLUDE_DIR, where to find ndofdev_external.h, etc. +# NDOF_LIBRARY, the library needed to use NDOF. +# NDOF_FOUND, If false, do not try to use NDOF. + +find_path(NDOF_INCLUDE_DIR ndofdev_external.h + PATH_SUFFIXES ndofdev + ) + +set(NDOF_NAMES ${NDOF_NAMES} ndofdev libndofdev) +find_library(NDOF_LIBRARY + NAMES ${NDOF_NAMES} + ) + +if (NDOF_LIBRARY AND NDOF_INCLUDE_DIR) + set(NDOF_FOUND "YES") +else (NDOF_LIBRARY AND NDOF_INCLUDE_DIR) + set(NDOF_FOUND "NO") +endif (NDOF_LIBRARY AND NDOF_INCLUDE_DIR) + + +if (NDOF_FOUND) + if (NOT NDOF_FIND_QUIETLY) + message(STATUS "Found NDOF: Library in '${NDOF_LIBRARY}' and header in '${NDOF_INCLUDE_DIR}' ") + endif (NOT NDOF_FIND_QUIETLY) +else (NDOF_FOUND) + if (NDOF_FIND_REQUIRED) + message(FATAL_ERROR "Could not find NDOF library!") + endif (NDOF_FIND_REQUIRED) +endif (NDOF_FOUND) + +mark_as_advanced( + NDOF_LIBRARY + NDOF_INCLUDE_DIR + ) diff --git a/linden/indra/cmake/GStreamer010Plugin.cmake b/linden/indra/cmake/GStreamer010Plugin.cmake new file mode 100644 index 000000000..0d334837d --- /dev/null +++ b/linden/indra/cmake/GStreamer010Plugin.cmake @@ -0,0 +1,39 @@ +# -*- cmake -*- +include(Prebuilt) + +if (STANDALONE) + include(FindPkgConfig) + + pkg_check_modules(GSTREAMER010 REQUIRED gstreamer-0.10) + pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10) +elseif (LINUX) + use_prebuilt_binary(gstreamer) + # possible libxml should have its own .cmake file instead + use_prebuilt_binary(libxml) + set(GSTREAMER010_FOUND ON FORCE BOOL) + set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL) + set(GSTREAMER010_INCLUDE_DIRS + ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10 + ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 + ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 + ) + # We don't need to explicitly link against gstreamer itself, because + # LLMediaImplGStreamer probes for the system's copy at runtime. + set(GSTREAMER010_LIBRARIES + gobject-2.0 + gmodule-2.0 + dl + gthread-2.0 + rt + glib-2.0 + ) +endif (STANDALONE) + +if (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND) + set(GSTREAMER010 ON CACHE BOOL "Build with GStreamer-0.10 streaming media support.") +endif (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND) + +if (GSTREAMER010) + add_definitions(-DLL_GSTREAMER010_ENABLED=1) +endif (GSTREAMER010) + diff --git a/linden/indra/cmake/Glui.cmake b/linden/indra/cmake/Glui.cmake new file mode 100644 index 000000000..f62a56856 --- /dev/null +++ b/linden/indra/cmake/Glui.cmake @@ -0,0 +1,28 @@ +# -*- cmake -*- +include(Linking) +include(Prebuilt) + +if (STANDALONE) + set(GLUI OFF CACHE BOOL + "GLUI support for the llplugin/llmedia test apps.") +else (STANDALONE) + use_prebuilt_binary(glui) + set(GLUI ON CACHE BOOL + "GLUI support for the llplugin/llmedia test apps.") +endif (STANDALONE) + +if (LINUX) + set(GLUI ON CACHE BOOL + "llplugin media apps HACK for Linux.") +endif (LINUX) + +if (DARWIN OR LINUX) + set(GLUI_LIBRARY + glui) +endif (DARWIN OR LINUX) + +if (WINDOWS) + set(GLUI_LIBRARY + debug glui32.lib + optimized glui32.lib) +endif (WINDOWS) diff --git a/linden/indra/cmake/Glut.cmake b/linden/indra/cmake/Glut.cmake new file mode 100644 index 000000000..314da3065 --- /dev/null +++ b/linden/indra/cmake/Glut.cmake @@ -0,0 +1,19 @@ +# -*- cmake -*- +include(Linking) +include(Prebuilt) + +if (WINDOWS) + use_prebuilt_binary(freeglut) + set(GLUT_LIBRARY + debug freeglut_static.lib + optimized freeglut_static.lib) +endif (WINDOWS) + +if (LINUX) + FIND_LIBRARY(GLUT_LIBRARY glut) +endif (LINUX) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(GLUT_LIBRARY GLUT) +endif (DARWIN) diff --git a/linden/indra/cmake/LLAudio.cmake b/linden/indra/cmake/LLAudio.cmake index 625e212ca..89b790c6b 100644 --- a/linden/indra/cmake/LLAudio.cmake +++ b/linden/indra/cmake/LLAudio.cmake @@ -1,11 +1,9 @@ # -*- cmake -*- include(Audio) -include(OPENAL) set(LLAUDIO_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llaudio - ${OPENAL_INCLUDE_DIRS} ) set(LLAUDIO_LIBRARIES llaudio ${OPENAL_LIBRARIES}) diff --git a/linden/indra/cmake/LLMedia.cmake b/linden/indra/cmake/LLMedia.cmake deleted file mode 100644 index 8a36a69f3..000000000 --- a/linden/indra/cmake/LLMedia.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -*- cmake -*- - -include(GStreamer) - -set(LLMEDIA_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llmedia - ) - -set(LLMEDIA_LIBRARIES - llmedia - ${GSTREAMER_LIBRARIES} - ${GSTREAMER_PLUGINS_BASE_LIBRARIES} - ) diff --git a/linden/indra/cmake/LLPlugin.cmake b/linden/indra/cmake/LLPlugin.cmake new file mode 100644 index 000000000..9722f16c3 --- /dev/null +++ b/linden/indra/cmake/LLPlugin.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- + + +set(LLPLUGIN_INCLUDE_DIRS + ${LIBS_OPEN_DIR}/llplugin + ) + +set(LLPLUGIN_LIBRARIES llplugin) diff --git a/linden/indra/cmake/MediaPluginBase.cmake b/linden/indra/cmake/MediaPluginBase.cmake new file mode 100644 index 000000000..2be035b64 --- /dev/null +++ b/linden/indra/cmake/MediaPluginBase.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- + + +set(MEDIA_PLUGIN_BASE_INCLUDE_DIRS + ${LIBS_OPEN_DIR}/media_plugins/base/ + ) + +set(MEDIA_PLUGIN_BASE_LIBRARIES media_plugin_base) diff --git a/linden/indra/cmake/Mozlib.cmake b/linden/indra/cmake/Mozlib.cmake index e9555dfc0..e69de29bb 100644 --- a/linden/indra/cmake/Mozlib.cmake +++ b/linden/indra/cmake/Mozlib.cmake @@ -1,47 +0,0 @@ -# -*- cmake -*- -include(Linking) -include(Prebuilt) - -if (STANDALONE) - set(MOZLIB OFF CACHE BOOL - "Enable Mozilla support in the viewer (requires llmozlib library).") -else (STANDALONE) - use_prebuilt_binary(llmozlib) - set(MOZLIB ON CACHE BOOL - "Enable Mozilla support in the viewer (requires llmozlib library).") -endif (STANDALONE) - -if (MOZLIB) - add_definitions(-DLL_LLMOZLIB_ENABLED=1) - - if (LINUX) - link_directories(${CMAKE_SOURCE_DIR}/newview/app_settings/mozilla-runtime-linux-${ARCH}) - set(MOZLIB_LIBRARIES - llmozlib2 - mozjs - nspr4 - plc4 - plds4 - xpcom - xul - profdirserviceprovider_s - ) - elseif (WINDOWS) - if (MSVC71) - set(MOZLIB_LIBRARIES - debug llmozlib2d - optimized llmozlib2) - elseif (MSVC80 OR MSVC90) - set(MOZLIB_LIBRARIES - debug llmozlib2d-vc80 - optimized llmozlib2-vc80) - endif (MSVC71) - else (LINUX) - set(MOZLIB_LIBRARIES - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libllmozlib2.dylib - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libllmozlib2.dylib - ) - endif (LINUX) -else (MOZLIB) - add_definitions(-DLL_LLMOZLIB_ENABLED=0) -endif (MOZLIB) diff --git a/linden/indra/cmake/NDOF.cmake b/linden/indra/cmake/NDOF.cmake index dad74e99b..bdf5db130 100644 --- a/linden/indra/cmake/NDOF.cmake +++ b/linden/indra/cmake/NDOF.cmake @@ -1,14 +1,28 @@ # -*- cmake -*- include(Prebuilt) -use_prebuilt_binary(ndofdev) +if (STANDALONE) + include(FindNDOF) + if(NOT NDOF_FOUND) + message(STATUS "Building without N-DoF joystick support") + endif(NOT NDOF_FOUND) +else (STANDALONE) + use_prebuilt_binary(ndofdev) -if (WINDOWS OR DARWIN OR LINUX) - add_definitions(-DLIB_NDOF=1) -endif (WINDOWS OR DARWIN OR LINUX) + if (WINDOWS) + set(NDOF_LIBRARY libndofdev) + elseif (DARWIN OR LINUX) + set(NDOF_LIBRARY ndofdev) + endif (WINDOWS) + + set(NDOF_INCLUDE_DIR ${ARCH_PREBUILT_DIRS}/include/ndofdev) + set(NDOF_FOUND 1) +endif (STANDALONE) -if (WINDOWS) - set(NDOF_LIBRARY libndofdev) -elseif (DARWIN OR LINUX) - set(NDOF_LIBRARY ndofdev) -endif (WINDOWS) +if (NDOF_FOUND) + add_definitions(-DLIB_NDOF=1) + include_directories(${NDOF_INCLUDE_DIR}) +else (NDOF_FOUND) + set(NDOF_INCLUDE_DIR "") + set(NDOF_LIBRARY "") +endif (NDOF_FOUND) diff --git a/linden/indra/cmake/OPENAL.cmake b/linden/indra/cmake/OPENAL.cmake index 4f0e0cca7..f7ebfe6bc 100644 --- a/linden/indra/cmake/OPENAL.cmake +++ b/linden/indra/cmake/OPENAL.cmake @@ -1,10 +1,12 @@ # -*- cmake -*- - -include(Variables) include(Linking) +include(Prebuilt) -set(OPENAL ON CACHE BOOL "Enable OpenAL") - +if (LINUX) + set(OPENAL ON CACHE BOOL "Enable OpenAL") +else (LINUX) + set(OPENAL OFF CACHE BOOL "Enable OpenAL") +endif (LINUX) if (OPENAL) @@ -109,5 +111,8 @@ if (OPENAL) set(OPENAL_FOUND TRUE CACHE BOOL "Found OpenAL and ALUT libraries successfully" ) +endif (OPENAL) +if (OPENAL) + message(STATUS "Building with OpenAL audio support") endif (OPENAL) diff --git a/linden/indra/cmake/OPENAL.cmake.imp b/linden/indra/cmake/OPENAL.cmake.imp new file mode 100644 index 000000000..60abef360 --- /dev/null +++ b/linden/indra/cmake/OPENAL.cmake.imp @@ -0,0 +1,115 @@ +# -*- cmake -*- + +include(Variables) +include(Linking) + +set(OPENAL ON CACHE BOOL "Enable OpenAL") + + +if (OPENAL) + + # message(STATUS "Building with OpenAL audio support") + + # OPENAL_LIB + use_prebuilt_binary(openal) + + if (WINDOWS) + set(OPENAL_LIB + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/openal32.lib + debug ${ARCH_PREBUILT_DIRS_DEBUG}/openal32.lib + ) + + elseif (DARWIN) + # Look for for system's OpenAL.framework + find_library(OPENAL_LIB + NAMES openal.1 + PATHS ${ARCH_PREBUILT_DIRS_RELEASE} + NO_DEFAULT_PATH + ) + else (WINDOWS) + set(OPENAL_LIB openal) + endif (WINDOWS) + + if (NOT OPENAL_LIB) + message(FATAL_ERROR "OpenAL not found!") + else (NOT OPENAL_LIB) + # message(STATUS "OpenAL found: ${OPENAL_LIB}") + endif (NOT OPENAL_LIB) + + + + # OPENAL_INCLUDE_DIR + + if (DARWIN) + set(OPENAL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/AL) + else (DARWIN) + find_path(OPENAL_INCLUDE_DIR + NAMES al.h + PATHS ${LIBS_PREBUILT_DIR}/include/AL + ) + endif (DARWIN) + + if (NOT OPENAL_INCLUDE_DIR) + message(FATAL_ERROR "al.h not found!") + else (NOT OPENAL_INCLUDE_DIR) + # message(STATUS "al.h found in: ${OPENAL_INCLUDE_DIR}") + endif (NOT OPENAL_INCLUDE_DIR) + + + + # ALUT_LIB + + if (WINDOWS) + set(ALUT_LIB + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/alut.lib + debug ${ARCH_PREBUILT_DIRS_DEBUG}/alut.lib + ) + elseif (DARWIN) + find_library( ALUT_LIB + NAMES alut.0 + PATHS ${ARCH_PREBUILT_DIRS_RELEASE} + NO_DEFAULT_PATH + ) + else (WINDOWS) + set(ALUT_LIB alut) + endif (WINDOWS) + + if (NOT ALUT_LIB) + message(FATAL_ERROR "ALUT not found!") + else (NOT ALUT_LIB) + # message(STATUS "ALUT found: ${ALUT_LIB}") + endif (NOT ALUT_LIB) + + + + # ALUT_INCLUDE_DIR + + find_path(ALUT_INCLUDE_DIR + NAMES alut.h + PATHS ${OPENAL_INCLUDE_DIR} + ) + + if (NOT ALUT_INCLUDE_DIR) + message(FATAL_ERROR "alut.h not found!") + else (NOT ALUT_INCLUDE_DIR) + # message(STATUS "alut.h found in: ${ALUT_INCLUDE_DIR}") + endif (NOT ALUT_INCLUDE_DIR) + + + + set(OPENAL_LIBRARIES + ${OPENAL_LIB} + ${ALUT_LIB} + ) + + set(OPENAL_INCLUDE_DIRS + ${OPENAL_INCLUDE_DIR} + ${ALUT_INCLUDE_DIR} + ) + + + set(OPENAL_FOUND TRUE CACHE BOOL + "Found OpenAL and ALUT libraries successfully" + ) + +endif (OPENAL) diff --git a/linden/indra/cmake/PluginAPI.cmake b/linden/indra/cmake/PluginAPI.cmake new file mode 100644 index 000000000..d1649e824 --- /dev/null +++ b/linden/indra/cmake/PluginAPI.cmake @@ -0,0 +1,16 @@ +# -*- cmake -*- + +if (WINDOWS) + set(PLUGIN_API_WINDOWS_LIBRARIES + wsock32 + ws2_32 + psapi + netapi32 + advapi32 + user32 + ) +else (WINDOWS) + set(PLUGIN_API_WINDOWS_LIBRARIES "") +endif (WINDOWS) + + diff --git a/linden/indra/cmake/QuickTimePlugin.cmake b/linden/indra/cmake/QuickTimePlugin.cmake new file mode 100644 index 000000000..8afd8f304 --- /dev/null +++ b/linden/indra/cmake/QuickTimePlugin.cmake @@ -0,0 +1,46 @@ +# -*- cmake -*- + +if(INSTALL_PROPRIETARY) + include(Prebuilt) + use_prebuilt_binary(quicktime) +endif(INSTALL_PROPRIETARY) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(QUICKTIME_LIBRARY QuickTime) +elseif (WINDOWS) + set(QUICKTIME_SDK_DIR "$ENV{PROGRAMFILES}/QuickTime SDK" + CACHE PATH "Location of the QuickTime SDK.") + + find_library(DEBUG_QUICKTIME_LIBRARY qtmlclient + PATHS + ${ARCH_PREBUILT_DIRS_DEBUG} + "${QUICKTIME_SDK_DIR}\\libraries" + ) + + find_library(RELEASE_QUICKTIME_LIBRARY qtmlclient + PATHS + ${ARCH_PREBUILT_DIRS_RELEASE} + "${QUICKTIME_SDK_DIR}\\libraries" + ) + + if (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY) + set(QUICKTIME_LIBRARY + optimized ${RELEASE_QUICKTIME_LIBRARY} + debug ${DEBUG_QUICKTIME_LIBRARY} + ) + + endif (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY) + + include_directories( + ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/quicktime + "${QUICKTIME_SDK_DIR}\\CIncludes" + ) +endif (DARWIN) + +mark_as_advanced(QUICKTIME_LIBRARY) + +if (QUICKTIME_LIBRARY) + set(QUICKTIME ON CACHE BOOL "Build with QuickTime streaming media support.") +endif (QUICKTIME_LIBRARY) + diff --git a/linden/indra/cmake/WebKitLibPlugin.cmake b/linden/indra/cmake/WebKitLibPlugin.cmake new file mode 100644 index 000000000..23958fedf --- /dev/null +++ b/linden/indra/cmake/WebKitLibPlugin.cmake @@ -0,0 +1,55 @@ +# -*- cmake -*- +include(Linking) +include(Prebuilt) + +if (STANDALONE) + set(WEBKITLIBPLUGIN OFF CACHE BOOL + "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") +else (STANDALONE) + use_prebuilt_binary(llqtwebkit) + set(WEBKITLIBPLUGIN ON CACHE BOOL + "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") +endif (STANDALONE) + +if (WINDOWS) + set(WEBKIT_PLUGIN_LIBRARIES + debug llqtwebkitd + debug QtWebKitd4 + debug QtOpenGLd4 + debug QtNetworkd4 + debug QtGuid4 + debug QtCored4 + debug qtmaind + optimized llqtwebkit + optimized QtWebKit4 + optimized QtOpenGL4 + optimized QtNetwork4 + optimized QtGui4 + optimized QtCore4 + optimized qtmain + ) +elseif (DARWIN) + set(WEBKIT_PLUGIN_LIBRARIES + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib + debug ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib + ) +elseif (LINUX) + if (STANDALONE) + set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit) + else (STANDALONE) + set(WEBKIT_PLUGIN_LIBRARIES + llqtwebkit + qgif + qjpeg + QtWebKit + QtOpenGL + QtNetwork + QtGui + QtCore + fontconfig + X11 + Xrender + GL + ) + endif (STANDALONE) +endif (WINDOWS) diff --git a/linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt b/linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt new file mode 100644 index 000000000..295c9fea7 --- /dev/null +++ b/linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt @@ -0,0 +1,257 @@ +*************** +*** 15,35 **** + wrap_oal.dll + ) + + set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") + set(debug_files +- freebl3.dll +- js3250.dll +- nspr4.dll +- nss3.dll +- nssckbi.dll +- plc4.dll +- plds4.dll +- smime3.dll +- softokn3.dll +- ssl3.dll +- xpcom.dll +- xul.dll + openjpegd.dll +- windbgdlg.exe + ) + +--- 15,30 ---- + wrap_oal.dll + ) ++ copy_if_different( ++ ${vivox_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/Debug" ++ out_targets ++ ${vivox_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ + + set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") + set(debug_files + openjpegd.dll + ) + +*************** +*** 42,50 **** + set(all_targets ${all_targets} ${out_targets}) + +- copy_if_different( +- ${vivox_src_dir} +- "${CMAKE_CURRENT_BINARY_DIR}/Debug" +- out_targets +- ${vivox_files} + ) + set(all_targets ${all_targets} ${out_targets}) +--- 37,206 ---- + set(all_targets ${all_targets} ${out_targets}) + ++ # Debug config runtime files required for the plugin test mule ++ set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") ++ set(plugintest_debug_files ++ libeay32.dll ++ libglib-2.0-0.dll ++ libgmodule-2.0-0.dll ++ libgobject-2.0-0.dll ++ libgthread-2.0-0.dll ++ qtcored4.dll ++ qtguid4.dll ++ qtnetworkd4.dll ++ qtopengld4.dll ++ qtwebkitd4.dll ++ ssleay32.dll ++ ) ++ copy_if_different( ++ ${plugintest_debug_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug" ++ out_targets ++ ${plugintest_debug_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ # Debug config runtime files required for the plugin test mule (Qt image format plugins) ++ set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug/imageformats") ++ set(plugintest_debug_files ++ qgifd4.dll ++ qicod4.dll ++ qjpegd4.dll ++ qmngd4.dll ++ qsvgd4.dll ++ qtiffd4.dll ++ ) ++ copy_if_different( ++ ${plugintest_debug_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug/imageformats" ++ out_targets ++ ${plugintest_debug_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ copy_if_different( ++ ${plugintest_debug_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/llplugin/imageformats" ++ out_targets ++ ${plugintest_debug_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ # Release & ReleaseDebInfo config runtime files required for the plugin test mule ++ set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") ++ set(plugintest_release_files ++ libeay32.dll ++ libglib-2.0-0.dll ++ libgmodule-2.0-0.dll ++ libgobject-2.0-0.dll ++ libgthread-2.0-0.dll ++ # llkdu.dll (not required for plugin test) ++ qtcore4.dll ++ qtgui4.dll ++ qtnetwork4.dll ++ qtopengl4.dll ++ qtwebkit4.dll ++ ssleay32.dll ++ ) ++ copy_if_different( ++ ${plugintest_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release" ++ out_targets ++ ${plugintest_release_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ copy_if_different( ++ ${plugintest_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo" ++ out_targets ++ ${plugintest_release_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ # Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins) ++ set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release/imageformats") ++ set(plugintest_release_files ++ qgif4.dll ++ qico4.dll ++ qjpeg4.dll ++ qmng4.dll ++ qsvg4.dll ++ qtiff4.dll ++ ) ++ copy_if_different( ++ ${plugintest_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release/imageformats" ++ out_targets ++ ${plugintest_release_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ copy_if_different( ++ ${plugintest_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo/imageformats" ++ out_targets ++ ${plugintest_release_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ copy_if_different( ++ ${plugintest_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin/imageformats" ++ out_targets ++ ${plugintest_release_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ copy_if_different( ++ ${plugintest_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin/imageformats" ++ out_targets ++ ${plugintest_release_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ # Debug config runtime files required for the plugins ++ set(plugins_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") ++ set(plugins_debug_files ++ libeay32.dll ++ qtcored4.dll ++ qtguid4.dll ++ qtnetworkd4.dll ++ qtopengld4.dll ++ qtwebkitd4.dll ++ ssleay32.dll ++ ) ++ copy_if_different( ++ ${plugins_debug_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/Debug/llplugin" ++ out_targets ++ ${plugins_debug_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ # Release & ReleaseDebInfo config runtime files required for the plugins ++ set(plugins_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") ++ set(plugins_release_files ++ libeay32.dll ++ qtcore4.dll ++ qtgui4.dll ++ qtnetwork4.dll ++ qtopengl4.dll ++ qtwebkit4.dll ++ ssleay32.dll ++ ) ++ copy_if_different( ++ ${plugins_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin" ++ out_targets ++ ${plugins_release_files} ++ ) ++ set(all_targets ${all_targets} ${out_targets}) ++ ++ copy_if_different( ++ ${plugins_release_src_dir} ++ "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin" ++ out_targets ++ ${plugins_release_files} + ) + set(all_targets ${all_targets} ${out_targets}) +*************** +*** 52,67 **** + set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") + set(release_files +- freebl3.dll +- js3250.dll +- nspr4.dll +- nss3.dll +- nssckbi.dll +- plc4.dll +- plds4.dll +- smime3.dll +- softokn3.dll +- ssl3.dll +- xpcom.dll +- xul.dll + openjpeg.dll + ) +--- 208,211 ---- + set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") + set(release_files + openjpeg.dll + ) +*************** +*** 252,256 **** + ${debug_appconfig_file} + ) +- add_dependencies(copy_win_libs prepare) + + if(EXISTS ${internal_llkdu_path}) +--- 396,399 ---- + ${debug_appconfig_file} + ) + + if(EXISTS ${internal_llkdu_path}) diff --git a/linden/indra/llaudio/CMakeLists.txt b/linden/indra/llaudio/CMakeLists.txt index 0a668f9e1..1a0527c95 100644 --- a/linden/indra/llaudio/CMakeLists.txt +++ b/linden/indra/llaudio/CMakeLists.txt @@ -4,6 +4,7 @@ project(llaudio) # Current starting point for CMake. Seems rather arbitrary - MC include(00-Common) +include(LLAudio) include(Audio) include(OPENAL) include(FMOD) @@ -12,9 +13,9 @@ include(LLCommon) include(LLMath) include(LLMessage) include(LLVFS) -include(LLMedia) include_directories( + ${LLAUDIO_INCLUDE_DIRS} ${FMOD_INCLUDE_DIR} ${LLCOMMON_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} @@ -26,43 +27,43 @@ include_directories( ${VORBIS_INCLUDE_DIRS} ${OPENAL_LIB_INCLUDE_DIRS} ${FREEAULT_LIB_INCLUDE_DIRS} - ${LLMEDIA_INCLUDE_DIRS} - ${GSTREAMER_INCLUDE_DIRS} ) set(llaudio_SOURCE_FILES - audioengine.cpp - listener.cpp + llaudioengine.cpp + lllistener.cpp llaudiodecodemgr.cpp - vorbisdecode.cpp - vorbisencode.cpp + llvorbisdecode.cpp + llvorbisencode.cpp ) set(llaudio_HEADER_FILES CMakeLists.txt - audioengine.h - listener.h + llaudioengine.h + lllistener.h llaudiodecodemgr.h - vorbisdecode.h - vorbisencode.h - windgen.h + llvorbisdecode.h + llvorbisencode.h + llwindgen.h ) if (FMOD) list(APPEND llaudio_SOURCE_FILES - audioengine_fmod.cpp - listener_fmod.cpp + llaudioengine_fmod.cpp + lllistener_fmod.cpp + llstreamingaudio_fmod.cpp ) list(APPEND llaudio_HEADER_FILES - audioengine_fmod.h - listener_fmod.h + llaudioengine_fmod.h + lllistener_fmod.h + llstreamingaudio_fmod.h ) if (LINUX) if (${CXX_VERSION} MATCHES "4.[23]") - set_source_files_properties(audioengine_fmod.cpp + set_source_files_properties(llaudioengine_fmod.cpp COMPILE_FLAGS -Wno-error=write-strings) endif (${CXX_VERSION} MATCHES "4.[23]") endif (LINUX) @@ -70,13 +71,13 @@ endif (FMOD) if (OPENAL) list(APPEND llaudio_SOURCE_FILES - audioengine_openal.cpp - listener_openal.cpp + llaudioengine_openal.cpp + lllistener_openal.cpp ) list(APPEND llaudio_HEADER_FILES - audioengine_openal.h - listener_openal.h + llaudioengine_openal.h + lllistener_openal.h ) endif (OPENAL) diff --git a/linden/indra/llaudio/listener.cpp b/linden/indra/llaudio/listener.cpp index e2dc30eef..e69de29bb 100644 --- a/linden/indra/llaudio/listener.cpp +++ b/linden/indra/llaudio/listener.cpp @@ -1,153 +0,0 @@ -/** - * @file listener.cpp - * @brief Implementation of LISTENER class abstracting the audio support - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "listener.h" - -#define DEFAULT_AT 0.0f,0.0f,-1.0f -#define DEFAULT_UP 0.0f,1.0f,0.0f - -//----------------------------------------------------------------------- -// constructor -//----------------------------------------------------------------------- -LLListener::LLListener() -{ - init(); -} - -//----------------------------------------------------------------------- -LLListener::~LLListener() -{ -} - -//----------------------------------------------------------------------- -void LLListener::init(void) -{ - mPosition.zeroVec(); - mListenAt.setVec(DEFAULT_AT); - mListenUp.setVec(DEFAULT_UP); - mVelocity.zeroVec(); -} - -//----------------------------------------------------------------------- -void LLListener::translate(LLVector3 offset) -{ - mPosition += offset; -} - -//----------------------------------------------------------------------- -void LLListener::setPosition(LLVector3 pos) -{ - mPosition = pos; -} - -//----------------------------------------------------------------------- -LLVector3 LLListener::getPosition(void) -{ - return(mPosition); -} - -//----------------------------------------------------------------------- -LLVector3 LLListener::getAt(void) -{ - return(mListenAt); -} - -//----------------------------------------------------------------------- -LLVector3 LLListener::getUp(void) -{ - return(mListenUp); -} - -//----------------------------------------------------------------------- -void LLListener::setVelocity(LLVector3 vel) -{ - mVelocity = vel; -} - -//----------------------------------------------------------------------- -void LLListener::orient(LLVector3 up, LLVector3 at) -{ - mListenUp = up; - mListenAt = at; -} - -//----------------------------------------------------------------------- -void LLListener::set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at) -{ - mPosition = pos; - mVelocity = vel; - - setPosition(pos); - setVelocity(vel); - orient(up,at); -} - -//----------------------------------------------------------------------- -void LLListener::setDopplerFactor(F32 factor) -{ -} - -//----------------------------------------------------------------------- -F32 LLListener::getDopplerFactor() -{ - return (1.f); -} - -//----------------------------------------------------------------------- -void LLListener::setDistanceFactor(F32 factor) -{ -} - -//----------------------------------------------------------------------- -F32 LLListener::getDistanceFactor() -{ - return (1.f); -} - -//----------------------------------------------------------------------- -void LLListener::setRolloffFactor(F32 factor) -{ -} - -//----------------------------------------------------------------------- -F32 LLListener::getRolloffFactor() -{ - return (1.f); -} - -//----------------------------------------------------------------------- -void LLListener::commitDeferredChanges() -{ -} - diff --git a/linden/indra/llaudio/listener.h b/linden/indra/llaudio/listener.h index 4137304e6..e69de29bb 100644 --- a/linden/indra/llaudio/listener.h +++ b/linden/indra/llaudio/listener.h @@ -1,80 +0,0 @@ -/** - * @file listener.h - * @brief Description of LISTENER base class abstracting the audio support. - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LISTENER_H -#define LL_LISTENER_H - -#include "v3math.h" - -class LLListener -{ - private: - protected: - LLVector3 mPosition; - LLVector3 mVelocity; - LLVector3 mListenAt; - LLVector3 mListenUp; - - public: - - private: - protected: - public: - LLListener(); - virtual ~LLListener(); - virtual void init(); - - virtual void set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at); - - virtual void setPosition(LLVector3 pos); - virtual void setVelocity(LLVector3 vel); - - virtual void orient(LLVector3 up, LLVector3 at); - virtual void translate(LLVector3 offset); - - virtual void setDopplerFactor(F32 factor); - virtual void setDistanceFactor(F32 factor); - virtual void setRolloffFactor(F32 factor); - - virtual LLVector3 getPosition(); - virtual LLVector3 getAt(); - virtual LLVector3 getUp(); - - virtual F32 getDopplerFactor(); - virtual F32 getDistanceFactor(); - virtual F32 getRolloffFactor(); - - virtual void commitDeferredChanges(); -}; - -#endif - diff --git a/linden/indra/llaudio/listener_ds3d.h b/linden/indra/llaudio/listener_ds3d.h index 3121e1254..e69de29bb 100644 --- a/linden/indra/llaudio/listener_ds3d.h +++ b/linden/indra/llaudio/listener_ds3d.h @@ -1,76 +0,0 @@ -/** - * @file listener_ds3d.h - * @brief Description of LISTENER class abstracting the audio support - * as a DirectSound 3D implementation (windows only) - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LISTENER_DS3D_H -#define LL_LISTENER_DS3D_H - -#include "listener.h" - -#include -#include -#include - -class LLListener_DS3D : public LLListener -{ - private: - protected: - IDirectSound3DListener8 *m3DListener; - public: - - private: - protected: - public: - LLListener_DS3D(); - virtual ~LLListener_DS3D(); - virtual void init(); - - virtual void setDS3DLPtr (IDirectSound3DListener8 *listener_p); - - virtual void translate(LLVector3 offset); - virtual void setPosition(LLVector3 pos); - virtual void setVelocity(LLVector3 vel); - virtual void orient(LLVector3 up, LLVector3 at); - - virtual void setDopplerFactor(F32 factor); - virtual F32 getDopplerFactor(); - virtual void setDistanceFactor(F32 factor); - virtual F32 getDistanceFactor(); - virtual void setRolloffFactor(F32 factor); - virtual F32 getRolloffFactor(); - - virtual void commitDeferredChanges(); -}; - -#endif - - diff --git a/linden/indra/llaudio/listener_fmod.cpp b/linden/indra/llaudio/listener_fmod.cpp index 4bbb3d925..e69de29bb 100644 --- a/linden/indra/llaudio/listener_fmod.cpp +++ b/linden/indra/llaudio/listener_fmod.cpp @@ -1,143 +0,0 @@ -/** - * @file listener_fmod.cpp - * @brief implementation of LISTENER class abstracting the audio - * support as a FMOD 3D implementation (windows only) - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "audioengine.h" -#include "listener_fmod.h" -#include "fmod.h" - -//----------------------------------------------------------------------- -// constructor -//----------------------------------------------------------------------- -LLListener_FMOD::LLListener_FMOD() -{ - init(); -} - -//----------------------------------------------------------------------- -LLListener_FMOD::~LLListener_FMOD() -{ -} - -//----------------------------------------------------------------------- -void LLListener_FMOD::init(void) -{ - // do inherited - LLListener::init(); - mDopplerFactor = 1.0f; - mDistanceFactor = 1.0f; - mRolloffFactor = 1.0f; -} - -//----------------------------------------------------------------------- -void LLListener_FMOD::translate(LLVector3 offset) -{ - LLListener::translate(offset); - - FSOUND_3D_Listener_SetAttributes(mPosition.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]); -} - -//----------------------------------------------------------------------- -void LLListener_FMOD::setPosition(LLVector3 pos) -{ - LLListener::setPosition(pos); - - FSOUND_3D_Listener_SetAttributes(pos.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]); -} - -//----------------------------------------------------------------------- -void LLListener_FMOD::setVelocity(LLVector3 vel) -{ - LLListener::setVelocity(vel); - - FSOUND_3D_Listener_SetAttributes(NULL, vel.mV, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]); -} - -//----------------------------------------------------------------------- -void LLListener_FMOD::orient(LLVector3 up, LLVector3 at) -{ - LLListener::orient(up, at); - - // Welcome to the transition between right and left - // (coordinate systems, that is) - // Leaving the at vector alone results in a L/R reversal - // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed - at = -at; - - FSOUND_3D_Listener_SetAttributes(NULL, NULL, at.mV[0],at.mV[1],at.mV[2], up.mV[0],up.mV[1],up.mV[2]); -} - -//----------------------------------------------------------------------- -void LLListener_FMOD::commitDeferredChanges() -{ - FSOUND_Update(); -} - - -void LLListener_FMOD::setRolloffFactor(F32 factor) -{ - mRolloffFactor = factor; - FSOUND_3D_SetRolloffFactor(factor); -} - - -F32 LLListener_FMOD::getRolloffFactor() -{ - return mRolloffFactor; -} - - -void LLListener_FMOD::setDopplerFactor(F32 factor) -{ - mDopplerFactor = factor; - FSOUND_3D_SetDopplerFactor(factor); -} - - -F32 LLListener_FMOD::getDopplerFactor() -{ - return mDopplerFactor; -} - - -void LLListener_FMOD::setDistanceFactor(F32 factor) -{ - mDistanceFactor = factor; - FSOUND_3D_SetDistanceFactor(factor); -} - - -F32 LLListener_FMOD::getDistanceFactor() -{ - return mDistanceFactor; -} diff --git a/linden/indra/llaudio/listener_fmod.h b/linden/indra/llaudio/listener_fmod.h index 5f372ab2c..e69de29bb 100644 --- a/linden/indra/llaudio/listener_fmod.h +++ b/linden/indra/llaudio/listener_fmod.h @@ -1,67 +0,0 @@ -/** - * @file listener_fmod.h - * @brief Description of LISTENER class abstracting the audio support - * as an FMOD 3D implementation (windows and Linux) - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LISTENER_FMOD_H -#define LL_LISTENER_FMOD_H - -#include "listener.h" - -class LLListener_FMOD : public LLListener -{ - public: - LLListener_FMOD(); - virtual ~LLListener_FMOD(); - virtual void init(); - - virtual void translate(LLVector3 offset); - virtual void setPosition(LLVector3 pos); - virtual void setVelocity(LLVector3 vel); - virtual void orient(LLVector3 up, LLVector3 at); - virtual void commitDeferredChanges(); - - virtual void setDopplerFactor(F32 factor); - virtual F32 getDopplerFactor(); - virtual void setDistanceFactor(F32 factor); - virtual F32 getDistanceFactor(); - virtual void setRolloffFactor(F32 factor); - virtual F32 getRolloffFactor(); - - protected: - F32 mDopplerFactor; - F32 mDistanceFactor; - F32 mRolloffFactor; -}; - -#endif - - diff --git a/linden/indra/llaudio/llaudiodecodemgr.cpp b/linden/indra/llaudio/llaudiodecodemgr.cpp index afb3c33c0..a14d4ecf2 100644 --- a/linden/indra/llaudio/llaudiodecodemgr.cpp +++ b/linden/indra/llaudio/llaudiodecodemgr.cpp @@ -33,18 +33,18 @@ #include "llaudiodecodemgr.h" -#include "vorbisdecode.h" -#include "audioengine.h" +#include "llvorbisdecode.h" +#include "llaudioengine.h" #include "lllfsthread.h" #include "llvfile.h" #include "llstring.h" #include "lldir.h" #include "llendianswizzle.h" -#include "audioengine.h" #include "llassetstorage.h" #include "vorbis/codec.h" #include "vorbis/vorbisfile.h" +#include "llvorbisencode.h" extern LLAudioEngine *gAudiop; @@ -218,11 +218,42 @@ BOOL LLVorbisDecodeState::initDecode() return(FALSE); } - size_t size_guess = (size_t)ov_pcm_total(&mVF, -1); + S32 sample_count = ov_pcm_total(&mVF, -1); + size_t size_guess = (size_t)sample_count; vorbis_info* vi = ov_info(&mVF, -1); size_guess *= vi->channels; size_guess *= 2; size_guess += 2048; + + bool abort_decode = false; + + if( vi->channels < 1 || vi->channels > LLVORBIS_CLIP_MAX_CHANNELS ) + { + abort_decode = true; + llwarns << "Bad channel count: " << vi->channels << llendl; + } + + if( (size_t)sample_count > LLVORBIS_CLIP_REJECT_SAMPLES ) + { + abort_decode = true; + llwarns << "Illegal sample count: " << sample_count << llendl; + } + + if( size_guess > LLVORBIS_CLIP_REJECT_SIZE ) + { + abort_decode = true; + llwarns << "Illegal sample size: " << size_guess << llendl; + } + + if( abort_decode ) + { + llwarns << "Canceling initDecode. Bad asset: " << mUUID << llendl; + llwarns << "Bad asset encoded by: " << ov_comment(&mVF,-1)->vendor << llendl; + delete mInFilep; + mInFilep = NULL; + return FALSE; + } + mWAVBuffer.reserve(size_guess); mWAVBuffer.resize(WAV_HEADER_SIZE); @@ -375,16 +406,16 @@ BOOL LLVorbisDecodeState::finishDecode() // write "data" chunk length, in little-endian format S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE; - mWAVBuffer[40] = (data_length - 8) & 0x000000FF; - mWAVBuffer[41] = ((data_length - 8)>> 8) & 0x000000FF; - mWAVBuffer[42] = ((data_length - 8)>> 16) & 0x000000FF; - mWAVBuffer[43] = ((data_length - 8)>> 24) & 0x000000FF; - + mWAVBuffer[40] = (data_length) & 0x000000FF; + mWAVBuffer[41] = (data_length >> 8) & 0x000000FF; + mWAVBuffer[42] = (data_length >> 16) & 0x000000FF; + mWAVBuffer[43] = (data_length >> 24) & 0x000000FF; // write overall "RIFF" length, in little-endian format - mWAVBuffer[4] = (data_length + 28) & 0x000000FF; - mWAVBuffer[5] = ((data_length + 28) >> 8) & 0x000000FF; - mWAVBuffer[6] = ((data_length + 28) >> 16) & 0x000000FF; - mWAVBuffer[7] = ((data_length + 28) >> 24) & 0x000000FF; + data_length += 36; + mWAVBuffer[4] = (data_length) & 0x000000FF; + mWAVBuffer[5] = (data_length >> 8) & 0x000000FF; + mWAVBuffer[6] = (data_length >> 16) & 0x000000FF; + mWAVBuffer[7] = (data_length >> 24) & 0x000000FF; // // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop) @@ -396,8 +427,7 @@ BOOL LLVorbisDecodeState::finishDecode() S32 fade_length; char pcmout[4096]; /*Flawfinder: ignore*/ - fade_length = llmin((S32)128,(S32)(data_length)/8); - + fade_length = llmin((S32)128,(S32)(data_length-36)/8); if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length)) { memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/ @@ -437,7 +467,7 @@ BOOL LLVorbisDecodeState::finishDecode() } } - if (0 == data_length) + if (36 == data_length) { llwarns << "BAD Vorbis decode in finishDecode!" << llendl; mValid = FALSE; diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/llaudioengine.cpp similarity index 85% rename from linden/indra/llaudio/audioengine.cpp rename to linden/indra/llaudio/llaudioengine.cpp index 1900c38ee..bed791afd 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/llaudioengine.cpp @@ -35,7 +35,8 @@ #include "linden_common.h" -#include "audioengine.h" +#include "llaudioengine.h" +#include "llstreamingaudio.h" #include "llerror.h" #include "llmath.h" @@ -47,9 +48,6 @@ #include "llaudiodecodemgr.h" #include "llassetstorage.h" -#include "llmediamanager.h" -#include "llmediabase.h" -#include "llmediaimplcommon.h" // necessary for grabbing sounds from sim (implemented in viewer) extern void request_sound(const LLUUID &sound_guid); @@ -72,6 +70,15 @@ LLAudioEngine::~LLAudioEngine() { } +LLStreamingAudioInterface* LLAudioEngine::getStreamingAudioImpl() +{ + return mStreamingAudioImpl; +} + +void LLAudioEngine::setStreamingAudioImpl(LLStreamingAudioInterface *impl) +{ + mStreamingAudioImpl = impl; +} void LLAudioEngine::setDefaults() { @@ -98,13 +105,10 @@ void LLAudioEngine::setDefaults() } mMasterGain = 1.f; - mInternetStreamGain = 0.125f; + mInternalGain = 0.f; mNextWindUpdate = 0.f; - mInternetStreamMedia = NULL; - mInternetStreamURL.clear(); - - mStatus = LLMediaBase::STATUS_UNKNOWN; + mStreamingAudioImpl = NULL; for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++) mSecondaryGain[i] = 1.0f; @@ -168,163 +172,61 @@ void LLAudioEngine::shutdown() delete mBuffers[i]; mBuffers[i] = NULL; } - - delete mInternetStreamMedia; - mInternetStreamMedia = NULL; - mInternetStreamURL.clear(); -} - - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -LLMediaBase::EStatus LLAudioEngine::getStatus() -{ - return mStatus; } // virtual void LLAudioEngine::startInternetStream(const std::string& url) { - llinfos << "entered startInternetStream()" << llendl; - - if (!mInternetStreamMedia) - { - LLMediaManager* mgr = LLMediaManager::getInstance(); - if (mgr) - { - mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. - llinfos << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl; - } - } - - if(!mInternetStreamMedia) - { - return; - } - // Check for a dead stream from gstreamer, just in case - else if(getStatus() == LLMediaBase::STATUS_DEAD) - { - llinfos << "don't play dead stream urls"<< llendl; - mInternetStreamURL.clear(); - mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); - mInternetStreamMedia->updateMedia(); - stopInternetStream(); - } - else if (url.empty()) - { - llinfos << "url is emptly. Setting stream to NULL"<< llendl; - mInternetStreamURL.clear(); - mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); - mInternetStreamMedia->updateMedia(); - } - // Stream appears to be good, attempting to play - else - { - // stop any other stream first - stopInternetStream(); - - llinfos << "Starting internet stream: " << url << llendl; - mInternetStreamURL = url; - mInternetStreamMedia->navigateTo(url); - //llinfos << "Playing....." << llendl; - mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START); - mInternetStreamMedia->updateMedia(); - mStatus = LLMediaBase::STATUS_STARTED; - } + if (mStreamingAudioImpl) + mStreamingAudioImpl->start(url); } + // virtual void LLAudioEngine::stopInternetStream() { - llinfos << "entered stopInternetStream()" << llendl; - mInternetStreamURL.clear(); - - if(mInternetStreamMedia) - { - if(!mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)) - { - llinfos << "attempting to stop stream failed!" << llendl; - } - mInternetStreamMedia->updateMedia(); - } - - mInternetStreamURL.clear(); + if (mStreamingAudioImpl) + mStreamingAudioImpl->stop(); } // virtual void LLAudioEngine::pauseInternetStream(int pause) { - llinfos << "entered pauseInternetStream()" << llendl; - - if(!mInternetStreamMedia) - return; - - if(pause) - { - if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_PAUSE)) - { - llinfos << "attempting to pause stream failed!" << llendl; - } - } else { - if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START)) - { - llinfos << "attempting to unpause stream failed!" << llendl; - } - } - mInternetStreamMedia->updateMedia(); + if (mStreamingAudioImpl) + mStreamingAudioImpl->pause(pause); } // virtual void LLAudioEngine::updateInternetStream() { - if (mInternetStreamMedia) - mInternetStreamMedia->updateMedia(); + if (mStreamingAudioImpl) + mStreamingAudioImpl->update(); } // virtual int LLAudioEngine::isInternetStreamPlaying() { - if (!mInternetStreamMedia) - return 0; - - if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_STARTED) - { - return 1; // Active and playing - } - - if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_PAUSED) - { - return 2; // paused - } + if (mStreamingAudioImpl) + return mStreamingAudioImpl->isPlaying(); return 0; // Stopped } -// virtual -void LLAudioEngine::getInternetStreamInfo(char* artist, char* title) -{ - artist[0] = 0; - title[0] = 0; -} // virtual void LLAudioEngine::setInternetStreamGain(F32 vol) { - mInternetStreamGain = vol; - - if(!mInternetStreamMedia) - return; - - vol = llclamp(vol, 0.f, 1.f); - mInternetStreamMedia->setVolume(vol); - mInternetStreamMedia->updateMedia(); + if (mStreamingAudioImpl) + mStreamingAudioImpl->setGain(vol); } // virtual -const std::string& LLAudioEngine::getInternetStreamURL() +std::string LLAudioEngine::getInternetStreamURL() { - return mInternetStreamURL; + if (mStreamingAudioImpl) + return mStreamingAudioImpl->getURL(); + else return std::string(); } @@ -335,13 +237,6 @@ void LLAudioEngine::updateChannels() { if (mChannels[i]) { - // set secondary gain if type is available - LLAudioSource* source = mChannels[i]->getSource(); - if (source) - { - mChannels[i]->setSecondaryGain(mSecondaryGain[source->getType()]); - } - mChannels[i]->updateBuffer(); mChannels[i]->update3DPosition(); mChannels[i]->updateLoop(); @@ -361,15 +256,6 @@ void LLAudioEngine::idle(F32 max_decode_time) // Primarily does position updating, cleanup of unused audio sources. // Also does regeneration of the current priority of each audio source. - if (getMuted()) - { - setInternalGain(0.f); - } - else - { - setInternalGain(getMasterGain()); - } - S32 i; for (i = 0; i < MAX_BUFFERS; i++) { @@ -398,6 +284,12 @@ void LLAudioEngine::idle(F32 max_decode_time) continue; } + if (sourcep->isMuted()) + { + ++iter; + continue; + } + if (!sourcep->getChannel() && sourcep->getCurrentBuffer()) { // We could potentially play this sound if its priority is high enough. @@ -420,7 +312,7 @@ void LLAudioEngine::idle(F32 max_decode_time) LLAudioChannel *channelp = getFreeChannel(max_priority); if (channelp) { - //LL_INFOS("AudioEngine") << "Replacing source in channel due to priority!" << llendl; + //llinfos << "Replacing source in channel due to priority!" << llendl; max_sourcep->setChannel(channelp); channelp->setSource(max_sourcep); if (max_sourcep->isSyncSlave()) @@ -453,9 +345,9 @@ void LLAudioEngine::idle(F32 max_decode_time) // attached to each channel, since only those with active channels // can have anything interesting happen with their queue? (Maybe not true) LLAudioSource *sourcep = iter->second; - if (!sourcep->mQueuedDatap) + if (!sourcep->mQueuedDatap || sourcep->isMuted()) { - // Nothing queued, so we don't care. + // Muted, or nothing queued, so we don't care. continue; } @@ -535,6 +427,10 @@ void LLAudioEngine::idle(F32 max_decode_time) for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter) { LLAudioSource *sourcep = iter->second; + if (sourcep->isMuted()) + { + continue; + } if (sourcep->isSyncMaster()) { if (sourcep->getPriority() > max_sm_priority) @@ -590,7 +486,7 @@ void LLAudioEngine::idle(F32 max_decode_time) { if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f) { - //LL_INFOS("AudioEngine") << "Flushing unused buffer!" << llendl; + //llinfos << "Flushing unused buffer!" << llendl; mBuffers[i]->mAudioDatap->mBufferp = NULL; delete mBuffers[i]; mBuffers[i] = NULL; @@ -670,7 +566,7 @@ void LLAudioEngine::enableWind(bool enable) } -LLAudioBuffer *LLAudioEngine::getFreeBuffer() +LLAudioBuffer * LLAudioEngine::getFreeBuffer() { static clock_t last_info = 0; static bool spamming = FALSE; @@ -822,15 +718,23 @@ bool LLAudioEngine::isWindEnabled() void LLAudioEngine::setMuted(bool muted) { - mMuted = muted; + if (muted != mMuted) + { + mMuted = muted; + setMasterGain(mMasterGain); + } enableWind(!mMuted); } - void LLAudioEngine::setMasterGain(const F32 gain) { mMasterGain = gain; - setInternalGain(gain); + F32 internal_gain = getMuted() ? 0.f : gain; + if (internal_gain != mInternalGain) + { + mInternalGain = internal_gain; + setInternalGain(mInternalGain); + } } F32 LLAudioEngine::getMasterGain() @@ -852,7 +756,10 @@ F32 LLAudioEngine::getSecondaryGain(S32 type) F32 LLAudioEngine::getInternetStreamGain() { - return mInternetStreamGain; + if (mStreamingAudioImpl) + return mStreamingAudioImpl->getGain(); + else + return 1.0f; } void LLAudioEngine::setMaxWindGain(F32 gain) @@ -929,10 +836,9 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i const S32 type, const LLVector3d &pos_global) { // Create a new source (since this can't be associated with an existing source. - //LL_INFOS("AudioEngine") << "Localized: " << audio_uuid << llendl; + //llinfos << "Localized: " << audio_uuid << llendl; - //If we cannot hear it, dont even try to load the sound. - if (mMuted || gain == 0.0) + if (mMuted) { return; } @@ -1020,28 +926,6 @@ F32 LLAudioEngine::getDopplerFactor() } -void LLAudioEngine::setDistanceFactor(F32 factor) -{ - if (mListenerp) - { - mListenerp->setDistanceFactor(factor); - } -} - - -F32 LLAudioEngine::getDistanceFactor() -{ - if (mListenerp) - { - return mListenerp->getDistanceFactor(); - } - else - { - return 0.f; - } -} - - void LLAudioEngine::setRolloffFactor(F32 factor) { if (mListenerp) @@ -1070,7 +954,7 @@ void LLAudioEngine::commitDeferredChanges() } -LLAudioSource *LLAudioEngine::findAudioSource(const LLUUID &source_id) +LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id) { source_map::iterator iter; iter = mAllSources.find(source_id); @@ -1086,7 +970,7 @@ LLAudioSource *LLAudioEngine::findAudioSource(const LLUUID &source_id) } -LLAudioData *LLAudioEngine::getAudioData(const LLUUID &audio_uuid) +LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid) { data_map::iterator iter; iter = mAllData.find(audio_uuid); @@ -1152,10 +1036,10 @@ bool LLAudioEngine::hasLocalFile(const LLUUID &uuid) void LLAudioEngine::startNextTransfer() { - //LL_INFOS("AudioEngine") << "LLAudioEngine::startNextTransfer()" << llendl; + //llinfos << "LLAudioEngine::startNextTransfer()" << llendl; if (mCurrentTransfer.notNull() || getMuted()) { - //LL_INFOS("AudioEngine") << "Transfer in progress, aborting" << llendl; + //llinfos << "Transfer in progress, aborting" << llendl; return; } @@ -1336,7 +1220,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.notNull()) { - LL_INFOS("AudioEngine") << "Getting asset data for: " << asset_id << llendl; + llinfos << "Getting asset data for: " << asset_id << llendl; gAudiop->mCurrentTransfer = asset_id; gAudiop->mCurrentTransferTimer.reset(); gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND, @@ -1344,7 +1228,7 @@ void LLAudioEngine::startNextTransfer() } else { - //LL_INFOS("AudioEngine") << "No pending transfers?" << llendl; + //llinfos << "No pending transfers?" << llendl; } } @@ -1354,7 +1238,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E { if (result_code) { - LL_INFOS("AudioEngine") << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl; + llinfos << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl; // Need to mark data as bad to avoid constant rerequests. LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) @@ -1394,13 +1278,14 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 mOwnerID(owner_id), mPriority(0.f), mGain(gain), - mType(type), + mSourceMuted(false), mAmbient(false), mLoop(false), mSyncMaster(false), mSyncSlave(false), mQueueSounds(false), mPlayedOnce(false), + mType(type), mChannelp(NULL), mCurrentDatap(NULL), mQueuedDatap(NULL) @@ -1452,6 +1337,10 @@ void LLAudioSource::updatePriority() { mPriority = 1.f; } + else if (isMuted()) + { + mPriority = 0.f; + } else { // Priority is based on distance @@ -1500,25 +1389,33 @@ bool LLAudioSource::setupChannel() bool LLAudioSource::play(const LLUUID &audio_uuid) { + // Special abuse of play(); don't play a sound, but kill it. if (audio_uuid.isNull()) { if (getChannel()) { getChannel()->setSource(NULL); setChannel(NULL); - addAudioData(NULL, true); + if (!isMuted()) + { + mCurrentDatap = NULL; + } } + return false; } + // Reset our age timeout if someone attempts to play the source. mAgeTimer.reset(); LLAudioData *adp = gAudiop->getAudioData(audio_uuid); - - bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); - - addAudioData(adp); + if (isMuted()) + { + return false; + } + + bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); if (!has_buffer) { // Don't bother trying to set up a channel or anything, we don't have an audio buffer. @@ -1543,10 +1440,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) } -bool LLAudioSource::isDone() +bool LLAudioSource::isDone() const { const F32 MAX_AGE = 60.f; const F32 MAX_UNPLAYED_AGE = 15.f; + const F32 MAX_MUTED_AGE = 11.f; if (isLoop()) { @@ -1554,7 +1452,6 @@ bool LLAudioSource::isDone() return false; } - if (hasPendingPreloads()) { return false; @@ -1571,10 +1468,10 @@ bool LLAudioSource::isDone() // This is a single-play source if (!mChannelp) { - if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce) + if ((elapsed > (mSourceMuted ? MAX_MUTED_AGE : MAX_UNPLAYED_AGE)) || mPlayedOnce) { // We don't have a channel assigned, and it's been - // over 5 seconds since we tried to play it. Don't bother. + // over 15 seconds since we tried to play it. Don't bother. //llinfos << "No channel assigned, source is done" << llendl; return true; } @@ -1600,7 +1497,7 @@ bool LLAudioSource::isDone() if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce) { - // The sound isn't playing back after 5 seconds or we're already done playing it, kill it. + // The sound isn't playing back after 15 seconds or we're already done playing it, kill it. return true; } @@ -1696,17 +1593,17 @@ bool LLAudioSource::hasPendingPreloads() const } -LLAudioData *LLAudioSource::getCurrentData() +LLAudioData * LLAudioSource::getCurrentData() { return mCurrentDatap; } -LLAudioData *LLAudioSource::getQueuedData() +LLAudioData * LLAudioSource::getQueuedData() { return mQueuedDatap; } -LLAudioBuffer *LLAudioSource::getCurrentBuffer() +LLAudioBuffer * LLAudioSource::getCurrentBuffer() { if (!mCurrentDatap) { @@ -1737,7 +1634,7 @@ LLAudioChannel::LLAudioChannel() : LLAudioChannel::~LLAudioChannel() { // Need to disconnect any sources which are using this channel. - //LL_INFOS("AudioEngine") << "Cleaning up audio channel" << llendl; + //llinfos << "Cleaning up audio channel" << llendl; if (mCurrentSourcep) { mCurrentSourcep->setChannel(NULL); @@ -1748,12 +1645,12 @@ LLAudioChannel::~LLAudioChannel() void LLAudioChannel::setSource(LLAudioSource *sourcep) { - //LL_INFOS("AudioEngine") << this << ": setSource(" << sourcep << ")" << llendl; + //llinfos << this << ": setSource(" << sourcep << ")" << llendl; if (!sourcep) { // Clearing the source for this channel, don't need to do anything. - //LL_INFOS("AudioEngine") << "Clearing source for channel" << llendl; + //llinfos << "Clearing source for channel" << llendl; cleanup(); mCurrentSourcep = NULL; mWaiting = false; @@ -1763,7 +1660,7 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep) if (sourcep == mCurrentSourcep) { // Don't reallocate the channel, this will make FMOD goofy. - //LL_INFOS("AudioEngine") << "Calling setSource with same source!" << llendl; + //llinfos << "Calling setSource with same source!" << llendl; } mCurrentSourcep = sourcep; diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/llaudioengine.h similarity index 92% rename from linden/indra/llaudio/audioengine.h rename to linden/indra/llaudio/llaudioengine.h index e46091c57..a1b240eea 100644 --- a/linden/indra/llaudio/audioengine.h +++ b/linden/indra/llaudio/llaudioengine.h @@ -37,18 +37,14 @@ #include #include -#include "listener.h" #include "v3math.h" #include "v3dmath.h" -#include "listener.h" #include "lltimer.h" #include "lluuid.h" #include "llframetimer.h" #include "llassettype.h" -#include "llmediabase.h" - -class LLMediaBase; +#include "lllistener.h" const F32 LL_WIND_UPDATE_INTERVAL = 0.1f; const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water @@ -75,7 +71,7 @@ class LLAudioData; class LLAudioChannel; class LLAudioChannelOpenAL; class LLAudioBuffer; - +class LLStreamingAudioInterface; // @@ -121,9 +117,11 @@ class LLAudioEngine // Use these for temporarily muting the audio system. // Does not change buffers, initialization, etc. but // stops playing new sounds. - virtual void setMuted(bool muted); - virtual bool getMuted() const { return mMuted; } - + void setMuted(bool muted); + bool getMuted() const { return mMuted; } +#ifdef USE_PLUGIN_MEDIA + LLPluginClassMedia* initializeMedia(const std::string& media_type); +#endif F32 getMasterGain(); void setMasterGain(F32 gain); @@ -134,8 +132,6 @@ class LLAudioEngine virtual void setDopplerFactor(F32 factor); virtual F32 getDopplerFactor(); - virtual void setDistanceFactor(F32 factor); - virtual F32 getDistanceFactor(); virtual void setRolloffFactor(F32 factor); virtual F32 getRolloffFactor(); virtual void setMaxWindGain(F32 gain); @@ -154,19 +150,19 @@ class LLAudioEngine LLAudioSource *findAudioSource(const LLUUID &source_id); LLAudioData *getAudioData(const LLUUID &audio_uuid); - - // Internet stream methods - virtual void startInternetStream(const std::string& url); - virtual void stopInternetStream(); - virtual void pauseInternetStream(int pause); - virtual void updateInternetStream(); - virtual int isInternetStreamPlaying(); - virtual void getInternetStreamInfo(char* artist, char* title); + // Internet stream implementation manipulation + LLStreamingAudioInterface *getStreamingAudioImpl(); + void setStreamingAudioImpl(LLStreamingAudioInterface *impl); + // Internet stream methods - these will call down into the *mStreamingAudioImpl if it exists + void startInternetStream(const std::string& url); + void stopInternetStream(); + void pauseInternetStream(int pause); + void updateInternetStream(); // expected to be called often + int isInternetStreamPlaying(); // use a value from 0.0 to 1.0, inclusive - virtual void setInternetStreamGain(F32 vol); - virtual const std::string& getInternetStreamURL(); - virtual LLMediaBase::EStatus getStatus(); - + void setInternetStreamGain(F32 vol); + std::string getInternetStreamURL(); + // For debugging usage virtual LLVector3 getListenerPos(); @@ -185,8 +181,6 @@ class LLAudioEngine static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status); friend class LLPipeline; // For debugging - - LLMediaBase * getStreamMedia() { return mInternetStreamMedia; } public: F32 mMaxWindGain; // Hack. Public to set before fade in? @@ -244,21 +238,16 @@ class LLAudioEngine LLAudioBuffer *mBuffers[MAX_BUFFERS]; F32 mMasterGain; + F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true. F32 mSecondaryGain[AUDIO_TYPE_COUNT]; - // Hack! Internet streams are treated differently from other sources! - F32 mInternetStreamGain; - std::string mInternetStreamURL; - F32 mNextWindUpdate; LLFrameTimer mWindUpdateTimer; - LLMediaBase::EStatus mStatus; - private: void setDefaults(); - LLMediaBase *mInternetStreamMedia; + LLStreamingAudioInterface *mStreamingAudioImpl; }; @@ -314,7 +303,8 @@ class LLAudioSource virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); } const LLUUID &getID() const { return mID; } - bool isDone(); + bool isDone() const; + bool isMuted() const { return mSourceMuted; } LLAudioData *getCurrentData(); LLAudioData *getQueuedData(); @@ -336,6 +326,7 @@ class LLAudioSource LLUUID mOwnerID; // owner of the object playing the sound F32 mPriority; F32 mGain; + bool mSourceMuted; bool mAmbient; bool mLoop; bool mSyncMaster; diff --git a/linden/indra/llaudio/audioengine_fmod.cpp b/linden/indra/llaudio/llaudioengine_fmod.cpp similarity index 71% rename from linden/indra/llaudio/audioengine_fmod.cpp rename to linden/indra/llaudio/llaudioengine_fmod.cpp index 938c2aa2d..85ae86352 100644 --- a/linden/indra/llaudio/audioengine_fmod.cpp +++ b/linden/indra/llaudio/llaudioengine_fmod.cpp @@ -32,8 +32,11 @@ #include "linden_common.h" -#include "audioengine_fmod.h" -#include "listener_fmod.h" +#include "llstreamingaudio.h" +#include "llstreamingaudio_fmod.h" + +#include "llaudioengine_fmod.h" +#include "lllistener_fmod.h" #include "llerror.h" #include "llmath.h" @@ -46,6 +49,7 @@ #include "sound_ids.h" + extern "C" { void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata); } @@ -53,35 +57,9 @@ extern "C" { FSOUND_DSPUNIT *gWindDSP = NULL; -// Safe strcpy -#if 0 //(unused) //LL_WINDOWS || LL_LINUX -static size_t strlcpy( char* dest, const char* src, size_t dst_size ) -{ - size_t source_len = 0; - size_t min_len = 0; - if( dst_size > 0 ) - { - if( src ) - { - source_len = strlen(src); /*Flawfinder: ignore*/ - min_len = llmin( dst_size - 1, source_len ); - memcpy(dest, src, min_len); /*Flawfinder: ignore*/ - } - dest[min_len] = '\0'; - } - return source_len; -} -#else -// apple ships with the non-standard strlcpy in /usr/include/string.h: -// size_t strlcpy(char *, const char *, size_t); -#endif - - LLAudioEngine_FMOD::LLAudioEngine_FMOD() { mInited = false; - mCurrentInternetStreamp = NULL; - mInternetStreamChannel = -1; mWindGen = NULL; } @@ -93,8 +71,6 @@ LLAudioEngine_FMOD::~LLAudioEngine_FMOD() bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { - mFadeIn = -10000; - LLAudioEngine::init(num_channels, userdata); // Reserve one extra channel for the http stream. @@ -241,7 +217,9 @@ bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) #endif - initInternetStream(); + // set up our favourite FMOD-native streaming audio implementation if none has already been added + if (!getStreamingAudioImpl()) // no existing implementation added + setStreamingAudioImpl(new LLStreamingAudio_FMOD()); LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL; @@ -296,13 +274,13 @@ void LLAudioEngine_FMOD::shutdown() } -LLAudioBuffer *LLAudioEngine_FMOD::createBuffer() +LLAudioBuffer * LLAudioEngine_FMOD::createBuffer() { return new LLAudioBufferFMOD(); } -LLAudioChannel *LLAudioEngine_FMOD::createChannel() +LLAudioChannel * LLAudioEngine_FMOD::createChannel() { return new LLAudioChannelFMOD(); } @@ -432,10 +410,12 @@ void LLAudioEngine_FMOD::setInternalGain(F32 gain) gain = llclamp( gain, 0.0f, 1.0f ); FSOUND_SetSFXMasterVolume( llround( 255.0f * gain ) ); - if ( mInternetStreamChannel != -1 ) + LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); + if ( saimpl ) { - F32 clamp_internet_stream_gain = llclamp( mInternetStreamGain, 0.0f, 1.0f ); - FSOUND_SetVolumeAbsolute( mInternetStreamChannel, llround( 255.0f * clamp_internet_stream_gain ) ); + // fmod likes its streaming audio channel gain re-asserted after + // master volume change. + saimpl->setGain(saimpl->getGain()); } } @@ -660,7 +640,7 @@ bool LLAudioBufferFMOD::loadWAV(const std::string& filename) return false; } - if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB)) + if (!LLAPRFile::isExist(filename, LL_APR_RPB)) { // File not found, abort. return false; @@ -752,313 +732,6 @@ void LLAudioBufferFMOD::set3DMode(bool use3d) } - -//--------------------------------------------------------------------------- -// Internet Streaming -//--------------------------------------------------------------------------- -void LLAudioEngine_FMOD::initInternetStream() -{ - // Number of milliseconds of audio to buffer for the audio card. - // Must be larger than the usual Second Life frame stutter time. - FSOUND_Stream_SetBufferSize(200); - - // Here's where we set the size of the network buffer and some buffering - // parameters. In this case we want a network buffer of 16k, we want it - // to prebuffer 40% of that when we first connect, and we want it - // to rebuffer 80% of that whenever we encounter a buffer underrun. - - // Leave the net buffer properties at the default. - //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80); - mInternetStreamURL.clear(); -} - - -void LLAudioEngine_FMOD::startInternetStream(const std::string& url) -{ - if (!mInited) - { - llwarns << "startInternetStream before audio initialized" << llendl; - return; - } - - // "stop" stream but don't clear url, etc. in calse url == mInternetStreamURL - stopInternetStream(); - if (!url.empty()) - { - llinfos << "Starting internet stream: " << url << llendl; - mCurrentInternetStreamp = new LLAudioStreamFMOD(url); - mInternetStreamURL = url; - } - else - { - llinfos << "Set internet stream to null" << llendl; - mInternetStreamURL.clear(); - } -} - - -signed char F_CALLBACKAPI LLAudioEngine_FMOD::callbackMetaData(char *name, char *value, void *userdata) -{ - /* - LLAudioEngine_FMOD* self = (LLAudioEngine_FMOD*)userdata; - - if (!strcmp("ARTIST", name)) - { - strlcpy(self->mInternetStreamArtist, value, 256); - self->mInternetStreamNewMetaData = true; - return true; - } - - if (!strcmp("TITLE", name)) - { - strlcpy(self->mInternetStreamTitle, value, 256); - self->mInternetStreamNewMetaData = true; - return true; - } - */ - - return true; -} - - -void LLAudioEngine_FMOD::updateInternetStream() -{ - // Kill dead internet streams, if possible - std::list::iterator iter; - for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) - { - LLAudioStreamFMOD *streamp = *iter; - if (streamp->stopStream()) - { - llinfos << "Closed dead stream" << llendl; - delete streamp; - mDeadStreams.erase(iter++); - } - else - { - iter++; - } - } - - // Don't do anything if there are no streams playing - if (!mCurrentInternetStreamp) - { - return; - } - - int open_state = mCurrentInternetStreamp->getOpenState(); - - if (!open_state) - { - // Stream is live - - - // start the stream if it's ready - if (mInternetStreamChannel < 0) - { - mInternetStreamChannel = mCurrentInternetStreamp->startStream(); - - if (mInternetStreamChannel != -1) - { - // Reset volume to previously set volume - setInternetStreamGain(mInternetStreamGain); - FSOUND_SetPaused(mInternetStreamChannel, false); - //FSOUND_Stream_Net_SetMetadataCallback(mInternetStream, callbackMetaData, this); - } - } - } - - switch(open_state) - { - default: - case 0: - // success - break; - case -1: - // stream handle is invalid - llwarns << "InternetStream - invalid handle" << llendl; - stopInternetStream(); - return; - case -2: - // opening - //strlcpy(mInternetStreamArtist, "Opening", 256); - break; - case -3: - // failed to open, file not found, perhaps - llwarns << "InternetSteam - failed to open" << llendl; - stopInternetStream(); - return; - case -4: - // connecting - //strlcpy(mInternetStreamArtist, "Connecting", 256); - break; - case -5: - // buffering - //strlcpy(mInternetStreamArtist, "Buffering", 256); - break; - } - -} - -void LLAudioEngine_FMOD::stopInternetStream() -{ - if (mInternetStreamChannel != -1) - { - FSOUND_SetPaused(mInternetStreamChannel, true); - FSOUND_SetPriority(mInternetStreamChannel, 0); - mInternetStreamChannel = -1; - } - - if (mCurrentInternetStreamp) - { - llinfos << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << llendl; - if (mCurrentInternetStreamp->stopStream()) - { - delete mCurrentInternetStreamp; - } - else - { - llwarns << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << llendl; - mDeadStreams.push_back(mCurrentInternetStreamp); - } - mCurrentInternetStreamp = NULL; - //mInternetStreamURL.clear(); - } -} - -void LLAudioEngine_FMOD::pauseInternetStream(int pause) -{ - if (pause < 0) - { - pause = mCurrentInternetStreamp ? 1 : 0; - } - - if (pause) - { - if (mCurrentInternetStreamp) - { - stopInternetStream(); - } - } - else - { - startInternetStream(mInternetStreamURL); - } -} - - -// A stream is "playing" if it has been requested to start. That -// doesn't necessarily mean audio is coming out of the speakers. -int LLAudioEngine_FMOD::isInternetStreamPlaying() -{ - if (mCurrentInternetStreamp) - { - return 1; // Active and playing - } - else if (!mInternetStreamURL.empty()) - { - return 2; // "Paused" - } - else - { - return 0; - } -} - - -void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol) -{ - mInternetStreamGain = vol; - - if (mInternetStreamChannel != -1) - { - vol = llclamp(vol, 0.f, 1.f); - int vol_int = llround(vol * 255.f); - FSOUND_SetVolumeAbsolute(mInternetStreamChannel, vol_int); - } -} - - -LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) : - mInternetStream(NULL), - mReady(false) -{ - mInternetStreamURL = url; - mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0); - if (!mInternetStream) - { - llwarns << "Couldn't open fmod stream, error " - << FMOD_ErrorString(FSOUND_GetError()) - << llendl; - mReady = false; - return; - } - - mReady = true; -} - -int LLAudioStreamFMOD::startStream() -{ - // We need a live and opened stream before we try and play it. - if (!mInternetStream || getOpenState()) - { - llwarns << "No internet stream to start playing!" << llendl; - return -1; - } - - // Make sure the stream is set to 2D mode. - FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D); - - return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true); -} - -bool LLAudioStreamFMOD::stopStream() -{ - if (mInternetStream) - { - int read_percent = 0; - int status = 0; - int bitrate = 0; - unsigned int flags = 0x0; - FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags); - - bool close = true; - switch (status) - { - case FSOUND_STREAM_NET_CONNECTING: - close = false; - break; - case FSOUND_STREAM_NET_NOTCONNECTED: - case FSOUND_STREAM_NET_BUFFERING: - case FSOUND_STREAM_NET_READY: - case FSOUND_STREAM_NET_ERROR: - default: - close = true; - } - - if (close) - { - FSOUND_Stream_Close(mInternetStream); - mInternetStream = NULL; - return true; - } - else - { - return false; - } - } - else - { - return true; - } -} - -int LLAudioStreamFMOD::getOpenState() -{ - int open_state = FSOUND_Stream_GetOpenState(mInternetStream); - return open_state; -} - void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata) { // originalbuffer = fmod's original mixbuffer. diff --git a/linden/indra/llaudio/audioengine_fmod.h b/linden/indra/llaudio/llaudioengine_fmod.h similarity index 77% rename from linden/indra/llaudio/audioengine_fmod.h rename to linden/indra/llaudio/llaudioengine_fmod.h index d0d2e1bc3..3968657cb 100644 --- a/linden/indra/llaudio/audioengine_fmod.h +++ b/linden/indra/llaudio/llaudioengine_fmod.h @@ -34,13 +34,13 @@ #ifndef LL_AUDIOENGINE_FMOD_H #define LL_AUDIOENGINE_FMOD_H -#include "audioengine.h" -#include "listener_fmod.h" -#include "windgen.h" +#include "llaudioengine.h" +#include "lllistener_fmod.h" +#include "llwindgen.h" #include "fmod.h" -class LLAudioStreamFMOD; +class LLAudioStreamManagerFMOD; class LLAudioEngine_FMOD : public LLAudioEngine { @@ -50,20 +50,11 @@ class LLAudioEngine_FMOD : public LLAudioEngine // initialization/startup/shutdown virtual bool init(const S32 num_channels, void *user_data); - virtual std::string getDriverName(bool verbose); + virtual std::string getDriverName(bool verbose); virtual void allocateListener(); virtual void shutdown(); - // Internet stream methods - virtual void initInternetStream(); - virtual void startInternetStream(const std::string& url); - virtual void updateInternetStream(); - virtual void stopInternetStream(); - virtual void pauseInternetStream(int pause); - virtual int isInternetStreamPlaying(); - virtual void setInternetStreamGain(F32 vol); - /*virtual*/ void initWind(); /*virtual*/ void cleanupWind(); @@ -83,15 +74,9 @@ class LLAudioEngine_FMOD : public LLAudioEngine protected: static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata); - LLAudioStreamFMOD *mCurrentInternetStreamp; - int mInternetStreamChannel; - - std::list mDeadStreams; - //F32 mMinDistance[MAX_BUFFERS]; //F32 mMaxDistance[MAX_BUFFERS]; - S32 mFadeIn; bool mInited; // On Windows, userdata is the HWND of the application window. @@ -140,22 +125,5 @@ class LLAudioBufferFMOD : public LLAudioBuffer FSOUND_SAMPLE *mSamplep; }; -class LLAudioStreamFMOD -{ -public: - LLAudioStreamFMOD(const std::string& url); - int startStream(); - bool stopStream(); // Returns true if the stream was successfully stopped. - bool ready(); - - const std::string& getURL() { return mInternetStreamURL; } - - int getOpenState(); -protected: - FSOUND_STREAM* mInternetStream; - bool mReady; - - std::string mInternetStreamURL; -}; #endif // LL_AUDIOENGINE_FMOD_H diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/llaudioengine_openal.cpp similarity index 93% rename from linden/indra/llaudio/audioengine_openal.cpp rename to linden/indra/llaudio/llaudioengine_openal.cpp index 84305f0f7..99ab18e08 100644 --- a/linden/indra/llaudio/audioengine_openal.cpp +++ b/linden/indra/llaudio/llaudioengine_openal.cpp @@ -34,8 +34,8 @@ #include "linden_common.h" #include "lldir.h" -#include "audioengine_openal.h" -#include "listener_openal.h" +#include "llaudioengine_openal.h" +#include "lllistener_openal.h" LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() @@ -55,41 +55,15 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() { } -static ALboolean alutInitHelp(const char **errorstring) -{ - ALboolean result = AL_FALSE; - ALenum err = AL_NO_ERROR; -#if LL_WINDOWS - __try { - result = alutInit(NULL, NULL); - err = alutGetError(); - alGetError(); // hit loading of wrap_oal.dll - if(!result) *errorstring = alutGetErrorString(err); - } __except( EXCEPTION_EXECUTE_HANDLER ) { - *errorstring = "[Exception]"; - result = AL_FALSE; - } - return result; -#else - result = alutInit(NULL, NULL); - if(!result) { - err = alutGetError(); - *errorstring = alutGetErrorString(err); - } - return result; -#endif -} - // virtual bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) { - const char *errorstring = "(null)"; mWindGen = NULL; LLAudioEngine::init(num_channels, userdata); - if(!alutInitHelp(&errorstring)) + if(!alutInit(NULL, NULL)) { - llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << errorstring << llendl; + llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl; return false; } @@ -287,8 +261,6 @@ bool LLAudioChannelOpenAL::updateBuffer() mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); alSourcef(mALSource, AL_ROLLOFF_FACTOR, gAudiop->mListenerp->getRolloffFactor()); - alSourcef(mALSource, AL_REFERENCE_DISTANCE, - gAudiop->mListenerp->getDistanceFactor()); } return true; @@ -417,7 +389,7 @@ void LLAudioEngine_OpenAL::initWind() mWindGen = new LLWindGen; mWindBufFreq = mWindGen->getInputSamplingRate(); - mWindBufSamples = llceil(mWindBufFreq * 0.05f); // 1/20th sec - WIND_BUFFER_SIZE_SEC + mWindBufSamples = llceil(mWindBufFreq * WIND_BUFFER_SIZE_SEC); mWindBufBytes = mWindBufSamples * 2 /*stereo*/ * sizeof(WIND_SAMPLE_T); mWindBuf = new WIND_SAMPLE_T [mWindBufSamples * 2 /*stereo*/]; diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/llaudioengine_openal.h similarity index 95% rename from linden/indra/llaudio/audioengine_openal.h rename to linden/indra/llaudio/llaudioengine_openal.h index 8c8bfd93f..5aca03e19 100644 --- a/linden/indra/llaudio/audioengine_openal.h +++ b/linden/indra/llaudio/llaudioengine_openal.h @@ -36,10 +36,9 @@ #ifndef LL_AUDIOENGINE_OPENAL_H #define LL_AUDIOENGINE_OPENAL_H -#include "audioengine.h" -#include "listener_openal.h" -#include "windgen.h" - +#include "llaudioengine.h" +#include "lllistener_openal.h" +#include "llwindgen.h" class LLAudioEngine_OpenAL : public LLAudioEngine { @@ -74,6 +73,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine int mNumEmptyWindALBuffers; static const int MAX_NUM_WIND_BUFFERS = 80; + static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec }; class LLAudioChannelOpenAL : public LLAudioChannel diff --git a/linden/indra/llaudio/lllistener.cpp b/linden/indra/llaudio/lllistener.cpp new file mode 100644 index 000000000..846c6bccb --- /dev/null +++ b/linden/indra/llaudio/lllistener.cpp @@ -0,0 +1,142 @@ +/** + * @file listener.cpp + * @brief Implementation of LISTENER class abstracting the audio support + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "lllistener.h" + +#define DEFAULT_AT 0.0f,0.0f,-1.0f +#define DEFAULT_UP 0.0f,1.0f,0.0f + +//----------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------- +LLListener::LLListener() +{ + init(); +} + +//----------------------------------------------------------------------- +LLListener::~LLListener() +{ +} + +//----------------------------------------------------------------------- +void LLListener::init(void) +{ + mPosition.zeroVec(); + mListenAt.setVec(DEFAULT_AT); + mListenUp.setVec(DEFAULT_UP); + mVelocity.zeroVec(); +} + +//----------------------------------------------------------------------- +void LLListener::translate(LLVector3 offset) +{ + mPosition += offset; +} + +//----------------------------------------------------------------------- +void LLListener::setPosition(LLVector3 pos) +{ + mPosition = pos; +} + +//----------------------------------------------------------------------- +LLVector3 LLListener::getPosition(void) +{ + return(mPosition); +} + +//----------------------------------------------------------------------- +LLVector3 LLListener::getAt(void) +{ + return(mListenAt); +} + +//----------------------------------------------------------------------- +LLVector3 LLListener::getUp(void) +{ + return(mListenUp); +} + +//----------------------------------------------------------------------- +void LLListener::setVelocity(LLVector3 vel) +{ + mVelocity = vel; +} + +//----------------------------------------------------------------------- +void LLListener::orient(LLVector3 up, LLVector3 at) +{ + mListenUp = up; + mListenAt = at; +} + +//----------------------------------------------------------------------- +void LLListener::set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at) +{ + mPosition = pos; + mVelocity = vel; + + setPosition(pos); + setVelocity(vel); + orient(up,at); +} + +//----------------------------------------------------------------------- +void LLListener::setDopplerFactor(F32 factor) +{ +} + +//----------------------------------------------------------------------- +F32 LLListener::getDopplerFactor() +{ + return (1.f); +} + +//----------------------------------------------------------------------- +void LLListener::setRolloffFactor(F32 factor) +{ +} + +//----------------------------------------------------------------------- +F32 LLListener::getRolloffFactor() +{ + return (1.f); +} + +//----------------------------------------------------------------------- +void LLListener::commitDeferredChanges() +{ +} + diff --git a/linden/indra/llaudio/lllistener.h b/linden/indra/llaudio/lllistener.h new file mode 100644 index 000000000..e94fbe853 --- /dev/null +++ b/linden/indra/llaudio/lllistener.h @@ -0,0 +1,78 @@ +/** + * @file listener.h + * @brief Description of LISTENER base class abstracting the audio support. + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LISTENER_H +#define LL_LISTENER_H + +#include "v3math.h" + +class LLListener +{ + private: + protected: + LLVector3 mPosition; + LLVector3 mVelocity; + LLVector3 mListenAt; + LLVector3 mListenUp; + + public: + + private: + protected: + public: + LLListener(); + virtual ~LLListener(); + virtual void init(); + + virtual void set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at); + + virtual void setPosition(LLVector3 pos); + virtual void setVelocity(LLVector3 vel); + + virtual void orient(LLVector3 up, LLVector3 at); + virtual void translate(LLVector3 offset); + + virtual void setDopplerFactor(F32 factor); + virtual void setRolloffFactor(F32 factor); + + virtual LLVector3 getPosition(); + virtual LLVector3 getAt(); + virtual LLVector3 getUp(); + + virtual F32 getDopplerFactor(); + virtual F32 getRolloffFactor(); + + virtual void commitDeferredChanges(); +}; + +#endif + diff --git a/linden/indra/llaudio/lllistener_ds3d.h b/linden/indra/llaudio/lllistener_ds3d.h new file mode 100644 index 000000000..1ff9c170c --- /dev/null +++ b/linden/indra/llaudio/lllistener_ds3d.h @@ -0,0 +1,74 @@ +/** + * @file listener_ds3d.h + * @brief Description of LISTENER class abstracting the audio support + * as a DirectSound 3D implementation (windows only) + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LISTENER_DS3D_H +#define LL_LISTENER_DS3D_H + +#include "lllistener.h" + +#include +#include +#include + +class LLListener_DS3D : public LLListener +{ + private: + protected: + IDirectSound3DListener8 *m3DListener; + public: + + private: + protected: + public: + LLListener_DS3D(); + virtual ~LLListener_DS3D(); + virtual void init(); + + virtual void setDS3DLPtr (IDirectSound3DListener8 *listener_p); + + virtual void translate(LLVector3 offset); + virtual void setPosition(LLVector3 pos); + virtual void setVelocity(LLVector3 vel); + virtual void orient(LLVector3 up, LLVector3 at); + + virtual void setDopplerFactor(F32 factor); + virtual F32 getDopplerFactor(); + virtual void setRolloffFactor(F32 factor); + virtual F32 getRolloffFactor(); + + virtual void commitDeferredChanges(); +}; + +#endif + + diff --git a/linden/indra/llaudio/lllistener_fmod.cpp b/linden/indra/llaudio/lllistener_fmod.cpp new file mode 100644 index 000000000..57ad461b0 --- /dev/null +++ b/linden/indra/llaudio/lllistener_fmod.cpp @@ -0,0 +1,131 @@ +/** + * @file listener_fmod.cpp + * @brief implementation of LISTENER class abstracting the audio + * support as a FMOD 3D implementation (windows only) + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llaudioengine.h" +#include "lllistener_fmod.h" +#include "fmod.h" + +//----------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------- +LLListener_FMOD::LLListener_FMOD() +{ + init(); +} + +//----------------------------------------------------------------------- +LLListener_FMOD::~LLListener_FMOD() +{ +} + +//----------------------------------------------------------------------- +void LLListener_FMOD::init(void) +{ + // do inherited + LLListener::init(); + mDopplerFactor = 1.0f; + mRolloffFactor = 1.0f; +} + +//----------------------------------------------------------------------- +void LLListener_FMOD::translate(LLVector3 offset) +{ + LLListener::translate(offset); + + FSOUND_3D_Listener_SetAttributes(mPosition.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]); +} + +//----------------------------------------------------------------------- +void LLListener_FMOD::setPosition(LLVector3 pos) +{ + LLListener::setPosition(pos); + + FSOUND_3D_Listener_SetAttributes(pos.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]); +} + +//----------------------------------------------------------------------- +void LLListener_FMOD::setVelocity(LLVector3 vel) +{ + LLListener::setVelocity(vel); + + FSOUND_3D_Listener_SetAttributes(NULL, vel.mV, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]); +} + +//----------------------------------------------------------------------- +void LLListener_FMOD::orient(LLVector3 up, LLVector3 at) +{ + LLListener::orient(up, at); + + // Welcome to the transition between right and left + // (coordinate systems, that is) + // Leaving the at vector alone results in a L/R reversal + // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed + at = -at; + + FSOUND_3D_Listener_SetAttributes(NULL, NULL, at.mV[0],at.mV[1],at.mV[2], up.mV[0],up.mV[1],up.mV[2]); +} + +//----------------------------------------------------------------------- +void LLListener_FMOD::commitDeferredChanges() +{ + FSOUND_Update(); +} + + +void LLListener_FMOD::setRolloffFactor(F32 factor) +{ + mRolloffFactor = factor; + FSOUND_3D_SetRolloffFactor(factor); +} + + +F32 LLListener_FMOD::getRolloffFactor() +{ + return mRolloffFactor; +} + + +void LLListener_FMOD::setDopplerFactor(F32 factor) +{ + mDopplerFactor = factor; + FSOUND_3D_SetDopplerFactor(factor); +} + + +F32 LLListener_FMOD::getDopplerFactor() +{ + return mDopplerFactor; +} + + diff --git a/linden/indra/llaudio/lllistener_fmod.h b/linden/indra/llaudio/lllistener_fmod.h new file mode 100644 index 000000000..5a48ec8b6 --- /dev/null +++ b/linden/indra/llaudio/lllistener_fmod.h @@ -0,0 +1,64 @@ +/** + * @file listener_fmod.h + * @brief Description of LISTENER class abstracting the audio support + * as an FMOD 3D implementation (windows and Linux) + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LISTENER_FMOD_H +#define LL_LISTENER_FMOD_H + +#include "lllistener.h" + +class LLListener_FMOD : public LLListener +{ + public: + LLListener_FMOD(); + virtual ~LLListener_FMOD(); + virtual void init(); + + virtual void translate(LLVector3 offset); + virtual void setPosition(LLVector3 pos); + virtual void setVelocity(LLVector3 vel); + virtual void orient(LLVector3 up, LLVector3 at); + virtual void commitDeferredChanges(); + + virtual void setDopplerFactor(F32 factor); + virtual F32 getDopplerFactor(); + virtual void setRolloffFactor(F32 factor); + virtual F32 getRolloffFactor(); + + protected: + F32 mDopplerFactor; + F32 mRolloffFactor; +}; + +#endif + + diff --git a/linden/indra/llaudio/listener_openal.cpp b/linden/indra/llaudio/lllistener_openal.cpp similarity index 93% rename from linden/indra/llaudio/listener_openal.cpp rename to linden/indra/llaudio/lllistener_openal.cpp index d0ef9b2f5..a96ebd5db 100644 --- a/linden/indra/llaudio/listener_openal.cpp +++ b/linden/indra/llaudio/lllistener_openal.cpp @@ -32,9 +32,9 @@ */ #include "linden_common.h" -#include "audioengine.h" +#include "llaudioengine.h" -#include "listener_openal.h" +#include "lllistener_openal.h" LLListener_OpenAL::LLListener_OpenAL() { @@ -114,12 +114,3 @@ F32 LLListener_OpenAL::getRolloffFactor() } -void LLListener_OpenAL::setDistanceFactor(F32 factor) -{ - mDistanceFactor = factor; -} - -F32 LLListener_OpenAL::getDistanceFactor() -{ - return mDistanceFactor; -} diff --git a/linden/indra/llaudio/listener_openal.h b/linden/indra/llaudio/lllistener_openal.h similarity index 93% rename from linden/indra/llaudio/listener_openal.h rename to linden/indra/llaudio/lllistener_openal.h index 2b79ada9c..0dfeea5c9 100644 --- a/linden/indra/llaudio/listener_openal.h +++ b/linden/indra/llaudio/lllistener_openal.h @@ -34,10 +34,9 @@ #ifndef LL_LISTENER_OPENAL_H #define LL_LISTENER_OPENAL_H -#include "listener.h" +#include "lllistener.h" - -//#include "AL/al.h" +#include "AL/al.h" #include "AL/alut.h" class LLListener_OpenAL : public LLListener @@ -54,13 +53,10 @@ class LLListener_OpenAL : public LLListener virtual void setDopplerFactor(F32 factor); virtual F32 getDopplerFactor(); - virtual void setDistanceFactor(F32 factor); - virtual F32 getDistanceFactor(); virtual void setRolloffFactor(F32 factor); virtual F32 getRolloffFactor(); protected: - F32 mDistanceFactor; F32 mRolloffFactor; }; diff --git a/linden/indra/llaudio/llstreamingaudio.h b/linden/indra/llaudio/llstreamingaudio.h new file mode 100644 index 000000000..aa89e6a17 --- /dev/null +++ b/linden/indra/llaudio/llstreamingaudio.h @@ -0,0 +1,56 @@ +/** + * @file streamingaudio.h + * @author Tofu Linden + * @brief Definition of LLStreamingAudioInterface base class abstracting the streaming audio interface + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_STREAMINGAUDIO_H +#define LL_STREAMINGAUDIO_H + +#include "stdtypes.h" // from llcommon + +// Entirely abstract. Based exactly on the historic API. +class LLStreamingAudioInterface +{ + public: + virtual ~LLStreamingAudioInterface() {} + + virtual void start(const std::string& url) = 0; + virtual void stop() = 0; + virtual void pause(int pause) = 0; + virtual void update() = 0; + virtual int isPlaying() = 0; + // use a value from 0.0 to 1.0, inclusive + virtual void setGain(F32 vol) = 0; + virtual F32 getGain() = 0; + virtual std::string getURL() = 0; +}; + +#endif // LL_STREAMINGAUDIO_H diff --git a/linden/indra/llaudio/llstreamingaudio_fmod.cpp b/linden/indra/llaudio/llstreamingaudio_fmod.cpp new file mode 100644 index 000000000..a71a87203 --- /dev/null +++ b/linden/indra/llaudio/llstreamingaudio_fmod.cpp @@ -0,0 +1,362 @@ +/** + * @file streamingaudio_fmod.cpp + * @brief LLStreamingAudio_FMOD implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llmath.h" + +#include "fmod.h" +#include "fmod_errors.h" + +#include "llstreamingaudio_fmod.h" + + +class LLAudioStreamManagerFMOD +{ +public: + LLAudioStreamManagerFMOD(const std::string& url); + int startStream(); + bool stopStream(); // Returns true if the stream was successfully stopped. + bool ready(); + + const std::string& getURL() { return mInternetStreamURL; } + + int getOpenState(); +protected: + FSOUND_STREAM* mInternetStream; + bool mReady; + + std::string mInternetStreamURL; +}; + + + +//--------------------------------------------------------------------------- +// Internet Streaming +//--------------------------------------------------------------------------- +LLStreamingAudio_FMOD::LLStreamingAudio_FMOD() : + mCurrentInternetStreamp(NULL), + mFMODInternetStreamChannel(-1), + mGain(1.0f) +{ + // Number of milliseconds of audio to buffer for the audio card. + // Must be larger than the usual Second Life frame stutter time. + FSOUND_Stream_SetBufferSize(200); + + // Here's where we set the size of the network buffer and some buffering + // parameters. In this case we want a network buffer of 16k, we want it + // to prebuffer 40% of that when we first connect, and we want it + // to rebuffer 80% of that whenever we encounter a buffer underrun. + + // Leave the net buffer properties at the default. + //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80); +} + + +LLStreamingAudio_FMOD::~LLStreamingAudio_FMOD() +{ + // nothing interesting/safe to do. +} + + +void LLStreamingAudio_FMOD::start(const std::string& url) +{ + //if (!mInited) + //{ + // llwarns << "startInternetStream before audio initialized" << llendl; + // return; + //} + + // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL + stop(); + + if (!url.empty()) + { + llinfos << "Starting internet stream: " << url << llendl; + mCurrentInternetStreamp = new LLAudioStreamManagerFMOD(url); + mURL = url; + } + else + { + llinfos << "Set internet stream to null" << llendl; + mURL.clear(); + } +} + + +void LLStreamingAudio_FMOD::update() +{ + // Kill dead internet streams, if possible + std::list::iterator iter; + for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) + { + LLAudioStreamManagerFMOD *streamp = *iter; + if (streamp->stopStream()) + { + llinfos << "Closed dead stream" << llendl; + delete streamp; + mDeadStreams.erase(iter++); + } + else + { + iter++; + } + } + + // Don't do anything if there are no streams playing + if (!mCurrentInternetStreamp) + { + return; + } + + int open_state = mCurrentInternetStreamp->getOpenState(); + + if (!open_state) + { + // Stream is live + + // start the stream if it's ready + if (mFMODInternetStreamChannel < 0) + { + mFMODInternetStreamChannel = mCurrentInternetStreamp->startStream(); + + if (mFMODInternetStreamChannel != -1) + { + // Reset volume to previously set volume + setGain(getGain()); + FSOUND_SetPaused(mFMODInternetStreamChannel, false); + } + } + } + + switch(open_state) + { + default: + case 0: + // success + break; + case -1: + // stream handle is invalid + llwarns << "InternetStream - invalid handle" << llendl; + stop(); + return; + case -2: + // opening + break; + case -3: + // failed to open, file not found, perhaps + llwarns << "InternetSteam - failed to open" << llendl; + stop(); + return; + case -4: + // connecting + break; + case -5: + // buffering + break; + } + +} + +void LLStreamingAudio_FMOD::stop() +{ + if (mFMODInternetStreamChannel != -1) + { + FSOUND_SetPaused(mFMODInternetStreamChannel, true); + FSOUND_SetPriority(mFMODInternetStreamChannel, 0); + mFMODInternetStreamChannel = -1; + } + + if (mCurrentInternetStreamp) + { + llinfos << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << llendl; + if (mCurrentInternetStreamp->stopStream()) + { + delete mCurrentInternetStreamp; + } + else + { + llwarns << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << llendl; + mDeadStreams.push_back(mCurrentInternetStreamp); + } + mCurrentInternetStreamp = NULL; + //mURL.clear(); + } +} + +void LLStreamingAudio_FMOD::pause(int pauseopt) +{ + if (pauseopt < 0) + { + pauseopt = mCurrentInternetStreamp ? 1 : 0; + } + + if (pauseopt) + { + if (mCurrentInternetStreamp) + { + stop(); + } + } + else + { + start(getURL()); + } +} + + +// A stream is "playing" if it has been requested to start. That +// doesn't necessarily mean audio is coming out of the speakers. +int LLStreamingAudio_FMOD::isPlaying() +{ + if (mCurrentInternetStreamp) + { + return 1; // Active and playing + } + else if (!mURL.empty()) + { + return 2; // "Paused" + } + else + { + return 0; + } +} + + +F32 LLStreamingAudio_FMOD::getGain() +{ + return mGain; +} + + +std::string LLStreamingAudio_FMOD::getURL() +{ + return mURL; +} + + +void LLStreamingAudio_FMOD::setGain(F32 vol) +{ + mGain = vol; + + if (mFMODInternetStreamChannel != -1) + { + vol = llclamp(vol, 0.f, 1.f); + int vol_int = llround(vol * 255.f); + FSOUND_SetVolumeAbsolute(mFMODInternetStreamChannel, vol_int); + } +} + + +/////////////////////////////////////////////////////// +// manager of possibly-multiple internet audio streams + +LLAudioStreamManagerFMOD::LLAudioStreamManagerFMOD(const std::string& url) : + mInternetStream(NULL), + mReady(false) +{ + mInternetStreamURL = url; + mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0); + if (!mInternetStream) + { + llwarns << "Couldn't open fmod stream, error " + << FMOD_ErrorString(FSOUND_GetError()) + << llendl; + mReady = false; + return; + } + + mReady = true; +} + +int LLAudioStreamManagerFMOD::startStream() +{ + // We need a live and opened stream before we try and play it. + if (!mInternetStream || getOpenState()) + { + llwarns << "No internet stream to start playing!" << llendl; + return -1; + } + + // Make sure the stream is set to 2D mode. + FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D); + + return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true); +} + +bool LLAudioStreamManagerFMOD::stopStream() +{ + if (mInternetStream) + { + int read_percent = 0; + int status = 0; + int bitrate = 0; + unsigned int flags = 0x0; + FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags); + + bool close = true; + switch (status) + { + case FSOUND_STREAM_NET_CONNECTING: + close = false; + break; + case FSOUND_STREAM_NET_NOTCONNECTED: + case FSOUND_STREAM_NET_BUFFERING: + case FSOUND_STREAM_NET_READY: + case FSOUND_STREAM_NET_ERROR: + default: + close = true; + } + + if (close) + { + FSOUND_Stream_Close(mInternetStream); + mInternetStream = NULL; + return true; + } + else + { + return false; + } + } + else + { + return true; + } +} + +int LLAudioStreamManagerFMOD::getOpenState() +{ + int open_state = FSOUND_Stream_GetOpenState(mInternetStream); + return open_state; +} diff --git a/linden/indra/llaudio/llstreamingaudio_fmod.h b/linden/indra/llaudio/llstreamingaudio_fmod.h new file mode 100644 index 000000000..968ab53a0 --- /dev/null +++ b/linden/indra/llaudio/llstreamingaudio_fmod.h @@ -0,0 +1,68 @@ +/** + * @file streamingaudio_fmod.h + * @author Tofu Linden + * @brief Definition of LLStreamingAudio_FMOD implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_STREAMINGAUDIO_FMOD_H +#define LL_STREAMINGAUDIO_FMOD_H + +#include "stdtypes.h" // from llcommon + +#include "llstreamingaudio.h" + +class LLAudioStreamManagerFMOD; + +class LLStreamingAudio_FMOD : public LLStreamingAudioInterface +{ + public: + LLStreamingAudio_FMOD(); + /*virtual*/ ~LLStreamingAudio_FMOD(); + + /*virtual*/ void start(const std::string& url); + /*virtual*/ void stop(); + /*virtual*/ void pause(int pause); + /*virtual*/ void update(); + /*virtual*/ int isPlaying(); + /*virtual*/ void setGain(F32 vol); + /*virtual*/ F32 getGain(); + /*virtual*/ std::string getURL(); + +private: + LLAudioStreamManagerFMOD *mCurrentInternetStreamp; + int mFMODInternetStreamChannel; + std::list mDeadStreams; + + std::string mURL; + F32 mGain; +}; + + +#endif // LL_STREAMINGAUDIO_FMOD_H diff --git a/linden/indra/llaudio/vorbisdecode.cpp b/linden/indra/llaudio/llvorbisdecode.cpp similarity index 100% rename from linden/indra/llaudio/vorbisdecode.cpp rename to linden/indra/llaudio/llvorbisdecode.cpp diff --git a/linden/indra/llaudio/vorbisdecode.h b/linden/indra/llaudio/llvorbisdecode.h similarity index 100% rename from linden/indra/llaudio/vorbisdecode.h rename to linden/indra/llaudio/llvorbisdecode.h diff --git a/linden/indra/llaudio/llvorbisencode.cpp b/linden/indra/llaudio/llvorbisencode.cpp new file mode 100644 index 000000000..a24394da1 --- /dev/null +++ b/linden/indra/llaudio/llvorbisencode.cpp @@ -0,0 +1,505 @@ +/** + * @file vorbisencode.cpp + * @brief Vorbis encoding routine routine for Indra. + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "vorbis/vorbisenc.h" + +#include "llvorbisencode.h" +#include "llerror.h" +#include "llrand.h" +#include "llmath.h" +#include "llapr.h" + +//#if LL_DARWIN +// MBW -- XXX -- Getting rid of SecondLifeVorbis for now -- no fmod means no name collisions. +#if 0 +#include "VorbisFramework.h" + +#define vorbis_analysis mac_vorbis_analysis +#define vorbis_analysis_headerout mac_vorbis_analysis_headerout +#define vorbis_analysis_init mac_vorbis_analysis_init +#define vorbis_encode_ctl mac_vorbis_encode_ctl +#define vorbis_encode_setup_init mac_vorbis_encode_setup_init +#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed + +#define vorbis_info_init mac_vorbis_info_init +#define vorbis_info_clear mac_vorbis_info_clear +#define vorbis_comment_init mac_vorbis_comment_init +#define vorbis_comment_clear mac_vorbis_comment_clear +#define vorbis_block_init mac_vorbis_block_init +#define vorbis_block_clear mac_vorbis_block_clear +#define vorbis_dsp_clear mac_vorbis_dsp_clear +#define vorbis_analysis_buffer mac_vorbis_analysis_buffer +#define vorbis_analysis_wrote mac_vorbis_analysis_wrote +#define vorbis_analysis_blockout mac_vorbis_analysis_blockout + +#define ogg_stream_packetin mac_ogg_stream_packetin +#define ogg_stream_init mac_ogg_stream_init +#define ogg_stream_flush mac_ogg_stream_flush +#define ogg_stream_pageout mac_ogg_stream_pageout +#define ogg_page_eos mac_ogg_page_eos +#define ogg_stream_clear mac_ogg_stream_clear + +#endif + +S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg) +{ + U16 num_channels = 0; + U32 sample_rate = 0; + U32 bits_per_sample = 0; + U32 physical_file_size = 0; + U32 chunk_length = 0; + U32 raw_data_length = 0; + U32 bytes_per_sec = 0; + BOOL uncompressed_pcm = FALSE; + + unsigned char wav_header[44]; /*Flawfinder: ignore*/ + + error_msg.clear(); + + //******************************** + LLAPRFile infile ; + infile.open(in_fname,LL_APR_RB, LLAPRFile::global); + //******************************** + if (!infile.getFileHandle()) + { + error_msg = "CannotUploadSoundFile"; + return(LLVORBISENC_SOURCE_OPEN_ERR); + } + + infile.read(wav_header, 44); + physical_file_size = infile.seek(APR_END,0); + + if (strncmp((char *)&(wav_header[0]),"RIFF",4)) + { + error_msg = "SoundFileNotRIFF"; + return(LLVORBISENC_WAV_FORMAT_ERR); + } + + if (strncmp((char *)&(wav_header[8]),"WAVE",4)) + { + error_msg = "SoundFileNotRIFF"; + return(LLVORBISENC_WAV_FORMAT_ERR); + } + + // parse the chunks + + U32 file_pos = 12; // start at the first chunk (usually fmt but not always) + + while ((file_pos + 8)< physical_file_size) + { + infile.seek(APR_SET,file_pos); + infile.read(wav_header, 44); + + chunk_length = ((U32) wav_header[7] << 24) + + ((U32) wav_header[6] << 16) + + ((U32) wav_header[5] << 8) + + wav_header[4]; + +// llinfos << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << llendl; + + if (!(strncmp((char *)&(wav_header[0]),"fmt ",4))) + { + if ((wav_header[8] == 0x01) && (wav_header[9] == 0x00)) + { + uncompressed_pcm = TRUE; + } + num_channels = ((U16) wav_header[11] << 8) + wav_header[10]; + sample_rate = ((U32) wav_header[15] << 24) + + ((U32) wav_header[14] << 16) + + ((U32) wav_header[13] << 8) + + wav_header[12]; + bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22]; + bytes_per_sec = ((U32) wav_header[19] << 24) + + ((U32) wav_header[18] << 16) + + ((U32) wav_header[17] << 8) + + wav_header[16]; + } + else if (!(strncmp((char *)&(wav_header[0]),"data",4))) + { + raw_data_length = chunk_length; + } + file_pos += (chunk_length + 8); + chunk_length = 0; + } + //**************** + infile.close(); + //**************** + + if (!uncompressed_pcm) + { + error_msg = "SoundFileNotPCM"; + return(LLVORBISENC_PCM_FORMAT_ERR); + } + + if ((num_channels < 1) || (num_channels > LLVORBIS_CLIP_MAX_CHANNELS)) + { + error_msg = "SoundFileInvalidChannelCount"; + return(LLVORBISENC_MULTICHANNEL_ERR); + } + + if (sample_rate != LLVORBIS_CLIP_SAMPLE_RATE) + { + error_msg = "SoundFileInvalidSampleRate"; + return(LLVORBISENC_UNSUPPORTED_SAMPLE_RATE); + } + + if ((bits_per_sample != 16) && (bits_per_sample != 8)) + { + error_msg = "SoundFileInvalidWordSize"; + return(LLVORBISENC_UNSUPPORTED_WORD_SIZE); + } + + if (!raw_data_length) + { + error_msg = "SoundFileInvalidHeader"; + return(LLVORBISENC_CLIP_TOO_LONG); + } + + F32 clip_length = (F32)raw_data_length/(F32)bytes_per_sec; + + if (clip_length > LLVORBIS_CLIP_MAX_TIME) + { + error_msg = "SoundFileInvalidTooLong"; + return(LLVORBISENC_CLIP_TOO_LONG); + } + + return(LLVORBISENC_NOERR); +} + +S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname) +{ +#define READ_BUFFER 1024 + unsigned char readbuffer[READ_BUFFER*4+44]; /* out of the data segment, not the stack */ /*Flawfinder: ignore*/ + + ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */ + ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ + ogg_packet op; /* one raw packet of data for decode */ + + vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */ + vorbis_comment vc; /* struct that stores all the user comments */ + + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + int eos=0; + int result; + + U16 num_channels = 0; + U32 sample_rate = 0; + U32 bits_per_sample = 0; + + S32 format_error = 0; + std::string error_msg; + if ((format_error = check_for_invalid_wav_formats(in_fname, error_msg))) + { + llwarns << error_msg << ": " << in_fname << llendl; + return(format_error); + } + +#if 1 + unsigned char wav_header[44]; /*Flawfinder: ignore*/ + + S32 data_left = 0; + + LLAPRFile infile ; + infile.open(in_fname,LL_APR_RB, LLAPRFile::global); + if (!infile.getFileHandle()) + { + llwarns << "Couldn't open temporary ogg file for writing: " << in_fname + << llendl; + return(LLVORBISENC_SOURCE_OPEN_ERR); + } + + LLAPRFile outfile ; + outfile.open(out_fname,LL_APR_WPB, LLAPRFile::global); + if (!outfile.getFileHandle()) + { + llwarns << "Couldn't open upload sound file for reading: " << in_fname + << llendl; + return(LLVORBISENC_DEST_OPEN_ERR); + } + + // parse the chunks + U32 chunk_length = 0; + U32 file_pos = 12; // start at the first chunk (usually fmt but not always) + + while (infile.eof() != APR_EOF) + { + infile.seek(APR_SET,file_pos); + infile.read(wav_header, 44); + + chunk_length = ((U32) wav_header[7] << 24) + + ((U32) wav_header[6] << 16) + + ((U32) wav_header[5] << 8) + + wav_header[4]; + +// llinfos << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << llendl; + + if (!(strncmp((char *)&(wav_header[0]),"fmt ",4))) + { + num_channels = ((U16) wav_header[11] << 8) + wav_header[10]; + sample_rate = ((U32) wav_header[15] << 24) + + ((U32) wav_header[14] << 16) + + ((U32) wav_header[13] << 8) + + wav_header[12]; + bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22]; + } + else if (!(strncmp((char *)&(wav_header[0]),"data",4))) + { + infile.seek(APR_SET,file_pos+8); + // leave the file pointer at the beginning of the data chunk data + data_left = chunk_length; + break; + } + file_pos += (chunk_length + 8); + chunk_length = 0; + } + + + /********** Encode setup ************/ + + /* choose an encoding mode */ + /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */ + vorbis_info_init(&vi); + + // always encode to mono + + // SL-52913 & SL-53779 determined this quality level to be our 'good + // enough' general-purpose quality level with a nice low bitrate. + // Equivalent to oggenc -q0.5 + F32 quality = 0.05f; +// quality = (bitrate==128000 ? 0.4f : 0.1); + +// if (vorbis_encode_init(&vi, /* num_channels */ 1 ,sample_rate, -1, bitrate, -1)) + if (vorbis_encode_init_vbr(&vi, /* num_channels */ 1 ,sample_rate, quality)) +// if (vorbis_encode_setup_managed(&vi,1,sample_rate,-1,bitrate,-1) || +// vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE_AVG,NULL) || +// vorbis_encode_setup_init(&vi)) + { + llwarns << "unable to initialize vorbis codec at quality " << quality << llendl; + // llwarns << "unable to initialize vorbis codec at bitrate " << bitrate << llendl; + return(LLVORBISENC_DEST_OPEN_ERR); + } + + /* add a comment */ + vorbis_comment_init(&vc); +// vorbis_comment_add(&vc,"Linden"); + + /* set up the analysis state and auxiliary encoding storage */ + vorbis_analysis_init(&vd,&vi); + vorbis_block_init(&vd,&vb); + + /* set up our packet->stream encoder */ + /* pick a random serial number; that way we can more likely build + chained streams just by concatenation */ + ogg_stream_init(&os, ll_rand()); + + /* Vorbis streams begin with three headers; the initial header (with + most of the codec setup parameters) which is mandated by the Ogg + bitstream spec. The second header holds any comment fields. The + third header holds the bitstream codebook. We merely need to + make the headers, then pass them to libvorbis one at a time; + libvorbis handles the additional Ogg bitstream constraints */ + + { + ogg_packet header; + ogg_packet header_comm; + ogg_packet header_code; + + vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code); + ogg_stream_packetin(&os,&header); /* automatically placed in its own + page */ + ogg_stream_packetin(&os,&header_comm); + ogg_stream_packetin(&os,&header_code); + + /* We don't have to write out here, but doing so makes streaming + * much easier, so we do, flushing ALL pages. This ensures the actual + * audio data will start on a new page + */ + while(!eos){ + int result=ogg_stream_flush(&os,&og); + if(result==0)break; + outfile.write(og.header, og.header_len); + outfile.write(og.body, og.body_len); + } + + } + + + while(!eos) + { + long bytes_per_sample = bits_per_sample/8; + + long bytes=(long)infile.read(readbuffer,llclamp((S32)(READ_BUFFER*num_channels*bytes_per_sample),0,data_left)); /* stereo hardwired here */ + + if (bytes==0) + { + /* end of file. this can be done implicitly in the mainline, + but it's easier to see here in non-clever fashion. + Tell the library we're at end of stream so that it can handle + the last frame and mark end of stream in the output properly */ + + vorbis_analysis_wrote(&vd,0); +// eos = 1; + + } + else + { + long i; + long samples; + int temp; + + data_left -= bytes; + /* data to encode */ + + /* expose the buffer to submit data */ + float **buffer=vorbis_analysis_buffer(&vd,READ_BUFFER); + + i = 0; + samples = bytes / (num_channels * bytes_per_sample); + + if (num_channels == 2) + { + if (bytes_per_sample == 2) + { + /* uninterleave samples */ + for(i=0; i +#if LL_DARWIN || LL_LINUX +// not required or present on Win32 +#include +#endif + +LLProcessLauncher::LLProcessLauncher() +{ +#if LL_WINDOWS + mProcessHandle = 0; +#else + mProcessID = 0; +#endif +} + +LLProcessLauncher::~LLProcessLauncher() +{ + kill(); +} + +void LLProcessLauncher::setExecutable(const std::string &executable) +{ + mExecutable = executable; +} + +void LLProcessLauncher::setWorkingDirectory(const std::string &dir) +{ + mWorkingDir = dir; +} + +void LLProcessLauncher::clearArguments() +{ + mLaunchArguments.clear(); +} + +void LLProcessLauncher::addArgument(const std::string &arg) +{ + mLaunchArguments.push_back(arg); +} + +void LLProcessLauncher::addArgument(const char *arg) +{ + mLaunchArguments.push_back(std::string(arg)); +} + +#if LL_WINDOWS + +int LLProcessLauncher::launch(void) +{ + // If there was already a process associated with this object, kill it. + kill(); + orphan(); + + int result = 0; + + PROCESS_INFORMATION pinfo; + STARTUPINFOA sinfo; + memset(&sinfo, 0, sizeof(sinfo)); + + std::string args = "\"" + mExecutable + "\""; + for(int i = 0; i < (int)mLaunchArguments.size(); i++) + { + args += " "; + args += mLaunchArguments[i]; + } + LL_INFOS("Plugin") << "Executable: " << mExecutable << " arguments: " << args << LL_ENDL; + + // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string... + char *args2 = new char[args.size() + 1]; + strcpy(args2, args.c_str()); + + if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo ) ) + { + // TODO: do better than returning the OS-specific error code on failure... + result = GetLastError(); + if(result == 0) + { + // Make absolutely certain we return a non-zero value on failure. + result = -1; + } + } + else + { + // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on + // CloseHandle(pinfo.hProcess); // stops leaks - nothing else + mProcessHandle = pinfo.hProcess; + CloseHandle(pinfo.hThread); // stops leaks - nothing else + } + + delete[] args2; + + return result; +} + +bool LLProcessLauncher::isRunning(void) +{ + if(mProcessHandle != 0) + { + DWORD waitresult = WaitForSingleObject(mProcessHandle, 0); + if(waitresult == WAIT_OBJECT_0) + { + // the process has completed. + mProcessHandle = 0; + } + } + + return (mProcessHandle != 0); +} +bool LLProcessLauncher::kill(void) +{ + bool result = true; + + if(mProcessHandle != 0) + { + TerminateProcess(mProcessHandle,0); + + if(isRunning()) + { + result = false; + } + } + + return result; +} + +void LLProcessLauncher::orphan(void) +{ + // Forget about the process + mProcessHandle = 0; +} + +// static +void LLProcessLauncher::reap(void) +{ + // No actions necessary on Windows. +} + +#else // Mac and linux + +#include +#include +#include + +static std::list sZombies; + +// Attempt to reap a process ID -- returns true if the process has exited and been reaped, false otherwise. +static bool reap_pid(pid_t pid) +{ + bool result = false; + + pid_t wait_result = ::waitpid(pid, NULL, WNOHANG); + if(wait_result == pid) + { + result = true; + } + else if(wait_result == -1) + { + if(errno == ECHILD) + { + // No such process -- this may mean we're ignoring SIGCHILD. + result = true; + } + } + + return result; +} + +int LLProcessLauncher::launch(void) +{ + // If there was already a process associated with this object, kill it. + kill(); + orphan(); + + int result = 0; + int current_wd = -1; + + // create an argv vector for the child process + const char ** fake_argv = new const char *[mLaunchArguments.size() + 2]; // 1 for the executable path, 1 for the NULL terminator + + int i = 0; + + // add the executable path + fake_argv[i++] = mExecutable.c_str(); + + // and any arguments + for(int j=0; j < mLaunchArguments.size(); j++) + fake_argv[i++] = mLaunchArguments[j].c_str(); + + // terminate with a null pointer + fake_argv[i] = NULL; + + if(!mWorkingDir.empty()) + { + // save the current working directory + current_wd = ::open(".", O_RDONLY); + + // and change to the one the child will be executed in + if (::chdir(mWorkingDir.c_str())) + { + // chdir failed + } + } + + // flush all buffers before the child inherits them + ::fflush(NULL); + + pid_t id = vfork(); + if(id == 0) + { + // child process + + ::execv(mExecutable.c_str(), (char * const *)fake_argv); + + // If we reach this point, the exec failed. + // Use _exit() instead of exit() per the vfork man page. + _exit(0); + } + + // parent process + + if(current_wd >= 0) + { + // restore the previous working directory + if (::fchdir(current_wd)) + { + // chdir failed + } + ::close(current_wd); + } + + delete[] fake_argv; + + mProcessID = id; + + // At this point, the child process will have been created (since that's how vfork works -- the child borrowed our execution context until it forked) + // If the process doesn't exist at this point, the exec failed. + if(!isRunning()) + { + result = -1; + } + + return result; +} + +bool LLProcessLauncher::isRunning(void) +{ + if(mProcessID != 0) + { + // Check whether the process has exited, and reap it if it has. + if(reap_pid(mProcessID)) + { + // the process has exited. + mProcessID = 0; + } + } + + return (mProcessID != 0); +} + +bool LLProcessLauncher::kill(void) +{ + bool result = true; + + if(mProcessID != 0) + { + // Try to kill the process. We'll do approximately the same thing whether the kill returns an error or not, so we ignore the result. + (void)::kill(mProcessID, SIGTERM); + + // This will have the side-effect of reaping the zombie if the process has exited. + if(isRunning()) + { + result = false; + } + } + + return result; +} + +void LLProcessLauncher::orphan(void) +{ + // Disassociate the process from this object + if(mProcessID != 0) + { + // We may still need to reap the process's zombie eventually + sZombies.push_back(mProcessID); + + mProcessID = 0; + } +} + +// static +void LLProcessLauncher::reap(void) +{ + // Attempt to real all saved process ID's. + + std::list::iterator iter = sZombies.begin(); + while(iter != sZombies.end()) + { + if(reap_pid(*iter)) + { + iter = sZombies.erase(iter); + } + else + { + iter++; + } + } +} + +#endif diff --git a/linden/indra/llcommon/llprocesslauncher.h b/linden/indra/llcommon/llprocesslauncher.h new file mode 100644 index 000000000..036732f95 --- /dev/null +++ b/linden/indra/llcommon/llprocesslauncher.h @@ -0,0 +1,86 @@ +/** + * @file llprocesslauncher.h + * @brief Utility class for launching, terminating, and tracking the state of processes. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPROCESSLAUNCHER_H +#define LL_LLPROCESSLAUNCHER_H + +#if LL_WINDOWS +#include +#endif + + +/* + LLProcessLauncher handles launching external processes with specified command line arguments. + It also keeps track of whether the process is still running, and can kill it if required. +*/ + +class LLProcessLauncher +{ + LOG_CLASS(LLProcessLauncher); +public: + LLProcessLauncher(); + virtual ~LLProcessLauncher(); + + void setExecutable(const std::string &executable); + void setWorkingDirectory(const std::string &dir); + + void clearArguments(); + void addArgument(const std::string &arg); + void addArgument(const char *arg); + + int launch(void); + bool isRunning(void); + + // Attempt to kill the process -- returns true if the process is no longer running when it returns. + // Note that even if this returns false, the process may exit some time after it's called. + bool kill(void); + + // Use this if you want the external process to continue execution after the LLProcessLauncher instance controlling it is deleted. + // Normally, the destructor will attempt to kill the process and wait for termination. + // This should only be used if the viewer is about to exit -- otherwise, the child process will become a zombie after it exits. + void orphan(void); + + // This needs to be called periodically on Mac/Linux to clean up zombie processes. + static void reap(void); +private: + std::string mExecutable; + std::string mWorkingDir; + std::vector mLaunchArguments; + +#if LL_WINDOWS + HANDLE mProcessHandle; +#else + pid_t mProcessID; +#endif +}; + +#endif // LL_LLPROCESSLAUNCHER_H diff --git a/linden/indra/llinventory/llparcel.cpp b/linden/indra/llinventory/llparcel.cpp index 9c27476b0..547862f81 100644 --- a/linden/indra/llinventory/llparcel.cpp +++ b/linden/indra/llinventory/llparcel.cpp @@ -199,6 +199,12 @@ void LLParcel::init(const LLUUID &owner_id, mObscureMusic = 1; mMediaWidth = 0; mMediaHeight = 0; + setMediaCurrentURL(LLStringUtil::null); + mMediaURLFilterEnable = FALSE; + mMediaURLFilterList = LLSD::emptyArray(); + mMediaAllowNavigate = TRUE; + mMediaURLTimeout = 0.0f; + mMediaPreventCameraZoom = FALSE; mGroupID.setNull(); @@ -314,6 +320,56 @@ void LLParcel::setMediaHeight(S32 height) { mMediaHeight = height; } + +void LLParcel::setMediaCurrentURL(const std::string& url) +{ + mMediaCurrentURL = url; + // The escaping here must match the escaping in the database + // abstraction layer if it's ever added. + // This should really filter the url in some way. Other than + // simply requiring non-printable. + LLStringFn::replace_nonprintable_in_ascii(mMediaCurrentURL, LL_UNKNOWN_CHAR); + +} + +void LLParcel::setMediaURLResetTimer(F32 time) +{ + mMediaResetTimer.start(); + mMediaResetTimer.setTimerExpirySec(time); +} + +void LLParcel::setMediaURLFilterList(LLSD list) +{ + // sanity check LLSD + // must be array of strings + if (!list.isArray()) + { + return; + } + + for (S32 i = 0; i < list.size(); i++) + { + if (!list[i].isString()) + return; + } + + // can't be too big + const S32 MAX_SIZE = 50; + if (list.size() > MAX_SIZE) + { + LLSD new_list = LLSD::emptyArray(); + + for (S32 i = 0; i < llmin(list.size(), MAX_SIZE); i++) + { + new_list.append(list[i]); + } + + list = new_list; + } + + mMediaURLFilterList = list; +} + // virtual void LLParcel::setLocalID(S32 local_id) { @@ -568,6 +624,34 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr return input_stream.good(); } +BOOL LLParcel::importMediaURLFilter(std::istream& input_stream, std::string& url) +{ + skip_to_end_of_next_keyword("{", input_stream); + + while(input_stream.good()) + { + skip_comments_and_emptyspace(input_stream); + std::string line, keyword, value; + get_line(line, input_stream, MAX_STRING); + get_keyword_and_value(keyword, value, line); + + if ("}" == keyword) + { + break; + } + else if ("url" == keyword) + { + url = value; + } + else + { + llwarns << "Unknown keyword in parcel media url filter section: <" + << keyword << ">" << llendl; + } + } + return input_stream.good(); +} + // Assumes we are in a block "ParcelData" void LLParcel::packMessage(LLMessageSystem* msg) { @@ -606,9 +690,15 @@ void LLParcel::packMessage(LLSD& msg) msg["media_height"] = getMediaHeight(); msg["auto_scale"] = getMediaAutoScale(); msg["media_loop"] = getMediaLoop(); + msg["media_current_url"] = getMediaCurrentURL(); msg["obscure_media"] = getObscureMedia(); msg["obscure_music"] = getObscureMusic(); msg["media_id"] = getMediaID(); + msg["media_allow_navigate"] = getMediaAllowNavigate(); + msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom(); + msg["media_url_timeout"] = getMediaURLTimeout(); + msg["media_url_filter_enable"] = getMediaURLFilterEnable(); + msg["media_url_filter_list"] = getMediaURLFilterList(); msg["group_id"] = getGroupID(); msg["pass_price"] = mPassPrice; msg["pass_hours"] = mPassHours; @@ -678,6 +768,21 @@ void LLParcel::unpackMessage(LLMessageSystem* msg) mObscureMedia = true; mObscureMusic = true; } + + if(msg->getNumberOfBlocks("MediaLinkSharing") > 0) + { + msg->getString("MediaLinkSharing", "MediaCurrentURL", buffer); + setMediaCurrentURL(buffer); + msg->getU8 ( "MediaLinkSharing", "MediaAllowNavigate", mMediaAllowNavigate ); + msg->getU8 ( "MediaLinkSharing", "MediaURLFilterEnable", mMediaURLFilterEnable ); + msg->getU8 ( "MediaLinkSharing", "MediaPreventCameraZoom", mMediaPreventCameraZoom ); + msg->getF32( "MediaLinkSharing", "MediaURLTimeout", mMediaURLTimeout); + } + else + { + setMediaCurrentURL(LLStringUtil::null); + } + } void LLParcel::packAccessEntries(LLMessageSystem* msg, @@ -994,6 +1099,20 @@ BOOL LLParcel::isSaleTimerExpired(const U64& time) return expired; } +BOOL LLParcel::isMediaResetTimerExpired(const U64& time) +{ + if (mMediaResetTimer.getStarted() == FALSE) + { + return FALSE; + } + BOOL expired = mMediaResetTimer.checkExpirationAndReset(0.0); + if (expired) + { + mMediaResetTimer.stop(); + } + return expired; +} + void LLParcel::startSale(const LLUUID& buyer_id, BOOL is_buyer_group) { @@ -1117,6 +1236,12 @@ void LLParcel::clearParcel() mObscureMusic = 1; mMediaWidth = 0; mMediaHeight = 0; + setMediaCurrentURL(LLStringUtil::null); + setMediaURLFilterList(LLSD::emptyArray()); + setMediaURLFilterEnable(FALSE); + setMediaAllowNavigate(TRUE); + setMediaPreventCameraZoom(FALSE); + setMediaURLTimeout(0.0f); setMusicURL(LLStringUtil::null); setInEscrow(FALSE); setAuthorizedBuyerID(LLUUID::null); diff --git a/linden/indra/llinventory/llparcel.h b/linden/indra/llinventory/llparcel.h index 6f5ae87eb..47571d077 100644 --- a/linden/indra/llinventory/llparcel.h +++ b/linden/indra/llinventory/llparcel.h @@ -247,6 +247,14 @@ class LLParcel void setObscureMusic( U8 flagIn ) { mObscureMusic = flagIn; } void setMediaWidth(S32 width); void setMediaHeight(S32 height); + void setMediaCurrentURL(const std::string& url); + void setMediaURLFilterEnable(U8 enable) { mMediaURLFilterEnable = enable; } + void setMediaURLFilterList(LLSD list); + void setMediaAllowNavigate(U8 enable) { mMediaAllowNavigate = enable; } + void setMediaURLTimeout(F32 timeout) { mMediaURLTimeout = timeout; } + void setMediaPreventCameraZoom(U8 enable) { mMediaPreventCameraZoom = enable; } + + void setMediaURLResetTimer(F32 time); virtual void setLocalID(S32 local_id); // blow away all the extra crap lurking in parcels, including urls, access lists, etc @@ -300,6 +308,7 @@ class LLParcel // BOOL importStream(std::istream& input_stream); BOOL importAccessEntry(std::istream& input_stream, LLAccessEntry* entry); // BOOL exportStream(std::ostream& output_stream); + BOOL importMediaURLFilter(std::istream& input_stream, std::string& url); void packMessage(LLMessageSystem* msg); void packMessage(LLSD& msg); @@ -341,8 +350,15 @@ class LLParcel S32 getMediaHeight() const { return mMediaHeight; } U8 getMediaAutoScale() const { return mMediaAutoScale; } U8 getMediaLoop() const { return mMediaLoop; } + const std::string& getMediaCurrentURL() const { return mMediaCurrentURL; } U8 getObscureMedia() const { return mObscureMedia; } U8 getObscureMusic() const { return mObscureMusic; } + U8 getMediaURLFilterEnable() const { return mMediaURLFilterEnable; } + LLSD getMediaURLFilterList() const { return mMediaURLFilterList; } + U8 getMediaAllowNavigate() const { return mMediaAllowNavigate; } + F32 getMediaURLTimeout() const { return mMediaURLTimeout; } + U8 getMediaPreventCameraZoom() const { return mMediaPreventCameraZoom; } + S32 getLocalID() const { return mLocalID; } const LLUUID& getOwnerID() const { return mOwnerID; } const LLUUID& getGroupID() const { return mGroupID; } @@ -418,6 +434,7 @@ class LLParcel BOOL getRecordTransaction() const { return mRecordTransaction; } void setRecordTransaction(BOOL record) { mRecordTransaction = record; } + BOOL isMediaResetTimerExpired(const U64& time); // more accessors U32 getParcelFlags() const { return mParcelFlags; } @@ -595,6 +612,8 @@ class LLParcel LLVector3 mUserLookAt; ELandingType mLandingType; LLTimer mSaleTimerExpires; + LLTimer mMediaResetTimer; + S32 mGraceExtension; BOOL mRecordTransaction; @@ -624,9 +643,15 @@ class LLParcel S32 mMediaHeight; U8 mMediaAutoScale; U8 mMediaLoop; + std::string mMediaCurrentURL; U8 mObscureMedia; U8 mObscureMusic; LLUUID mMediaID; + U8 mMediaURLFilterEnable; + LLSD mMediaURLFilterList; + U8 mMediaAllowNavigate; + U8 mMediaPreventCameraZoom; + F32 mMediaURLTimeout; S32 mPassPrice; F32 mPassHours; LLVector3 mAABBMin; diff --git a/linden/indra/llmath/CMakeLists.txt b/linden/indra/llmath/CMakeLists.txt index e5ec3e1aa..c05bf1da4 100644 --- a/linden/indra/llmath/CMakeLists.txt +++ b/linden/indra/llmath/CMakeLists.txt @@ -83,3 +83,4 @@ set_source_files_properties(${llmath_HEADER_FILES} list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) +add_dependencies(llmath prepare) diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h index 9f8e539dc..0de568cbd 100644 --- a/linden/indra/llmath/llmath.h +++ b/linden/indra/llmath/llmath.h @@ -35,6 +35,7 @@ #include #include +#include #include "lldefs.h" #include "llstl.h" // *TODO: Remove when LLString is gone #include "llstring.h" // *TODO: Remove when LLString is gone @@ -60,7 +61,9 @@ #endif // Single Precision Floating Point Routines -#if _MSC_VER < 1400 +#ifndef fsqrtf +#define fsqrtf(x) ((F32)sqrt((F64)(x))) +#endif #ifndef sqrtf #define sqrtf(x) ((F32)sqrt((F64)(x))) #endif @@ -81,11 +84,6 @@ #ifndef powf #define powf(x,y) ((F32)pow((F64)(x),(F64)(y))) #endif -#endif - -#ifndef fsqrtf -#define fsqrtf(x) sqrtf(x) -#endif const F32 GRAVITY = -9.8f; diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index 4c94a5214..b0b8a94e4 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp @@ -3376,7 +3376,8 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, std::vector &segments, const LLVector3& obj_cam_vec, const LLMatrix4& mat, - const LLMatrix3& norm_mat) + const LLMatrix3& norm_mat, + S32 face_mask) { LLMemType m1(LLMemType::MTYPE_VOLUME); @@ -3384,12 +3385,17 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, normals.clear(); segments.clear(); + S32 cur_index = 0; //for each face for (face_list_t::iterator iter = mVolumeFaces.begin(); iter != mVolumeFaces.end(); ++iter) { const LLVolumeFace& face = *iter; + if (!(face_mask & (0x1 << cur_index++))) + { + continue; + } if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) { } diff --git a/linden/indra/llmath/llvolume.h b/linden/indra/llmath/llvolume.h index 2b1c60d53..0b9002f66 100644 --- a/linden/indra/llmath/llvolume.h +++ b/linden/indra/llmath/llvolume.h @@ -905,9 +905,13 @@ class LLVolume : public LLRefCount // returns number of triangle indeces required for path/profile mesh S32 getNumTriangleIndices() const; - void generateSilhouetteVertices(std::vector &vertices, std::vector &normals, std::vector &segments, const LLVector3& view_vec, - const LLMatrix4& mat, - const LLMatrix3& norm_mat); + void generateSilhouetteVertices(std::vector &vertices, + std::vector &normals, + std::vector &segments, + const LLVector3& view_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat, + S32 face_index); //get the face index of the face that intersects with the given line segment at the point //closest to start. Moves end to the point of intersection. Returns -1 if no intersection. diff --git a/linden/indra/llmath/v3math.h b/linden/indra/llmath/v3math.h index 7f96800e2..8c65d9330 100644 --- a/linden/indra/llmath/v3math.h +++ b/linden/indra/llmath/v3math.h @@ -411,8 +411,8 @@ inline bool operator<(const LLVector3 &a, const LLVector3 &b) return (a.mV[0] < b.mV[0] || (a.mV[0] == b.mV[0] && (a.mV[1] < b.mV[1] - || (a.mV[1] == b.mV[1]) - && a.mV[2] < b.mV[2]))); + || ((a.mV[1] == b.mV[1]) + && a.mV[2] < b.mV[2])))); } inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b) diff --git a/linden/indra/llmedia/CMakeLists.txt b/linden/indra/llmedia/CMakeLists.txt deleted file mode 100644 index c7b5cd10e..000000000 --- a/linden/indra/llmedia/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# -*- cmake -*- - -project(llmedia) - -include(00-Common) -include(LLAudio) -include(LLCommon) -include(LLImage) -include(LLMath) -include(LLMedia) -include(LLMessage) -include(LLWindow) -include(Mozlib) - -include_directories( - ${GSTREAMER_INCLUDE_DIRS} - ${GSTREAMER_PLUGINS_BASE_INCLUDE_DIRS} - ${LLAUDIO_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ) - -set(llmedia_SOURCE_FILES - llmediaimplcommon.cpp - llmediaimplexample1.cpp - llmediaimplexample2.cpp - llmediaimplfactory.cpp - llmediamanager.cpp - llmediaimplgstreamer.cpp - llmediaimplgstreamervidplug.cpp - llgstplaythread.cpp - ) - -set(llmedia_HEADER_FILES - CMakeLists.txt - - llmediabase.h - llmediaemitter.h - llmediaimplcommon.h - llmediaimplexample1.h - llmediaimplexample2.h - llmediaimplfactory.h - llmediaimplregister.h - llmediamanager.h - llmediaobserver.h - llmediaimplgstreamer.h - llmediaimplgstreamervidplug.h - llgstplaythread.h - ) - - # Work around a bad interaction between broken gstreamer headers and - # g++ 4.3's increased strictness. - - if (${CXX_VERSION} MATCHES "4.[23]") - set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES - COMPILE_FLAGS -Wno-error=write-strings) - endif (${CXX_VERSION} MATCHES "4.[23]") - -if (MOZLIB) - list(APPEND llmedia_SOURCE_FILES llmediaimplllmozlib.cpp) - - list(APPEND llmedia_HEADER_FILES llmediaimplllmozlib.h) -endif (MOZLIB) - -set_source_files_properties(${llmedia_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND llmedia_SOURCE_FILES ${llmedia_HEADER_FILES}) - -add_library (llmedia ${llmedia_SOURCE_FILES}) -target_link_libraries( - llmedia - ${GSTREAMER_LIBRARIES} - ${GSTREAMER_PLUGINS_BASE_LIBRARIES} - ${QUICKTIME_LIBRARY} - ) diff --git a/linden/indra/llmedia/llgstplaythread.cpp b/linden/indra/llmedia/llgstplaythread.cpp deleted file mode 100644 index 152f9d95c..000000000 --- a/linden/indra/llmedia/llgstplaythread.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file llgstplaythread.cpp - * @author Jacek Antonelli - * @brief GStreamer playback management thread class - * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Jacek Antonelli - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $/LicenseInfo$ - */ - -#include "llgstplaythread.h" -#include "llmediaimplgstreamer.h" - -LLGstPlayThread:: -LLGstPlayThread( LLMediaImplCommon *impl, - const std::string& name, apr_pool_t *poolp ): - LLThread( name, poolp ), - mMediaImpl( impl ) -{ -} - - -LLGstPlayThread::~LLGstPlayThread() -{ -} - - -// virtual -void LLGstPlayThread::run() -{ - ((LLMediaImplGStreamer *)mMediaImpl)->startPlay(); -} diff --git a/linden/indra/llmedia/llgstplaythread.h b/linden/indra/llmedia/llgstplaythread.h deleted file mode 100644 index c3c36a746..000000000 --- a/linden/indra/llmedia/llgstplaythread.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file llgstplaythread.h - * @author Jacek Antonelli - * @brief GStreamer playback management thread class - * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Jacek Antonelli - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $/LicenseInfo$ - */ - - -#ifndef LL_LLGSTPLAYTHREAD_H -#define LL_LLGSTPLAYTHREAD_H - -#include "linden_common.h" - -#include "llthread.h" -#include "llmediaimplcommon.h" - -class LLGstPlayThread: public LLThread -{ - public: - - LLGstPlayThread( LLMediaImplCommon *impl, - const std::string& name, apr_pool_t *poolp ); - - ~LLGstPlayThread(); - - virtual void run(); - - private: - - // Actually, this will really only be an LLMediaImplGStreamer. - // But we have to jump through some hoops to mutual pointer-holding. - // There may be a better way, but I don't have the motivation to find it. - LLMediaImplCommon *mMediaImpl; -}; - - -#endif // LL_LLGSTPLAYTHREAD_H diff --git a/linden/indra/llmedia/llmediabase.h b/linden/indra/llmedia/llmediabase.h deleted file mode 100644 index 3bcee4ea1..000000000 --- a/linden/indra/llmedia/llmediabase.h +++ /dev/null @@ -1,265 +0,0 @@ -/** - * @file llmediabase.h - * @author Callum Prentice - * @date 2007-10-22 00:00:00 - * @brief Abstract class that defines LLMedia public interface - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIABASE_H -#define LLMEDIABASE_H - -#if LL_LLMOZLIB_ENABLED && !defined ( MOZILLA_INTERNAL_API ) - // Without this, nsTAString.h errors out with: - // "Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead." - // It might be worth our while to figure out if we can use the frozen apis at some point... - #define MOZILLA_INTERNAL_API 1 -#endif - -#include - -class LLMediaObserver; -class LLMediaImplMakerBase; - -class LLMediaBase -{ - public: - LLMediaBase() {}; - virtual ~LLMediaBase() {}; - - //////////////////////////////////////////////////////////////////////////////// - // housekeeping - - // local initialization, called by the media manager when creating a source - virtual bool init() = 0; - - // undoes everything init() didm called by the media manager when destroying a source - virtual bool reset() = 0; - - - /* Mirrors GStreamer debug levels. */ - enum EDebugLevel { - DEBUG_LEVEL_NONE = 0, - DEBUG_LEVEL_ERROR, - DEBUG_LEVEL_WARNING, - DEBUG_LEVEL_INFO, - DEBUG_LEVEL_DEBUG, - DEBUG_LEVEL_LOG, - DEBUG_LEVEL_COUNT, - }; - - /* Set the debug verbosity level. Only implemented for GStreamer. */ - virtual bool setDebugLevel( EDebugLevel level ) = 0; - - // accessor for MIME type - virtual bool setMimeType( const std::string mime_type ) = 0; - virtual std::string getMimeType() const = 0; - - // accessor for intial URL. Note that this may have changed under the hood - // so pass back the original URL seeded to this impl - virtual std::string getMediaURL() const = 0; - - // ask impl for version string - virtual std::string getVersion() = 0; - - // set/clear URL to visit when a 404 page is reached - virtual bool set404RedirectUrl( std::string redirect_url ) = 0; - virtual bool clr404RedirectUrl() = 0; - - // sets the background color of the browser window - virtual bool setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const = 0; - - // sets the color of the caret in media impls that have one - virtual bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const = 0; - - //////////////////////////////////////////////////////////////////////////////// - // media management - - // needs to be called regularly to make media stream update itself - virtual bool updateMedia() = 0; - - // allows you to request a change in media width, height - may fail if media doesn't support size change - virtual bool setRequestedMediaSize( int media_width, int media_height ) = 0; - - // gets media width (may change throughout lifetime of media stream) - event emitted when media size changed too - virtual int getMediaWidth() const = 0; - - // gets media height (may change throughout lifetime of media stream) - event emitted when media size changed too - virtual int getMediaHeight() const = 0; - - // allows you to try to explicitly change media depth - may fail if media doesn't support depth change - virtual bool setMediaDepth( int media_depth ) = 0; - - // gets media depth (may change throughout lifetime of media stream) - event emitted when media depth changed too - virtual int getMediaDepth() const = 0; - - // gets size of media buffer for current frame (might NOT be the same as media width * height * depth) - virtual int getMediaBufferSize() const = 0; - - // returns pointer to raw media pixels - virtual unsigned char* getMediaData() = 0; - - // returns the size of the data, which may be different that the size of the media - virtual int getMediaDataWidth() const = 0; - virtual int getMediaDataHeight() const = 0; - - //////////////////////////////////////////////////////////////////////////////// - // texture management - - // gets internal format to use for OpenGL texture - virtual int getTextureFormatInternal() const = 0; - - // gets primary format to use for OpenGL texture - virtual int getTextureFormatPrimary() const = 0; - - // gets format type to use for OpenGL texture - virtual int getTextureFormatType() const = 0; - - - - - //////////////////////////////////////////////////////////////////////////////// - // audio - - // set/get control volume from media stream if present - virtual bool setVolume( float volume ) = 0; - virtual float getVolume() const = 0; - - - //////////////////////////////////////////////////////////////////////////////// - // transport control etc. - enum ECommand { - COMMAND_NONE = 0, - COMMAND_STOP = 1, - COMMAND_START = 2, - COMMAND_PAUSE = 4, - COMMAND_BACK = 5, - COMMAND_FORWARD = 6 - }; - enum EStatus { - STATUS_UNKNOWN = 0, - STATUS_INITIALIZING = 1, - STATUS_NAVIGATING = 2, - STATUS_STARTED = 3, - STATUS_STOPPED = 4, - STATUS_PAUSED = 6, - STATUS_RESETTING = 7, - STATUS_DEAD = 8 - }; - virtual bool addCommand( ECommand cmd ) = 0; - virtual bool clearCommand() = 0; - virtual bool updateCommand() = 0; - virtual EStatus getStatus() = 0; - virtual bool seek( double time ) = 0; - virtual bool setLooping( bool enable) = 0; - virtual bool isLooping() = 0; - - //////////////////////////////////////////////////////////////////////////////// - // scaling - - // autoscale means try to scale media to size of texture - may fail if media doesn't support size change - virtual bool setAutoScaled( bool auto_scaled ) = 0; - virtual bool isAutoScaled() const = 0; - - - //////////////////////////////////////////////////////////////////////////////// - // mouse and keyboard interaction - virtual bool mouseDown( int x_pos, int y_pos ) = 0; - virtual bool mouseUp( int x_pos, int y_pos ) = 0; - virtual bool mouseMove( int x_pos, int y_pos ) = 0; - virtual bool keyPress( int key_code ) = 0; - virtual bool scrollByLines( int lines ) = 0; - virtual bool focus( bool focus ) = 0; - virtual bool unicodeInput( unsigned long uni_char ) = 0; - virtual bool mouseLeftDoubleClick( int x_pos, int y_pos ) = 0; - - - //////////////////////////////////////////////////////////////////////////////// - // navigation - virtual bool navigateTo( const std::string url ) = 0; - virtual bool navigateForward() = 0; - virtual bool navigateBack() = 0; - virtual bool canNavigateForward() = 0; - virtual bool canNavigateBack() = 0; - - //////////////////////////////////////////////////////////////////////////////// - // caching/cookies - virtual bool enableCookies( bool enable ) = 0; - virtual bool clearCache() = 0; - virtual bool clearCookies() = 0; - - //////////////////////////////////////////////////////////////////////////////// - // proxy - virtual bool enableProxy(bool enable, std::string proxy_host_name, int proxy_port) = 0; - - //////////////////////////////////////////////////////////////////////////////// - // observer interface - virtual bool addObserver( LLMediaObserver* subject ) = 0; - virtual bool remObserver( LLMediaObserver* subject ) = 0; - - //////////////////////////////////////////////////////////////////////////////// - // factory interface - virtual void setImplMaker(LLMediaImplMakerBase* impl_maker) = 0; - - //////////////////////////////////////////////////////////////////////////////// - // type registry interface - virtual bool supportsMediaType(std::string scheme, std::string type) = 0; -}; - -////////////////////////////////////////////////////////////// -// media key codes - (mirroring mozilla's values) -const unsigned long LL_MEDIA_KEY_BACKSPACE = 0x08; -const unsigned long LL_MEDIA_KEY_TAB = 0x09; -const unsigned long LL_MEDIA_KEY_RETURN = 0x0D; -const unsigned long LL_MEDIA_KEY_PAD_RETURN = 0x0E; -const unsigned long LL_MEDIA_KEY_ESCAPE = 0x1B; -const unsigned long LL_MEDIA_KEY_PAGE_UP = 0x21; -const unsigned long LL_MEDIA_KEY_PAGE_DOWN = 0x22; -const unsigned long LL_MEDIA_KEY_END = 0x23; -const unsigned long LL_MEDIA_KEY_HOME = 0x24; -const unsigned long LL_MEDIA_KEY_LEFT = 0x25; -const unsigned long LL_MEDIA_KEY_UP = 0x26; -const unsigned long LL_MEDIA_KEY_RIGHT = 0x27; -const unsigned long LL_MEDIA_KEY_DOWN = 0x28; -const unsigned long LL_MEDIA_KEY_INSERT = 0x2D; -const unsigned long LL_MEDIA_KEY_DELETE = 0x2E; - -////////////////////////////////////////////////////////////// -// media frame buffer types - (mirroring GL values) -const int LL_MEDIA_UNSIGNED_BYTE = 0x1401; -const int LL_MEDIA_RGB = 0x1907; -const int LL_MEDIA_RGBA = 0x1908; -const int LL_MEDIA_RGB8 = 0x8051; -const int LL_MEDIA_UNSIGNED_INT_8_8_8_8 = 0x8035; -const int LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV = 0x8367; -const int LL_MEDIA_BGR = 0x80E0; -const int LL_MEDIA_BGRA = 0x80E1; - - -#endif // LLMEDIABASE_H diff --git a/linden/indra/llmedia/llmediaemitter.h b/linden/indra/llmedia/llmediaemitter.h deleted file mode 100644 index ef3caeb5c..000000000 --- a/linden/indra/llmedia/llmediaemitter.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file llmediaemitter.h - * @author Callum Prentice - * @date 2007-10-22 00:00:00 - * @brief Manages and emits events to observers - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAEMITTER_H -#define LLMEDIAEMITTER_H - -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -// -template< class T > -class LLMediaEmitter -{ - public: - LLMediaEmitter() { }; - ~LLMediaEmitter() { }; - - typedef typename T::EventType EventType; - typedef std::list< T* > ObserverContainer; - typedef void( T::*observerMethod )( const EventType& ); - - /////////////////////////////////////////////////////////////////////////////// - // - bool addObserver( T* observer_in ) - { - if ( ! observer_in ) - return false; - - if ( std::find( observers.begin(), observers.end(), observer_in) != observers.end() ) - return false; - - observers.push_back( observer_in ); - - return true; - }; - - /////////////////////////////////////////////////////////////////////////////// - // - bool remObserver( T* observer_in ) - { - if ( ! observer_in ) - return false; - - observers.remove( observer_in ); - observers.remove( observer_in ); - observers.remove( observer_in ); - - - - return true; - }; - - /////////////////////////////////////////////////////////////////////////////// - // - void update( observerMethod method, const EventType& msgIn ) - { - typename std::list< T* >::iterator iter = observers.begin(); - - while( iter != observers.end() ) - { - ( ( *iter )->*method )( msgIn ); - - ++iter; - }; - }; - - protected: - ObserverContainer observers; -}; - -#endif // LLMEDIAEMITTER_H diff --git a/linden/indra/llmedia/llmediaimplcommon.cpp b/linden/indra/llmedia/llmediaimplcommon.cpp deleted file mode 100644 index 166e86d2a..000000000 --- a/linden/indra/llmedia/llmediaimplcommon.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/** - * @file llmediaimplcommon.cpp - * @brief Common impl functionality - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llmediaimplcommon.h" -#include "llmediaemitter.h" -#include "llmediaimplfactory.h" -#include "llmediaobserver.h" - -#ifdef WIN32 - // platform specific includes needed before OpenGL header - #include - #include -#elif defined(__APPLE__) - // framework-style include path when building on the Mac. - #include -#else // Assume this is linux - // Linux, MESA headers, but not necessarily assuming MESA runtime. - // quotes so we get libraries/.../GL/ version - #include "GL/gl.h" -#endif - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -LLMediaImplCommon::LLMediaImplCommon() : - mMimeType( std::string() ), - mInitialURL( std::string() ), - mImplMaker( NULL ), - mAutoScaled( false ), - mMediaWidth( 0 ), - mMediaPrevWidth( 0 ), - mMediaHeight( 0 ), - mMediaPrevHeight( 0 ), - mMediaDepth( 0 ), - mMediaPrevDepth( 0 ), - mMediaRowSpan( 0 ), - mMediaRequestedWidth( 0 ), - mMediaRequestedHeight( 0 ), - mCommand( LLMediaBase::COMMAND_NONE ), - mStatus( LLMediaBase::STATUS_UNKNOWN ), - mVolume( 0 ), - mLooping( false ), - mDebugLevel( LLMediaBase::DEBUG_LEVEL_NONE ) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -LLMediaImplCommon::~LLMediaImplCommon() -{ -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::init() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::reset() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setDebugLevel( LLMediaBase::EDebugLevel level ) -{ - mDebugLevel = level; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setMimeType( const std::string mime_type ) -{ - mMimeType = mime_type; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -std::string LLMediaImplCommon::getMimeType() const -{ - return mMimeType; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -std::string LLMediaImplCommon::getMediaURL() const -{ - return mInitialURL; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -std::string LLMediaImplCommon::getVersion() -{ - return std::string( "" ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::set404RedirectUrl( std::string redirect_url ) -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::clr404RedirectUrl() -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::updateMedia() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -unsigned char* LLMediaImplCommon::getMediaData() -{ - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getMediaDataWidth() const -{ - return getMediaWidth(); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getMediaDataHeight() const -{ - return getMediaHeight(); -} - - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setMediaSize( int media_width, int media_height ) -{ - // if nothing changed, don't do anything - if ( ( mMediaWidth == media_width ) && - ( mMediaHeight == media_height ) ) - return false; - - // save old values so we can tell elsewhere if media size has changed - mMediaPrevWidth = mMediaWidth; - mMediaPrevHeight = mMediaHeight; - - mMediaWidth = media_width; - mMediaHeight = media_height; - - // only fire an event if the width changed - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getMediaWidth() const -{ - return mMediaWidth; -} - - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getMediaHeight() const -{ - return mMediaHeight; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setRequestedMediaSize(int width, int height) -{ - mMediaRequestedWidth = width; - mMediaRequestedHeight = height; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setMediaDepth( int media_depth ) -{ - // if nothing changed, don't do anything - if ( mMediaDepth == media_depth ) - return false; - - // save old values so we can tell elsewhere if media size has changed - mMediaPrevDepth = mMediaDepth; - mMediaDepth = media_depth; - - // update value of rowspan too since it's based on media width & depth - mMediaRowSpan = mMediaWidth * mMediaDepth; - - // only fire an event if the depth changed - //LLMediaEvent event( this ); - //mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getMediaDepth() const -{ - return mMediaDepth; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getMediaBufferSize() const -{ - return mMediaRowSpan * mMediaHeight; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getTextureFormatInternal() const -{ - return LL_MEDIA_RGB; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getTextureFormatPrimary() const -{ - return LL_MEDIA_RGB; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -int LLMediaImplCommon::getTextureFormatType() const -{ - return LL_MEDIA_UNSIGNED_BYTE; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setVolume( float volume ) -{ - mVolume = volume; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -float LLMediaImplCommon::getVolume() const -{ - return mVolume; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::addCommand( LLMediaBase::ECommand cmd ) -{ - // eventually will be a std::queue so you can add multiple commands - mCommand = cmd; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::clearCommand() -{ - // eventually will be a std::queue so you can add multiple commands - mCommand = LLMediaBase::COMMAND_NONE; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::updateCommand() -{ - if ( nextCommand() == LLMediaBase::COMMAND_START ) - { - setStatus( LLMediaBase::STATUS_STARTED ); - clearCommand(); - }; - - if ( nextCommand() == LLMediaBase::COMMAND_STOP ) - { - setStatus( LLMediaBase::STATUS_STOPPED ); - clearCommand(); - }; - - if ( nextCommand() == LLMediaBase::COMMAND_PAUSE ) - { - setStatus( LLMediaBase::STATUS_PAUSED ); - clearCommand(); - }; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// non-virtual (only impls use this) -LLMediaBase::ECommand LLMediaImplCommon::nextCommand() -{ - return mCommand; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -LLMediaBase::EStatus LLMediaImplCommon::getStatus() -{ - return mStatus; -} - -//////////////////////////////////////////////////////////////////////////////// -// non-virtual (only impls set this) -bool LLMediaImplCommon::setStatus( LLMediaBase::EStatus status ) -{ - mStatus = status; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::seek( double time ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::navigateTo( const std::string url ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::setAutoScaled( bool auto_scaled ) -{ - mAutoScaled = auto_scaled; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::isAutoScaled() const -{ - return mAutoScaled; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::mouseDown( int x_pos, int y_pos ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::mouseUp( int x_pos, int y_pos ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::mouseMove( int x_pos, int y_pos ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::keyPress( int key_code ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::scrollByLines( int lines ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::focus( bool focus ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::unicodeInput( unsigned long uni_char ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::mouseLeftDoubleClick( int x_pos, int y_pos ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::navigateForward() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::navigateBack() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::canNavigateForward() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::canNavigateBack() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::enableCookies( bool enable ) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::clearCache() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::clearCookies() -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual (derives from LLMediaBase) -bool LLMediaImplCommon::enableProxy(bool enable, std::string proxy_host_name, int proxy_port) -{ - return false; -} -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplCommon::addObserver( LLMediaObserver* subject ) -{ - return mEventEmitter.addObserver( subject ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplCommon::remObserver( LLMediaObserver* subject ) -{ - return mEventEmitter.remObserver( subject ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaImplCommon::setImplMaker(LLMediaImplMakerBase* impl_maker) -{ - mImplMaker = impl_maker; -} -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplCommon::supportsMediaType(std::string scheme, std::string type) -{ - int idx1 = type.find("/"); - int len = (idx1 == std::string::npos) ? 0 : idx1; - std::string category = type.substr(0,len); - - return mImplMaker->supportsScheme(scheme) || - mImplMaker->supportsMimeType(type) || - mImplMaker->supportsMimeTypeCategory(category); -} diff --git a/linden/indra/llmedia/llmediaimplcommon.h b/linden/indra/llmedia/llmediaimplcommon.h deleted file mode 100644 index 845429cf8..000000000 --- a/linden/indra/llmedia/llmediaimplcommon.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @file llmediaimplcommon.h - * @brief Common impl functionality - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAIMPLCOMMON_H -#define LLMEDIAIMPLCOMMON_H - -#include "llmediabase.h" -#include "llmediaemitter.h" -#include "llmediaobserver.h" - -#include - -class LLMediaImplMakerBase; - -class LLMediaImplCommon : - public LLMediaBase -{ - public: - LLMediaImplCommon(); - virtual ~LLMediaImplCommon(); - - //////////////////////////////////////////////////////////////////////////////// - // begin: default implementation of the abstract interface - // see llmediabase.h for documentation - - // housekeeping - virtual bool init(); - virtual bool reset(); - virtual bool setDebugLevel( LLMediaBase::EDebugLevel level ); - virtual bool setMimeType( const std::string url ); - virtual std::string getMimeType() const; - virtual std::string getMediaURL() const; - virtual std::string getVersion(); - virtual bool set404RedirectUrl( std::string redirect_url ); - virtual bool clr404RedirectUrl(); - virtual bool setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const; - virtual bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const; - - // media management - virtual bool updateMedia(); - virtual bool setRequestedMediaSize( int width, int height ); - virtual int getMediaWidth() const; - virtual int getMediaHeight() const; - virtual int getMediaDepth() const; - virtual int getMediaBufferSize() const; - virtual unsigned char* getMediaData(); - virtual int getMediaDataWidth() const; - virtual int getMediaDataHeight() const; - - // texture management - virtual int getTextureFormatInternal() const; - virtual int getTextureFormatPrimary() const; - virtual int getTextureFormatType() const; - - // audio - virtual bool setVolume( float volume ); - virtual float getVolume() const; - - // transport control - virtual bool addCommand( ECommand cmd ); - virtual bool clearCommand(); - virtual bool updateCommand(); - LLMediaBase::ECommand nextCommand(); - virtual LLMediaBase::EStatus getStatus(); - bool setStatus( LLMediaBase::EStatus status ); - - virtual bool seek( double time ); - virtual bool setLooping(bool enable) { mLooping = enable; return true; } - virtual bool isLooping() { return mLooping; } - virtual bool navigateTo( const std::string url ); - - // scaling - virtual bool setAutoScaled( bool auto_scaled ); - virtual bool isAutoScaled() const; - - // mouse and keyboard interaction - virtual bool mouseDown( int x_pos, int y_pos ); - virtual bool mouseUp( int x_pos, int y_pos ); - virtual bool mouseMove( int x_pos, int y_pos ); - virtual bool keyPress( int key_code ); - virtual bool scrollByLines( int lines ); - virtual bool focus( bool focus ); - virtual bool unicodeInput( unsigned long uni_char ); - virtual bool mouseLeftDoubleClick( int x_pos, int y_pos ); - - // navigation - virtual bool navigateForward(); - virtual bool navigateBack(); - virtual bool canNavigateForward(); - virtual bool canNavigateBack(); - - // caching/cookies - virtual bool enableCookies( bool enable ); - virtual bool clearCache(); - virtual bool clearCookies(); - - virtual bool enableProxy(bool enable, std::string proxy_host_name, int proxy_port); - - // observer interface - bool addObserver( LLMediaObserver* subject ); - bool remObserver( LLMediaObserver* subject ); - - // type registry interface - void setImplMaker(LLMediaImplMakerBase* impl_maker); - bool supportsMediaType(std::string scheme, std::string type); - - protected: - virtual bool setMediaSize( int width, int height ); - virtual bool setMediaDepth( int media_depth ); - - LLMediaEmitter< LLMediaObserver > mEventEmitter; - - // Back pointer to the construction object, which is used to discover types handled - // by the Impl, and meta data associated with the Impl. - LLMediaImplMakerBase* mImplMaker; - std::string mMimeType; - std::string mInitialURL; - bool mAutoScaled; - int mMediaWidth; - int mMediaPrevWidth; - int mMediaHeight; - int mMediaPrevHeight; - int mMediaDepth; - int mMediaPrevDepth; - int mMediaRowSpan; - int mMediaRequestedWidth; - int mMediaRequestedHeight; - float mVolume; - LLMediaBase::ECommand mCommand; - LLMediaBase::EStatus mStatus; - bool mLooping; - LLMediaBase::EDebugLevel mDebugLevel; -}; - -#endif // LLMEDIAIMPLCOMMON_H diff --git a/linden/indra/llmedia/llmediaimplexample1.cpp b/linden/indra/llmedia/llmediaimplexample1.cpp deleted file mode 100644 index fe7b7e286..000000000 --- a/linden/indra/llmedia/llmediaimplexample1.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file llmediaimplexample1.cpp - * @brief Example 1 of a media impl concrete class - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llmediaimplexample1.h" -#include "llmediaimplregister.h" - -#include - -// register this impl with media manager factory -static LLMediaImplRegister sLLMediaImplExample1Reg( "LLMediaImplExample1", new LLMediaImplExample1Maker() ); - -#include - -#include - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplExample1Maker::LLMediaImplExample1Maker() -{ - // Register to handle the scheme - mSchema.push_back( "example1" ); -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplExample1::LLMediaImplExample1() : - mMediaPixels( 0 ) -{ - setRequestedMediaSize( 400, 200 ); - setMediaDepth( 3 ); - - srand( (unsigned int)(time( NULL )) ); -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-initialization - called once at application startup -bool LLMediaImplExample1::startup( LLMediaManagerData* init_data ) -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-uninitialization - called once at application closedown -bool LLMediaImplExample1::closedown() -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample1::init() -{ - int buffer_size = getMediaBufferSize(); - - mMediaPixels = new unsigned char[ buffer_size ]; - - memset( mMediaPixels, 0xAA, buffer_size ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample1::navigateTo( const std::string url ) -{ - std::cout << "LLMediaImplExample1::navigateTo" << std::endl; - - setStatus( LLMediaBase::STATUS_NAVIGATING ); - - // force a size change event for new URL - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -std::string LLMediaImplExample1::getVersion() -{ - std::string version_string = "[" + sLLMediaImplExample1Reg.getImplName() + "] - " + "1.0.0.0"; - - return version_string; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample1::updateMedia() -{ - if ( mMediaPixels && getStatus() == LLMediaBase::STATUS_STARTED ) - { - // first time - make sure it's a few seconds back so first update happens immediately - static time_t t = time( 0 ) - 4; - - // selected time period elapsed (1 second) - if ( time( 0 ) - t > 1 ) - { - // display checkerboard - const int num_squares = rand() % 20 + 4; - int sqr1_r = rand() % 0x80; - int sqr1_g = rand() % 0x80; - int sqr1_b = rand() % 0x80; - int sqr2_r = rand() % 0x80; - int sqr2_g = rand() % 0x80; - int sqr2_b = rand() % 0x80; - - for ( int y1 = 0; y1 < num_squares; ++y1 ) - { - for ( int x1 = 0; x1 < num_squares; ++x1 ) - { - int px_start = getMediaWidth() * x1 / num_squares; - int px_end = ( getMediaWidth() * ( x1 + 1 ) ) / num_squares; - int py_start = getMediaHeight() * y1 / num_squares; - int py_end = ( getMediaHeight() * ( y1 + 1 ) ) / num_squares; - - for( int y2 = py_start; y2 < py_end; ++y2 ) - { - for( int x2 = px_start; x2 < px_end; ++x2 ) - { - int rowspan = getMediaWidth() * getMediaDepth(); - - if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) - { - mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 0 ] = sqr1_r; - mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 1 ] = sqr1_g; - mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 2 ] = sqr1_b; - } - else - { - mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 0 ] = sqr2_r; - mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 1 ] = sqr2_g; - mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 2 ] = sqr2_b; - }; - }; - }; - }; - }; - - // emit an event to say that something in the media stream changed - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); - - // reset time - t = time( 0 ); - - return true; - }; - }; - - // update the command (e.g. transport controls) state - updateCommand(); - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -unsigned char* LLMediaImplExample1::getMediaData() -{ - return mMediaPixels; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample1::reset() -{ - if ( mMediaPixels ) - { - delete [] mMediaPixels; - }; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample1::mouseMove( int x_pos, int y_pos ) -{ - if ( mMediaPixels && getStatus() == LLMediaBase::STATUS_STARTED ) - { - int base_pos = x_pos * getMediaDepth() + y_pos * getMediaDepth() * getMediaWidth(); - // example: write a bright pixel to the display when we move the mouse - mMediaPixels[ base_pos + 0 ] = rand() % 0x80 + 0x80; - mMediaPixels[ base_pos + 1 ] = rand() % 0x80 + 0x80; - mMediaPixels[ base_pos + 2 ] = rand() % 0x80 + 0x80; - - // emit an event to say that something in the media stream changed - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); - }; - - return true; -} - - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample1::setRequestedMediaSize( int width, int height ) -{ - // we accept any size: - return setMediaSize(width, height); -} diff --git a/linden/indra/llmedia/llmediaimplexample2.cpp b/linden/indra/llmedia/llmediaimplexample2.cpp deleted file mode 100644 index 7590e19b0..000000000 --- a/linden/indra/llmedia/llmediaimplexample2.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/** - * @file llmediaimplexample2.cpp - * @brief Example 2 of a media impl concrete class - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llmediaimplexample2.h" -#include "llmediaimplregister.h" - -#include - -// register this impl with media manager factory -static LLMediaImplRegister sLLMediaImplExample2Reg( "LLMediaImplExample2", new LLMediaImplExample2Maker() ); - -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplExample2Maker::LLMediaImplExample2Maker() -{ - // Register to handle the scheme - mSchema.push_back( "example2." ); -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplExample2::LLMediaImplExample2() : - mMediaPixels( 0 ) -{ - setRequestedMediaSize( 500, 500 ); - setMediaDepth( 3 ); - - mXpos = ( getMediaWidth() / 2 ) + rand() % ( getMediaWidth() / 16 ) - ( getMediaWidth() / 32 ); - mYpos = ( getMediaHeight() / 2 ) + rand() % ( getMediaHeight() / 16 ) - ( getMediaHeight() / 32 ); - - srand( (unsigned int)(time( NULL )) ); -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-initialization - called once at application startup -bool LLMediaImplExample2::startup( LLMediaManagerData* init_data ) -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-uninitialization - called once at application closedown -bool LLMediaImplExample2::closedown() -{ - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample2::init() -{ - int buffer_size = getMediaBufferSize(); - - mMediaPixels = new unsigned char[ buffer_size ]; - - memset( mMediaPixels, 0x00, buffer_size ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample2::navigateTo( const std::string url ) -{ - std::cout << "LLMediaImplExample2::navigateTo" << std::endl; - - setStatus( LLMediaBase::STATUS_NAVIGATING ); - - // force a size change event for new URL - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -std::string LLMediaImplExample2::getVersion() -{ - std::string version_string = "[" + sLLMediaImplExample2Reg.getImplName() + "] - " + "1.0.0.0"; - - return version_string; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample2::updateMedia() -{ - if ( mMediaPixels && getStatus() == LLMediaBase::STATUS_STARTED ) - { - static int x_inc = rand() % 5 + 2; - static int y_inc = rand() % 5 + 2; - int block_size = 32; - - for( int y = 0; y < block_size; ++y ) - { - for( int x = 0; x < block_size; ++x ) - { - int rowspan = getMediaWidth() * getMediaDepth(); - mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 0 ] = 0; - mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 1 ] = 0; - mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 2 ] = 0; - }; - }; - - if ( mXpos + x_inc < 0 || mXpos + x_inc >= getMediaWidth() - block_size ) - x_inc =- x_inc; - - if ( mYpos + y_inc < 0 || mYpos + y_inc >= getMediaHeight() - block_size ) - y_inc =- y_inc; - - mXpos += x_inc; - mYpos += y_inc; - - unsigned char col_r = rand() % 0xff; - unsigned char col_g = rand() % 0xff; - unsigned char col_b = rand() % 0xff; - - for( int y = 0; y < block_size; ++y ) - { - for( int x = 0; x < block_size; ++x ) - { - int rowspan = getMediaWidth() * getMediaDepth(); - mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 0 ] = col_r; - mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 1 ] = col_g; - mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 2 ] = col_b; - }; - }; - - // emit an event to say that something in the media stream changed - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); - }; - - // update the command (e.g. transport controls) state - updateCommand(); - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -unsigned char* LLMediaImplExample2::getMediaData() -{ - return mMediaPixels; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample2::reset() -{ - if ( mMediaPixels ) - { - delete [] mMediaPixels; - }; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplExample2::setRequestedMediaSize( int width, int height ) -{ - // we accept any size: - return setMediaSize(width, height); -} diff --git a/linden/indra/llmedia/llmediaimplfactory.cpp b/linden/indra/llmedia/llmediaimplfactory.cpp deleted file mode 100644 index c5d098f74..000000000 --- a/linden/indra/llmedia/llmediaimplfactory.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file llmediaimplfactory.cpp - * @brief Creates media impls that have registered themselves with LLMediaRegster - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llmediaimplfactory.h" - -#include - -LLMediaImplFactory* LLMediaImplFactory::sInstance = NULL; - -/////////////////////////////////////////////////////////////////////////////// -// static -LLMediaImplFactory* LLMediaImplFactory::getInstance() -{ - if ( ! sInstance ) - sInstance = new LLMediaImplFactory(); - - return sInstance; -} - -/////////////////////////////////////////////////////////////////////////////// -// -void LLMediaImplFactory::registerImpl( const std::string& impl_name, LLMediaImplMakerBase* impl_maker ) -{ - mNameImplMakerContainer.insert( name_impl_maker_container_t::value_type( impl_name, impl_maker ) ); -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplMakerBase* LLMediaImplFactory::getImplMaker( const std::string& scheme, const std::string& type ) -{ - name_impl_maker_container_t::const_iterator iter; - name_impl_maker_container_t::const_iterator begin = mNameImplMakerContainer.begin(); - name_impl_maker_container_t::const_iterator end = mNameImplMakerContainer.end(); - - for(iter = begin; iter != end; ++iter) - { - if(( *iter->second ).supportsScheme(scheme)) - { - return ( iter->second ); - } - } - - for(iter = begin; iter != end; ++iter) - { - if(( *iter->second ).supportsMimeType(type)) - { - return ( iter->second ); - } - } - int idx1 = type.find("/"); - int len = (idx1 == std::string::npos) ? 0 : idx1; - std::string category = type.substr(0,len); - for(iter = begin; iter != end; ++iter) - { - if(( *iter->second ).supportsMimeTypeCategory(category)) - { - return ( iter->second ); - } - } - - return NULL; -}; - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplMakerBase* LLMediaImplFactory::getImplMaker( const std::string& impl_name ) -{ - name_impl_maker_container_t::const_iterator found = mNameImplMakerContainer.find( impl_name ); - - if ( found == mNameImplMakerContainer.end() ) - { - return NULL; - }; - - return found->second; -} diff --git a/linden/indra/llmedia/llmediaimplfactory.h b/linden/indra/llmedia/llmediaimplfactory.h deleted file mode 100644 index 93a7cc10e..000000000 --- a/linden/indra/llmedia/llmediaimplfactory.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file llmediaimplfactory.h - * @brief Creates media impls that have registered themselves with LLMediaRegster - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAIMPLFACTORY_H -#define LLMEDIAIMPLFACTORY_H - -#include -#include -#include -#include - -#include "llmediabase.h" - -/////////////////////////////////////////////////////////////////////////////// -// -class LLMediaImplMakerBase -{ - public: - virtual bool supportsScheme(std::string scheme) = 0; - virtual bool supportsMimeType(std::string type) = 0; - virtual bool supportsMimeTypeCategory(std::string category) = 0; - virtual LLMediaBase* create() = 0; - virtual ~LLMediaImplMakerBase() {}; - - protected: - typedef std::vector vector_impl_registry_t; - vector_impl_registry_t mSchema; - vector_impl_registry_t mMimeTypes; - vector_impl_registry_t mMimeTypeCategories; -}; - -/////////////////////////////////////////////////////////////////////////////// -// -class LLMediaImplMaker : public LLMediaImplMakerBase -{ - public: - bool supportsScheme(std::string scheme) - { - vector_impl_registry_t::iterator found = std::find(mSchema.begin(), mSchema.end(), scheme); - return found != mSchema.end(); - } - bool supportsMimeType(std::string type) - { - vector_impl_registry_t::iterator found = std::find(mMimeTypes.begin(), mMimeTypes.end(), type); - return found != mMimeTypes.end(); - } - bool supportsMimeTypeCategory(std::string category) - { - vector_impl_registry_t::iterator found = std::find(mMimeTypeCategories.begin(), mMimeTypeCategories.end(), category); - return found != mMimeTypeCategories.end(); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// -class LLMediaImplFactory -{ - public: - static LLMediaImplFactory* getInstance(); - void registerImpl( const std::string& impl_name, LLMediaImplMakerBase* impl_maker ); - LLMediaImplMakerBase* getImplMaker( const std::string& scheme, const std::string& type ); - LLMediaImplMakerBase* getImplMaker( const std::string& impl_name); - - private: - typedef std::map< std::string, LLMediaImplMakerBase* > name_impl_maker_container_t; - name_impl_maker_container_t mNameImplMakerContainer; - - static LLMediaImplFactory* sInstance; -}; - -#endif // LLMEDIAIMPLFACTORY_H diff --git a/linden/indra/llmedia/llmediaimplgstreamer.h b/linden/indra/llmedia/llmediaimplgstreamer.h deleted file mode 100644 index 8d2e75675..000000000 --- a/linden/indra/llmedia/llmediaimplgstreamer.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @file llmediaimplgstreamer.h - * @author Tofu Linden - * @brief implementation that supports media playback via GStreamer. - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// header guard -#ifndef llmediaimplgstreamer_h -#define llmediaimplgstreamer_h - -#include "llmediaimplcommon.h" -#include "llmediaimplfactory.h" - -///#if LL_GSTREAMER_ENABLED - -extern "C" { -#include -} - -#include -#include "apr_pools.h" -#include "apr_dso.h" - - -#include "llmediaimplgstreamervidplug.h" -#include "llgstplaythread.h" - -class LLMediaManagerData; -class LLMediaImplMaker; - -/////////////////////////////////////////////////////////////////////////// -class LLMediaImplGStreamer: - public LLMediaImplCommon -{ - friend class LLGstPlayThread; - - public: - LLMediaImplGStreamer (); - virtual ~LLMediaImplGStreamer (); - - //////////////////////////////////////////////////////// - // implementation of the media public interface - - static bool startup( LLMediaManagerData* init_data ); - static bool closedown(); - - // Sets GST_PLUGIN_PATH env var for GStreamer. - static void set_gst_plugin_path(); - - /* virtual */ bool setDebugLevel( LLMediaBase::EDebugLevel level ); - - // Function given to GStreamer for handling debug messages - static void gstreamer_log(GstDebugCategory *category, - GstDebugLevel level, - const gchar *file, - const gchar *function, - gint line, - GObject *object, - GstDebugMessage *message, - gpointer data) -#if __GNUC__ - // recommended by the gstreamer docs - G_GNUC_NO_INSTRUMENT -#endif - ; - - /* virtual */ std::string getVersion(); - /* virtual */ bool navigateTo( const std::string url ); - /* virtual */ bool updateMedia(); - /* virtual */ unsigned char* getMediaData(); - /* virtual */ int getTextureFormatPrimary() const; - /* virtual */ int getTextureFormatType() const; - /* virtual */ int getTextureFormatInternal() const; - /* virtual */ bool seek( double time ); - /* virtual */ bool setVolume( float volume ); - - LLMediaEmitter< LLMediaObserver > getEventEmitter() const {return mEventEmitter;}; - - protected: - - void startPlay(); - - - private: - - // misc - bool unload(); - bool pause(); - bool stop(); - bool play(); - - static gboolean bus_callback (GstBus *bus, - GstMessage *message, - gpointer data); - - unsigned char* mediaData; - int mMediaRowbytes; - int mTextureFormatPrimary; - int mTextureFormatType; - - // GStreamer-specific - GMainLoop *mPump; // event pump for this media - GstElement *mPlaybin; - GstSLVideo *mVideoSink; - std::string mLastTitle; - GstState mState; - GstState getState() const { return mState; } - - LLGstPlayThread *mPlayThread; -}; - -class LLMediaImplGStreamerMaker : public LLMediaImplMaker -{ - public: - LLMediaImplGStreamerMaker(); - LLMediaImplGStreamer* create() - { - return new LLMediaImplGStreamer(); - } -}; - -///////////////////////////////////////////////////////////////////////// -// Debug/Info/Warning macros. -#define STDERRMSG(...) do{\ - fprintf(stderr, "%s:%d: ", __FUNCTION__, __LINE__);\ - fprintf(stderr, __VA_ARGS__);\ - fputc('\n',stderr);\ - }while(0) -#define NULLMSG(...) do{}while(0) - -#define DEBUGMSG NULLMSG -#define INFOMSG STDERRMSG -#define WARNMSG STDERRMSG -///////////////////////////////////////////////////////////////////////// - -///#endif // LL_GSTREAMER_ENABLED - -#endif // llmediaimplgstreamer_h diff --git a/linden/indra/llmedia/llmediaimplllmozlib.cpp b/linden/indra/llmedia/llmediaimplllmozlib.cpp deleted file mode 100644 index 5b4b02ebe..000000000 --- a/linden/indra/llmedia/llmediaimplllmozlib.cpp +++ /dev/null @@ -1,624 +0,0 @@ -/** - * @file llmediaimplllmozlib.cpp - * @brief Example 2 of a media impl concrete class - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llmediaimplllmozlib.h" - -#if LL_LLMOZLIB_ENABLED - -#include "llmediaimplregister.h" -#include "llmediamanager.h" - -#ifdef WIN32 - // platform specific includes needed before OpenGL header - #include - #include -#elif defined(__APPLE__) - // framework-style include path when building on the Mac. - #include -#else // Assume this is linux - // Linux, MESA headers, but not necessarily assuming MESA runtime. - // quotes so we get libraries/.../GL/ version - #include "GL/gl.h" -#endif - - -#include - - -#include - -// register this impl with media manager factory -static LLMediaImplRegister sLLMediaImplLLMozLibReg( "LLMediaImplLLMozLib", new LLMediaImplLLMozLibMaker() ); - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplLLMozLibMaker::LLMediaImplLLMozLibMaker() -{ - // Register to handle the mime category - mMimeTypes.push_back( "image/svg+xml" ); - mMimeTypeCategories.push_back( "text" ); -#if !LL_QUICKTIME_ENABLED - mMimeTypeCategories.push_back( "image" ); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplLLMozLib::LLMediaImplLLMozLib() : - mBrowserWindowWidth( 800 ), - mBrowserWindowHeight( 600 ), - mMediaDataWidth( 0 ), - mMediaDataHeight( 0 ), - mWindowId( 0 ), - mNeedsUpdate( false ) -{ - setRequestedMediaSize( mBrowserWindowWidth, mBrowserWindowHeight ); - - setMediaDepth( 4 ); -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-initialization - called once at application startup -bool LLMediaImplLLMozLib::startup( LLMediaManagerData* init_data ) -{ - - // 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 = setlocale(LC_ALL, NULL); - - - bool result = LLMozLib::getInstance()->init( init_data->getBrowserApplicationDir(), - init_data->getBrowserComponentDir(), - init_data->getBrowserProfileDir(), - init_data->getBrowserParentWindow() ); - - - setlocale(LC_ALL, saved_locale.c_str() ); - - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-uninitialization - called once at application closedown -bool LLMediaImplLLMozLib::closedown() -{ - // name discrepancy - this reset actually shuts down LLMozLib - LLMozLib::getInstance()->reset(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) -bool LLMediaImplLLMozLib::setBrowserUserAgent(std::string user_agent) -{ - // append special string to the embedded browser user agent string - LLMozLib::getInstance()->setBrowserAgentId(user_agent); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::init() -{ - // if mWindowId is non-0, it's we already called init() and shouldn't call it again - // (::reset() will zero this value) - if ( mWindowId ) - return false; - -#if defined(LL_LINUX) || defined(WIN32) - static std::string saved_locale; - saved_locale = setlocale(LC_ALL, NULL); -#endif // defined(LL_LINUX) || defined(WIN32) - - mWindowId = LLMozLib::getInstance()->createBrowserWindow( mBrowserWindowWidth, mBrowserWindowHeight ); - - LLMozLib::getInstance()->setSize( mWindowId, mBrowserWindowWidth, mBrowserWindowHeight ); - - LLMozLib::getInstance()->setBackgroundColor( mWindowId, 0x00, 0x00, 0x00 ); - - LLMozLib::getInstance()->addObserver( mWindowId, this ); - - // plugins only work with some client-side hackery and they cause - // exception handling issues (DEV-10020) so we turn them off - LLMozLib::getInstance()->enablePlugins( false ); - - // second life client needs the bitmap flipped - LLMozLib::getInstance()->flipWindow( mWindowId, true ); - - // set media depth now we have created a browser window and know what it is - setMediaDepth( LLMozLib::getInstance()->getBrowserDepth( mWindowId ) ); - -#if defined(LL_LINUX) || defined(WIN32) - setlocale(LC_ALL, saved_locale.c_str() ); -#endif // defined(LL_LINUX) || defined(WIN32) - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -std::string LLMediaImplLLMozLib::getVersion() -{ - std::string version_string = "[" + sLLMediaImplLLMozLibReg.getImplName() + "] - " + LLMozLib::getInstance()->getVersion(); - - return version_string; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::set404RedirectUrl( std::string redirect_url ) -{ - return LLMozLib::getInstance()->set404RedirectUrl( mWindowId, redirect_url ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual - -bool LLMediaImplLLMozLib::clr404RedirectUrl() -{ - return LLMozLib::getInstance()->clr404RedirectUrl( mWindowId ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const -{ - return LLMozLib::getInstance()->setBackgroundColor( mWindowId, red, green, blue ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const -{ - return LLMozLib::getInstance()->setCaretColor( mWindowId, red, green, blue ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::navigateTo( const std::string url ) -{ - // pass url to llmozlib - LLMozLib::getInstance()->navigateTo( mWindowId, url ); - - // emit event with size change to kick things off - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); - - // not that useful right now but maybe later - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::updateMedia() -{ - if ( getStatus() == LLMediaBase::STATUS_STARTED ) - { - // if flag set, the page changed and we need to update - if ( mNeedsUpdate ) - { - // snap browser pixels - LLMozLib::getInstance()->grabBrowserWindow( mWindowId ); - - // update media width - rendering the page can change it - mMediaDataWidth = LLMozLib::getInstance()->getBrowserRowSpan( mWindowId ) / getMediaDepth(); - mMediaDataHeight = LLMozLib::getInstance()->getBrowserHeight( mWindowId ); - - // emit an event to say that something in the media stream changed - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); - - // flag that we've done the update and one isn't needed next frame - mNeedsUpdate = false; - }; - }; - - // update the state (e.g. transport controls) state - updateState(); - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplLLMozLib::updateState() -{ - if ( nextCommand() == LLMediaBase::COMMAND_START ) - { - setStatus( LLMediaBase::STATUS_STARTED ); - clearCommand(); - }; - - if ( nextCommand() == LLMediaBase::COMMAND_STOP ) - { - setStatus( LLMediaBase::STATUS_STOPPED ); - clearCommand(); - }; - - if ( nextCommand() == LLMediaBase::COMMAND_BACK ) - { - setStatus( LLMediaBase::STATUS_STARTED ); - LLMozLib::getInstance()->navigateBack( mWindowId ); - clearCommand(); - }; - - if ( nextCommand() == LLMediaBase::COMMAND_FORWARD ) - { - setStatus( LLMediaBase::STATUS_STARTED ); - LLMozLib::getInstance()->navigateForward( mWindowId ); - clearCommand(); - }; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onPageChanged( const EventType& eventIn ) -{ - // force an update when the contents of the page changes - mNeedsUpdate = true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onClickLinkHref( const EventType& eventIn ) -{ - LLMediaEvent event( this, eventIn.getStringValue(), eventIn.getStringValue2() ); - mEventEmitter.update( &LLMediaObserver::onClickLinkHref, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onClickLinkNoFollow( const EventType& eventIn ) -{ - LLMediaEvent event( this, eventIn.getStringValue() ); - mEventEmitter.update( &LLMediaObserver::onClickLinkNoFollow, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onUpdateProgress( const EventType& eventIn ) -{ - LLMediaEvent event( this, eventIn.getIntValue() ); - mEventEmitter.update( &LLMediaObserver::onUpdateProgress, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onStatusTextChange( const EventType& eventIn ) -{ - LLMediaEvent event( this, eventIn.getStringValue() ); - mEventEmitter.update( &LLMediaObserver::onStatusTextChange, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onLocationChange( const EventType& eventIn ) -{ - LLMediaEvent event( this, eventIn.getEventUri() ); - mEventEmitter.update( &LLMediaObserver::onLocationChange, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onNavigateBegin( const EventType& eventIn ) -{ - LLMediaEvent event( this, eventIn.getEventUri() ); - mEventEmitter.update( &LLMediaObserver::onNavigateBegin, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLMediaImplLLMozLib::onNavigateComplete( const EventType& eventIn ) -{ - // force an update when the page is finished - mNeedsUpdate = true; - - // pass in url and HTML response code (200/404 etc.) - LLMediaEvent event( this, eventIn.getEventUri(), eventIn.getIntValue() ); - mEventEmitter.update( &LLMediaObserver::onNavigateComplete, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -unsigned char* LLMediaImplLLMozLib::getMediaData() -{ - return (unsigned char*)LLMozLib::getInstance()->getBrowserWindowPixels( mWindowId ); -} - -// helper func to compute size of media data -bool LLMediaImplLLMozLib::recomputeSizes() -{ - int new_width = mMediaRequestedWidth; - int new_height = mMediaRequestedHeight; - - if (new_width < 0) - new_width = 512; - - if (new_height < 0) - new_height = 512; - - if (mAutoScaled) - { - new_width = LLMediaManager::textureWidthFromMediaWidth( new_width ); - new_height = LLMediaManager::textureHeightFromMediaHeight( new_height ); - } - - bool status = LLMozLib::getInstance()->setSize( mWindowId, new_width, new_height ); - - if (status) - setMediaSize(new_width, new_height); - - return status; -} - - -//////////////////////////////////////////////////////////////////////////////// -// virtual -int LLMediaImplLLMozLib::getMediaDataWidth() const -{ - return mMediaDataWidth; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -int LLMediaImplLLMozLib::getMediaDataHeight() const -{ - return mMediaDataHeight; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::setRequestedMediaSize(int width, int height) -{ - LLMediaImplCommon::setRequestedMediaSize(width, height); - - return recomputeSizes(); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::setAutoScaled( bool auto_scaled ) -{ - LLMediaImplCommon::setAutoScaled(auto_scaled); - - return recomputeSizes(); -} - - -//////////////////////////////////////////////////////////////////////////////// -// virtual -int LLMediaImplLLMozLib::getTextureFormatPrimary() const -{ -#if defined(__APPLE__) || defined(MACOSX) - return GL_BGRA_EXT; -#else - return LLMozLib::getInstance()->getBrowserDepth( mWindowId ) == 3 ? GL_BGR_EXT : GL_BGRA_EXT; -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -int LLMediaImplLLMozLib::getTextureFormatType() const -{ -#if defined(__APPLE__) || defined(MACOSX) - #ifdef __BIG_ENDIAN__ - return GL_UNSIGNED_INT_8_8_8_8_REV; - #else - return GL_UNSIGNED_INT_8_8_8_8; - #endif -#else - return GL_UNSIGNED_BYTE; -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::mouseDown( int x_pos, int y_pos ) -{ - return LLMozLib::getInstance()->mouseDown( mWindowId, x_pos, y_pos ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::mouseUp( int x_pos, int y_pos ) -{ - LLMozLib::getInstance()->mouseUp( mWindowId, x_pos, y_pos ); - - // this seems better than sending focus on mouse down (still need to improve this) - LLMozLib::getInstance()->focusBrowser( mWindowId, true ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::mouseMove( int x_pos, int y_pos ) -{ - return LLMozLib::getInstance()->mouseMove( mWindowId, x_pos, y_pos ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::keyPress( int key_code ) -{ - // We don't have to deal with printable characters here - they should - // go through handleUnicodeChar(). This table could be more complete - // than it is, but I think this covers all of the important - // non-printables. - - unsigned long moz_key; - - switch(key_code) - { - case LL_MEDIA_KEY_BACKSPACE: - moz_key = LL_DOM_VK_BACK_SPACE; break; - case LL_MEDIA_KEY_TAB: - moz_key = LL_DOM_VK_TAB; break; - case LL_MEDIA_KEY_RETURN: - moz_key = LL_DOM_VK_RETURN; break; - case LL_MEDIA_KEY_PAD_RETURN: - moz_key = LL_DOM_VK_ENTER; break; - case LL_MEDIA_KEY_ESCAPE: - moz_key = LL_DOM_VK_ESCAPE; break; - case LL_MEDIA_KEY_PAGE_UP: - moz_key = LL_DOM_VK_PAGE_UP; break; - case LL_MEDIA_KEY_PAGE_DOWN: - moz_key = LL_DOM_VK_PAGE_DOWN; break; - case LL_MEDIA_KEY_END: - moz_key = LL_DOM_VK_END; break; - case LL_MEDIA_KEY_HOME: - moz_key = LL_DOM_VK_HOME; break; - case LL_MEDIA_KEY_LEFT: - moz_key = LL_DOM_VK_LEFT; break; - case LL_MEDIA_KEY_UP: - moz_key = LL_DOM_VK_UP; break; - case LL_MEDIA_KEY_RIGHT: - moz_key = LL_DOM_VK_RIGHT; break; - case LL_MEDIA_KEY_DOWN: - moz_key = LL_DOM_VK_DOWN; break; - case LL_MEDIA_KEY_INSERT: - moz_key = LL_DOM_VK_INSERT; break; - case LL_MEDIA_KEY_DELETE: - moz_key = LL_DOM_VK_DELETE; break; - - default: - return false; // don't know how to map this key. - } - - return LLMozLib::getInstance()->keyPress( mWindowId, moz_key ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::scrollByLines( int lines ) -{ - return LLMozLib::getInstance()->scrollByLines(mWindowId, lines); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::focus( bool focus ) -{ - return LLMozLib::getInstance()->focusBrowser(mWindowId, focus); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::unicodeInput( unsigned long uni_char ) -{ - return LLMozLib::getInstance()->unicodeInput(mWindowId, uni_char); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::mouseLeftDoubleClick( int x_pos, int y_pos ) -{ - return LLMozLib::getInstance()->mouseLeftDoubleClick( mWindowId, x_pos, y_pos ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::navigateForward() -{ - return LLMozLib::getInstance()->navigateForward(mWindowId); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::navigateBack() -{ - return LLMozLib::getInstance()->navigateBack(mWindowId); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::canNavigateForward() -{ - return LLMozLib::getInstance()->canNavigateForward(mWindowId); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::canNavigateBack() -{ - return LLMozLib::getInstance()->canNavigateBack(mWindowId); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::enableCookies(bool enable) -{ - return LLMozLib::getInstance()->enableCookies(enable); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::enableProxy(bool enable, std::string proxy_host_name, int proxy_port) -{ - return LLMozLib::getInstance()->enableProxy(enable, proxy_host_name, proxy_port); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::clearCache() -{ - return LLMozLib::getInstance()->clearCache(); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::clearCookies() -{ - return LLMozLib::getInstance()->clearAllCookies(); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplLLMozLib::reset() -{ - LLMozLib::getInstance()->remObserver( mWindowId, this ); - - LLMozLib::getInstance()->destroyBrowserWindow( mWindowId ); - - mWindowId = 0; - - return true; -} - -#endif // LL_LLMOZLIB_ENABLED diff --git a/linden/indra/llmedia/llmediaimplllmozlib.h b/linden/indra/llmedia/llmediaimplllmozlib.h deleted file mode 100644 index f71300e4c..000000000 --- a/linden/indra/llmedia/llmediaimplllmozlib.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file llmediaimplllmozlib.cpp - * @brief Example 2 of a media impl concrete class - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAIMPLLLMOZLIB_H -#define LLMEDIAIMPLLLMOZLIB_H - -#include "llmediaimplcommon.h" -#include "llmediaimplfactory.h" - -#if LL_LLMOZLIB_ENABLED - -#include "llmozlib2.h" - -class LLMediaManagerData; - -class LLMediaImplLLMozLib : - public LLMediaImplCommon, - public LLEmbeddedBrowserWindowObserver -{ - public: - LLMediaImplLLMozLib(); - - static bool startup( LLMediaManagerData* init_data ); - static bool closedown(); - - // Update the user-agent string reported when the browser requests - // web page, because we need to include the Second Life version - // and skin name (which can change without restarts). - // Must be called after startup(). - static bool setBrowserUserAgent(std::string user_agent); - - /* virtual */ bool init(); - /* virtual */ std::string getVersion(); - /* virtual */ bool set404RedirectUrl( std::string redirect_url ); - /* virtual */ bool clr404RedirectUrl(); - /* virtual */ bool setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const; - /* virtual */ bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const; - /* virtual */ bool navigateTo( const std::string url ); - /* virtual */ bool updateMedia(); - /* virtual */ unsigned char* getMediaData(); - /* virtual */ int getMediaDataWidth() const; - /* virtual */ int getMediaDataHeight() const; - /* virtual */ bool setRequestedMediaSize(int width, int height); - /* virtual */ bool setAutoScaled( bool auto_scaled ); - /* virtual */ int getTextureFormatPrimary() const; - /* virtual */ int getTextureFormatType() const; - /* virtual */ bool mouseDown( int x_pos, int y_pos ); - /* virtual */ bool mouseUp( int x_pos, int y_pos ); - /* virtual */ bool mouseMove( int x_pos, int y_pos ); - /* virtual */ bool keyPress( int key_code ); - /* virtual */ bool scrollByLines( int lines ); - /* virtual */ bool focus( bool focus ); - /* virtual */ bool unicodeInput( unsigned long uni_char ); - /* virtual */ bool mouseLeftDoubleClick( int x_pos, int y_pos ); - /* virtual */ bool navigateForward(); - /* virtual */ bool navigateBack(); - /* virtual */ bool canNavigateForward(); - /* virtual */ bool canNavigateBack(); - /* virtual */ bool enableCookies(bool enable); - /* virtual */ bool enableProxy(bool enable, std::string proxy_host_name, int proxy_port); - /* virtual */ bool clearCache(); - /* virtual */ bool clearCookies(); - /* virtual */ bool reset(); - - // LLMozLib observerables - virtual void onNavigateBegin( const EventType& eventIn ); - virtual void onNavigateComplete( const EventType& eventIn ); - virtual void onUpdateProgress( const EventType& eventIn ); - virtual void onPageChanged( const EventType& eventIn ); - virtual void onStatusTextChange( const EventType& eventIn ); - virtual void onLocationChange( const EventType& eventIn ); - virtual void onClickLinkHref( const EventType& eventIn ); - virtual void onClickLinkNoFollow( const EventType& eventIn ); - - private: - bool recomputeSizes(); - int mWindowId; - int mBrowserWindowWidth; - int mBrowserWindowHeight; - int mMediaDataWidth; - int mMediaDataHeight; - bool mNeedsUpdate; - bool updateState(); -}; - -// The maker class -class LLMediaImplLLMozLibMaker : public LLMediaImplMaker -{ - public: - LLMediaImplLLMozLibMaker(); - LLMediaImplLLMozLib* create() - { - return new LLMediaImplLLMozLib(); - } -}; -#endif // LL_LLMOZLIB_ENABLED - -#endif // LLMEDIAIMPLLLMOZLIB_H diff --git a/linden/indra/llmedia/llmediaimplquicktime.cpp b/linden/indra/llmedia/llmediaimplquicktime.cpp deleted file mode 100644 index 76cacee97..000000000 --- a/linden/indra/llmedia/llmediaimplquicktime.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/** - * @file llmediaimplquicktime.cpp - * @brief QuickTime media impl concrete class - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llmediaimplquicktime.h" - -#if LL_QUICKTIME_ENABLED - -#include "llmediamanager.h" -#include "llmediaimplregister.h" - -#if LL_WINDOWS -#include -#endif - -#include -#include - -// register this impl with media manager factory -static LLMediaImplRegister sLLMediaImplQuickTimeReg( "LLMediaImplQuickTime", new LLMediaImplQuickTimeMaker() ); - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplQuickTimeMaker::LLMediaImplQuickTimeMaker() -{ - // Register to handle the scheme - mSchema.push_back( "rtsp" ); - - // Register to handle the category - mMimeTypeCategories.push_back( "video" ); - mMimeTypeCategories.push_back( "audio" ); - mMimeTypeCategories.push_back( "image" ); -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplQuickTime::LLMediaImplQuickTime() : - mMovieHandle( 0 ), - mGWorldHandle( 0 ), - mMovieController( 0 ), - mMinWidth( 32 ), - mMaxWidth( 2048 ), - mMinHeight( 32 ), - mMaxHeight( 2048 ), - mCurVolume( 0 ) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplQuickTime::~LLMediaImplQuickTime() -{ - unload(); -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-initialization - called once at application startup -bool LLMediaImplQuickTime::startup( LLMediaManagerData* init_data ) -{ -#ifdef WIN32 - if ( InitializeQTML( 0L ) != noErr ) - { - return false; - }; -#endif - - EnterMovies(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) super-uninitialization - called once at application closedown -bool LLMediaImplQuickTime::closedown() -{ - ExitMovies(); - -#ifdef WIN32 - TerminateQTML(); -#endif - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// private -bool LLMediaImplQuickTime::load( const std::string url ) -{ - if ( url.empty() ) - return false; - - //In case std::string::c_str() makes a copy of the url data, - //make sure there is memory to hold it before allocating memory for handle. - //if fails, NewHandleClear(...) should return NULL. - const char* url_string = url.c_str() ; - Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); - if ( NULL == handle ) - return false; - if(noErr != MemError() || NULL == *handle) - { - return false ; - } - - BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) ); - - //std::cout << "LLMediaImplQuickTime::load( " << url << " )" << std::endl; - - // TODO: supposed to use NewMovieFromDataParams now - OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType ); - DisposeHandle( handle ); - if ( noErr != err ) - return false; - - // do pre-roll actions (typically fired for streaming movies but not always) - PrePrerollMovie( mMovieHandle, 0, GetMoviePreferredRate( mMovieHandle ), moviePrePrerollCompleteCallback, ( void * )this ); - - // get movie rect (and check for min/max) - Rect movie_rect; - setMovieBoxEnhanced( &movie_rect ); - - // make a new movie controller - mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie ); - -#if defined(__APPLE__) || defined(MACOSX) - setMediaDepth( 4 ); -#else - setMediaDepth( 3 ); -#endif - - // tell manager about the media size - setMediaSize( movie_rect.right - movie_rect.left, movie_rect.bottom - movie_rect.top); - - // movie controller - MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this ); - - SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize ); - - // function that gets called when a frame is drawn - SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); - - // emit an event to say that a media source was loaded - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaLoaded, event ); - - // set up inital state - sizeChanged(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -std::string LLMediaImplQuickTime::getVersion() -{ - long version; - Gestalt( gestaltQuickTimeVersion, &version ); - - std::ostringstream codec( "" ); - codec << "["; - codec << sLLMediaImplQuickTimeReg.getImplName(); - codec << "] - "; - codec << "QuickTime: " << std::hex << version; - - return codec.str(); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplQuickTime::navigateTo( const std::string url ) -{ - // tell engine what we're doing - setStatus( LLMediaBase::STATUS_NAVIGATING ); - - // remove the movie we were looking at - unload(); - - // load the new one (no real 'go to this url' function in QT) - load( url ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplQuickTime::sizeChanged() -{ - if ( ! mMovieHandle ) - return false; - - // sanitize size of movie - Rect movie_rect; - setMovieBoxEnhanced( &movie_rect ); - - // we need this later - int width = ( movie_rect.right - movie_rect.left ); - int height = ( movie_rect.bottom - movie_rect.top ); - - std::cout << "LLMEDIA> size changed to " << width << " x " << height << std::endl; - - setMediaSize( width, height ); - - // media depth won't change - int depth_bits = getMediaDepth() * 8; - - GWorldPtr old_gworld_handle = mGWorldHandle; - - if (old_gworld_handle) - { - GWorldFlags result = UpdateGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, 0 ); - if ( gwFlagErr == result ) - { - // TODO: unrecoverable?? throw exception? return something? - return false; - } - } - else - { - OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, keepLocal | pixelsLocked ); - if ( noErr != result ) - { - // ATODO: unrecoverable?? throw exception? return something? - return false; - } - - // clear memory in GWorld to avoid random screen visual fuzz from uninitialized texture data - if ( mGWorldHandle ) - { - PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); - unsigned char* ptr = ( unsigned char* )GetPixBaseAddr( pix_map_handle ); - memset( ptr, 0x00, height * QTGetPixMapHandleRowBytes( pix_map_handle ) ); - } - } - - // point movie at GWorld if it's new - if ( mMovieHandle && ! old_gworld_handle ) - { - SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice ( mGWorldHandle ) ); - } - - // update movie controller - if ( mMovieController ) - { - MCSetControllerPort( mMovieController, mGWorldHandle ); - MCPositionController( mMovieController, &movie_rect, &movie_rect, - mcTopLeftMovie | mcPositionDontInvalidate ); - MCMovieChanged( mMovieController, mMovieHandle ); - } - - // Emit event with size change so the calling app knows about it too - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// static -Boolean LLMediaImplQuickTime::mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) -{ - Boolean result = false; - - LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; - - switch( action ) - { - // handle window resizing - case mcActionControllerSizeChanged: - self->sizeChanged(); - break; - - // Block any movie controller actions that open URLs. - case mcActionLinkToURL: - case mcActionGetNextURL: - case mcActionLinkToURLExtended: - // Prevent the movie controller from handling the message - result = true; - break; - - default: - break; - }; - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// private -bool LLMediaImplQuickTime::unload() -{ - if ( mMovieHandle ) - { - StopMovie( mMovieHandle ); - if ( mMovieController ) - { - MCMovieChanged( mMovieController, mMovieHandle ); - }; - }; - - if ( mMovieController ) - { - MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this ); - DisposeMovieController( mMovieController ); - mMovieController = NULL; - }; - - if ( mMovieHandle ) - { - SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this ); - DisposeMovie ( mMovieHandle ); - mMovieHandle = NULL; - }; - - if ( mGWorldHandle ) - { - DisposeGWorld( mGWorldHandle ); - mGWorldHandle = NULL; - }; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// static -OSErr LLMediaImplQuickTime::movieDrawingCompleteCallback( Movie call_back_movie, long ref ) -{ - LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; - - // IMPORTANT: typically, a consumer who is observing this event will set a flag - // when this event is fired then render later. Be aware that the media stream - // can change during this period - dimensions, depth, format etc. - LLMediaEvent event( self ); - self->mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); - - return noErr; -} - -//////////////////////////////////////////////////////////////////////////////// -// static -void LLMediaImplQuickTime::moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) -{ - LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; - - LLMediaEvent event( self ); - self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); -} - -/////////////////////////////////////////////////////////////////////////////// -// used for stop / loop -void LLMediaImplQuickTime::rewind() -{ - GoToBeginningOfMovie ( mMovieHandle ); - - MCMovieChanged( mMovieController, mMovieHandle ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplQuickTime::processState() -{ - // start stream - if ( nextCommand() == LLMediaBase::COMMAND_START ) - { - // valid when we are in these states - if ( getStatus() == LLMediaBase::STATUS_NAVIGATING|| getStatus() == LLMediaBase::STATUS_STOPPED || getStatus() == LLMediaBase::STATUS_PAUSED ) - { - // it appears that the movie must be in a loaded state before we do this command - if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) - { - MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate( mMovieHandle ) ); - - MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); - - setStatus( LLMediaBase::STATUS_STARTED ); - - clearCommand(); - } - } - } - else - if ( nextCommand() == LLMediaBase::COMMAND_STOP ) - { - // valid when we are in these states - if ( getStatus() == LLMediaBase::STATUS_NAVIGATING || getStatus() == LLMediaBase::STATUS_STARTED || getStatus() == LLMediaBase::STATUS_PAUSED ) - { - // it appears that the movie must be in a loaded state before we do this command - if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) - { - // stop playing - Fixed rate = X2Fix( 0.0 ); - MCDoAction( mMovieController, mcActionPlay, (void*)rate ); - - // go back to start - rewind(); - - setStatus( LLMediaBase::STATUS_STOPPED ); - clearCommand(); - }; - }; - } - else - if ( nextCommand() == LLMediaBase::COMMAND_PAUSE ) - { - // valid when we are in these states - if ( getStatus() == LLMediaBase::STATUS_NAVIGATING || getStatus() == LLMediaBase::STATUS_STARTED || getStatus() == LLMediaBase::STATUS_STOPPED ) - { - // it appears that the movie must be in a loaded state before we do this command - if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) - { - // stop playing - Fixed rate = X2Fix( 0.0 ); - MCDoAction( mMovieController, mcActionPlay, (void*)rate ); - - setStatus( LLMediaBase::STATUS_PAUSED ); - clearCommand(); - }; - }; - }; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplQuickTime::setMovieBoxEnhanced( Rect* rect ) -{ - // get movie rect - GetMovieNaturalBoundsRect( mMovieHandle, rect ); - - int natural_width = ( rect->right - rect->left ); - int natural_height = ( rect->bottom - rect->top ); - - int width = natural_width; - int height = natural_height; - - // if the user has requested a specific size, use it: - if ((mMediaRequestedWidth != 0) && (mMediaRequestedHeight != 0)) - { - width = mMediaRequestedWidth; - height = mMediaRequestedHeight; - } - - // if the user has requested, resize media to exactly fit texture - if (mAutoScaled) - { - width = LLMediaManager::textureWidthFromMediaWidth( width ); - height = LLMediaManager::textureHeightFromMediaHeight( height ); - } - - // make sure it falls in valid range - if ( width < mMinWidth ) - width = mMinWidth; - - if ( width > mMaxWidth ) - width = mMaxWidth; - - if ( height < mMinHeight ) - height = mMinHeight; - - if ( height > mMaxHeight ) - height = mMaxHeight; - - - // scale movie to fit rect and invert vertically to match opengl image format - MatrixRecord transform; - SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix - double scaleX = (double) width / natural_width; - double scaleY = -1.0 * (double) height / natural_height; - double centerX = width / 2.0; - double centerY = height / 2.0; - ScaleMatrix( &transform, X2Fix ( scaleX ), X2Fix ( scaleY ), X2Fix ( centerX ), X2Fix ( centerY ) ); - SetMovieMatrix( mMovieHandle, &transform ); - - // return the new rect - rect->right = width; - rect->bottom = height; - rect->left = 0; - rect->top = 0; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplQuickTime::updateMedia() -{ - if ( ! mMovieHandle ) - return false; - - if ( ! mMovieController ) - return false; - - if ( ! mGWorldHandle ) - return false; - - // service QuickTime - MoviesTask( mMovieHandle, 0 ); - MCIdle( mMovieController ); - - // update state machine (deals with transport controls for example) - processState(); - - // special code for looping - need to rewind at the end of the movie - - if ( isLooping() ) - { - // QT call to see if we are at the end - can't do with controller - if ( IsMovieDone( mMovieHandle ) ) - { - // go back to start - rewind(); - - // kick off new play - MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate( mMovieHandle ) ); - - // set the volume - MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -unsigned char* LLMediaImplQuickTime::getMediaData() -{ - unsigned char* ptr = NULL; - - if ( mGWorldHandle ) - { - PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); - - ptr = ( unsigned char* )GetPixBaseAddr( pix_map_handle ); - }; - - return ptr; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -int LLMediaImplQuickTime::getMediaDataWidth() const -{ - if ( mGWorldHandle ) - { - int depth = getMediaDepth(); - - if (depth < 1) - depth = 1; - - // ALWAYS use the row bytes from the PixMap if we have a GWorld because - // sometimes it's not the same as mMediaDepth * mMediaWidth ! - PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); - return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth; - } - else - { - return LLMediaImplCommon::getMediaDataWidth(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -int LLMediaImplQuickTime::getTextureFormatPrimary() const -{ -#if defined(__APPLE__) || defined(MACOSX) - return LL_MEDIA_BGRA; -#else - return LL_MEDIA_RGB; -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -int LLMediaImplQuickTime::getTextureFormatType() const -{ -#if defined(__APPLE__) || defined(MACOSX) - #ifdef __BIG_ENDIAN__ - return LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; - #else - return LL_MEDIA_UNSIGNED_INT_8_8_8_8; - #endif -#else - return LL_MEDIA_UNSIGNED_BYTE; -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplQuickTime::seek( double time ) -{ - if ( mMovieController ) - { - TimeRecord when; - when.scale = GetMovieTimeScale( mMovieHandle ); - when.base = 0; - - // 'time' is in (floating point) seconds. The timebase time will be in 'units', where - // there are 'scale' units per second. - SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) ); - - when.value.hi = ( SInt32 )( raw_time >> 32 ); - when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) ); - - MCDoAction( mMovieController, mcActionGoToTime, &when ); - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplQuickTime::setVolume( float volume ) -{ - mCurVolume = (short)(volume * ( double ) 0x100 ); - - if ( mMovieController ) - { - MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); - - return true; - } - - return false; -} - -#endif // _3DNOW_InstructionExtensions/ LL_QUICKTIME_ENABLED - diff --git a/linden/indra/llmedia/llmediaimplquicktime.h b/linden/indra/llmedia/llmediaimplquicktime.h deleted file mode 100644 index d4e1db8af..000000000 --- a/linden/indra/llmedia/llmediaimplquicktime.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file llmediaimplquicktime.h - * @brief QuickTime media impl concrete class - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAIMPLQUICKTIME_H -#define LLMEDIAIMPLQUICKTIME_H - -#include "llmediaimplcommon.h" -#include "llmediaimplfactory.h" - -#if LL_QUICKTIME_ENABLED - -#include - -// QuickTime includes -#if defined(__APPLE__) - #include -#elif defined(WIN32) - #include "MacTypes.h" - #include "QTML.h" - #include "Movies.h" - #include "QDoffscreen.h" - #include "FixMath.h" -#endif - -class LLMediaManagerData; - -class LLMediaImplQuickTime : - public LLMediaImplCommon -{ - public: - LLMediaImplQuickTime(); - virtual ~LLMediaImplQuickTime(); - - static bool startup( LLMediaManagerData* init_data ); - static bool closedown(); - - /* virtual */ std::string getVersion(); - /* virtual */ bool navigateTo( const std::string url ); - /* virtual */ bool updateMedia(); - /* virtual */ unsigned char* getMediaData(); - /* virtual */ int getMediaDataWidth() const; - /* virtual */ int getTextureFormatPrimary() const; - /* virtual */ int getTextureFormatType() const; - /* virtual */ bool seek( double time ); - /* virtual */ bool setVolume( float volume ); - - bool sizeChanged(); - - private: - static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref ); - static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ); - static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *refcon ); - - bool load( const std::string url ); - bool unload(); - void rewind(); - bool processState(); - bool setMovieBoxEnhanced( Rect* rect ); - - Movie mMovieHandle; - GWorldPtr mGWorldHandle; - ComponentInstance mMovieController; - const int mMinWidth; - const int mMaxWidth; - const int mMinHeight; - const int mMaxHeight; - int mCurVolume; -}; - -// The maker class -class LLMediaImplQuickTimeMaker : public LLMediaImplMaker -{ - public: - LLMediaImplQuickTimeMaker(); - LLMediaImplQuickTime* create() - { - return new LLMediaImplQuickTime(); - } -}; - -#endif // LL_QUICKTIME_ENABLED - -#endif // LLMEDIAIMPLQUICKTIME_H diff --git a/linden/indra/llmedia/llmediamanager.cpp b/linden/indra/llmedia/llmediamanager.cpp deleted file mode 100644 index 48da8082d..000000000 --- a/linden/indra/llmedia/llmediamanager.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/** - * @file llmediamanager.cpp - * @brief Manages instances of media impls - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llmediamanager.h" - -#if LL_WINDOWS - // GStreamer 0.10.22 - gstutils.h - conversion from 'guint64' to 'guint8'. - // This was an intentional change to make GStreamer more threadsafe, and - // is okay. Delete this bit if GStreamer ever gets more VS-friendly -- McCabe - #pragma warning(disable : 4244) -#endif -#include "llmediaimplgstreamer.h" -#if LL_WINDOWS - #pragma warning(default : 4244) -#endif - -#include "llmediaimplfactory.h" - -#include "llmediaimplexample1.h" -#include "llmediaimplexample2.h" -#include "llmediaimplquicktime.h" - -#if LL_LLMOZLIB_ENABLED -# include "llmediaimplllmozlib.h" -#endif - -#include "llerror.h" -LLMediaManager* LLMediaManager::sInstance = 0; - - -//////////////////////////////////////////////////////////////////////////////// -// (private) -LLMediaManager::LLMediaManager() -{ -} - -//////////////////////////////////////////////////////////////////////////////// -LLMediaManager::~LLMediaManager() -{ -} - -//////////////////////////////////////////////////////////////////////////////// -// Early initialization for web browser for the viewer, so we can show -// the login screen and defer initialization of QuickTime, etc. JC -// (static) -void LLMediaManager::initBrowser( LLMediaManagerData* init_data ) -{ - if ( ! sInstance ) - sInstance = new LLMediaManager(); - -#if LL_LLMOZLIB_ENABLED - LLMediaImplLLMozLib::startup( init_data ); -#endif // LL_LLMOZLIB_ENABLED -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) -void LLMediaManager::initClass( LLMediaManagerData* init_data ) -{ - if ( ! sInstance ) - sInstance = new LLMediaManager(); - - LL_DEBUGS("MediaManager") << "LLMediaManager::initClass" << LL_ENDL; - // Initialize impl classes here - this breaks the encapsulation model - // but some of the initialization takes a long time and we only want to - // do it once at app startup before any of the impls have been created - // Each impl provides a static startup method that does any initialization - // which takes a significant amount of time. - LLMediaImplExample1::startup( init_data ); - LLMediaImplExample2::startup( init_data ); - -#if LL_QUICKTIME_ENABLED - LL_DEBUGS("MediaManager") << "LLMediaManager::initClass: starting quicktime." << LL_ENDL; - LLMediaImplQuickTime::startup( init_data ); -#endif // LL_QUICKTIME_ENABLED - -///#if LL_GSTREAMER_ENABLED - LL_DEBUGS("MediaManager") << "LLMediaManager::initClass: starting gstreamer" << LL_ENDL; - LLMediaImplGStreamer::startup( init_data ); -///#endif // LL_GSTREAMER_ENABLED -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) -void LLMediaManager::updateClass() -{ - if (!sInstance) return; - - media_impl_container_t::iterator it - = sInstance->mMediaImplContainer.begin(); - media_impl_container_t::iterator end - = sInstance->mMediaImplContainer.end(); - for ( ; it != end; ++it ) - { - LLMediaBase* impl = *it; - impl->updateMedia(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) -void LLMediaManager::cleanupClass() -{ - // Uninitialize impl classes here - this breaks the encapsulation model - // but some of the uninitialization takes a long time and we only want to - // do it once at app startup before any of the impls have been created. - // Each impl provides a static closedown method that does any uninitialization - // which takes a significant amount of time. - LLMediaImplExample1::closedown(); - LLMediaImplExample2::closedown(); - -#if LL_LLMOZLIB_ENABLED - LLMediaImplLLMozLib::closedown(); -#endif // LL_LLMOZLIB_ENABLED - -#if LL_QUICKTIME_ENABLED - LLMediaImplQuickTime::closedown(); -#endif // LL_QUICKTIME_ENABLED - -///#if LL_GSTREAMER_ENABLED - LLMediaImplGStreamer::closedown(); -///#endif // LL_QUICKTIME_ENABLED - - if ( sInstance ) - delete sInstance; - - sInstance = 0; -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) -LLMediaManager* LLMediaManager::getInstance() -{ - return sInstance; -} - -//////////////////////////////////////////////////////////////////////////////// -// (static) -void LLMediaManager::setBrowserUserAgent(std::string user_agent) -{ -#if LL_LLMOZLIB_ENABLED - // *HACK: Breaks encapsulation model, as initClass does above. JC - LLMediaImplLLMozLib::setBrowserUserAgent(user_agent); -#endif // LL_LLMOZLIB_ENABLED -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLMediaBase* LLMediaManager::createSourceFromMimeType( std::string scheme, std::string mime_type ) -{ - - LLMediaImplMakerBase* impl_maker = LLMediaImplFactory::getInstance()->getImplMaker( scheme, mime_type ); - - // If an impl maker is return it means this media type is supported - if ( impl_maker ) - { - LLMediaBase* media_impl = impl_maker->create(); - if( media_impl ) - { - media_impl->setImplMaker( impl_maker ); - std::pair< media_impl_container_t::iterator, bool > result = - mMediaImplContainer.insert( media_impl ); - - if ( result.second ) - { - media_impl->setMimeType( mime_type ); - - media_impl->init(); - - return media_impl; - }; - }; - }; - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaManager::destroySource( LLMediaBase* media_impl ) -{ - media_impl_container_t::iterator iter = - mMediaImplContainer.find( media_impl ); - - if ( iter != mMediaImplContainer.end() ) - { - if ( *iter ) - { - ( *iter)->reset(); - - delete ( *iter ); - - mMediaImplContainer.erase( iter ); - - return true; - }; - }; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaManager::addMimeTypeImplNameMap( std::string mime_type, std::string impl_name ) -{ - std::pair< mime_type_impl_name_container_t::iterator, bool > result = - mMimeTypeImplNameContainer.insert( std::make_pair( mime_type, impl_name ) ); - - return result.second; -} - -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLMediaManager::getImplNameFromMimeType( std::string mime_type ) -{ - mime_type_impl_name_container_t::iterator iter = - mMimeTypeImplNameContainer.find( mime_type ); - - if ( iter != mMimeTypeImplNameContainer.end() ) - { - return ( *iter ).second; - } - else - { - return std::string( "" ); - }; -} -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaManager::supportsMediaType( const std::string& impl_name, const std::string& scheme, const std::string& mime_type ) -{ - LLMediaImplMakerBase* impl_maker = LLMediaImplFactory::getInstance()->getImplMaker( impl_name ); - if( impl_maker ) - { - int idx1 = mime_type.find("/"); - int len = (idx1 == std::string::npos) ? 0 : idx1; - std::string category = mime_type.substr(0,len); - - return impl_maker->supportsScheme(scheme) || - impl_maker->supportsMimeType(mime_type) || - impl_maker->supportsMimeTypeCategory(category); - } - return false; -} - -// static -int LLMediaManager::textureWidthFromMediaWidth( int media_width ) -{ - int texture_width = 1; - while ( texture_width < media_width ) - { - texture_width <<= 1; - }; - return texture_width; -} - -// static -int LLMediaManager::textureHeightFromMediaHeight( int media_height ) -{ - int texture_height = 1; - while ( texture_height < media_height ) - { - texture_height <<= 1; - }; - return texture_height; -} diff --git a/linden/indra/llmedia/llmediamanager.h b/linden/indra/llmedia/llmediamanager.h deleted file mode 100644 index dc832d5db..000000000 --- a/linden/indra/llmedia/llmediamanager.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file llmediamanager.h - * @brief Manages instances of media impls - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAMANAGER_H -#define LLMEDIAMANAGER_H - -#include -#include - -#include "llmediaimplcommon.h" - -//////////////////////////////////////////////////////////////////////////////// -// -class LLMediaManagerData -{ - public: - LLMediaManagerData() : - mBrowserParentWindow( 0 ), - mBrowserProfileDir( "" ), - mBrowserProfileName ( "" ) - { }; - - void setBrowserApplicationDir( const std::string& browser_application_dir ) { mBrowserApplicationDir = browser_application_dir; }; - std::string& getBrowserApplicationDir() { return mBrowserApplicationDir; }; - - void setBrowserComponentDir( const std::string& browser_component_dir ) { mBrowserComponentDir = browser_component_dir; }; - std::string& getBrowserComponentDir() { return mBrowserComponentDir; }; - - void setBrowserParentWindow( void* browser_parent_window ) { mBrowserParentWindow = browser_parent_window; }; - void* getBrowserParentWindow() { return mBrowserParentWindow; }; - - void setBrowserProfileDir( const std::string& browser_profile_dir ) { mBrowserProfileDir = browser_profile_dir; }; - std::string& getBrowserProfileDir() { return mBrowserProfileDir; }; - - void setBrowserProfileName( const std::string& browser_profile_name ) { mBrowserProfileName = browser_profile_name; }; - std::string& getBrowserProfileName() { return mBrowserProfileName; }; - - private: - void* mBrowserParentWindow; - std::string mBrowserProfileDir; - std::string mBrowserProfileName; - std::string mBrowserApplicationDir; - std::string mBrowserComponentDir; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -class LLMediaManager -{ - public: - virtual ~LLMediaManager(); - - // Special case early init for just web browser component - // so we can show login screen. See .cpp file for details. JC - static void initBrowser( LLMediaManagerData* init_data ); - - static void initClass( LLMediaManagerData* init_data ); - static void cleanupClass(); - static LLMediaManager* getInstance(); - - // We append the skin name to the browser user agent string, so - // we need to change it while the app is running, not just at - // init time. - // Must be called after initClass() above. - // *HACK: Breaks encapsulation model. JC - static void setBrowserUserAgent(std::string user_agent); - - // Calls update on all media sources - static void updateClass(); - - // Given an URL and mime_type, construct/destroy a playback engine for - // it (a "media impl"). - LLMediaBase* createSourceFromMimeType( std::string scheme, std::string mime_type ); - bool destroySource( LLMediaBase* media_impl ); - - // mime type to impl mapping functions - bool addMimeTypeImplNameMap( std::string mime_type, std::string impl_name ); - std::string getImplNameFromMimeType( std::string mime_type ); - - // Name accessor for querying type support - bool supportsMediaType( const std::string& impl_name, const std::string& scheme, const std::string& mime_type ); - - // convenience functions for getting suggested texture sizes to hold various size media - static int textureWidthFromMediaWidth( int media_width ); - static int textureHeightFromMediaHeight( int media_height ); - - private: - LLMediaManager(); - static LLMediaManager* sInstance; - - typedef std::set< LLMediaBase* > media_impl_container_t; - media_impl_container_t mMediaImplContainer; - - typedef std::map< std::string, std::string > mime_type_impl_name_container_t; - mime_type_impl_name_container_t mMimeTypeImplNameContainer; -}; - -#endif // LLMEDIAMANAGER_H diff --git a/linden/indra/llmedia/llmediaobserver.h b/linden/indra/llmedia/llmediaobserver.h deleted file mode 100644 index ab8d7552f..000000000 --- a/linden/indra/llmedia/llmediaobserver.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file llmediaobserver.h - * @brief Derrive from this class and override methods to observe events from emitter class - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAEOBSERVER_H -#define LLMEDIAEOBSERVER_H - -class LLMediaBase; - -class LLMediaEvent -{ - public: - LLMediaEvent( LLMediaBase* subject ) : - mSubject( subject ), mIntValue(-1) - { - }; - - LLMediaEvent( LLMediaBase* subject, std::string in ) : - mSubject( subject ), mIntValue(-1), mStringValue(in) - { - }; - - LLMediaEvent( LLMediaBase* subject, std::string string_in, std::string string_ex_in ) : - mSubject( subject ), mIntValue(-1), mStringValue(string_in), mStringValueEx(string_ex_in) - { - }; - - LLMediaEvent( LLMediaBase* subject, std::string string_in, int int_in ) : - mSubject( subject ), mIntValue(int_in), mStringValue(string_in) - { - }; - - LLMediaEvent( LLMediaBase* subject, int in ) : - mSubject( subject ), mIntValue(in) - { - }; - - virtual ~LLMediaEvent() { } - - LLMediaBase* getSubject() const - { - return mSubject; - }; - - int getIntValue() const - { - return mIntValue; - } - - std::string getStringValue() const - { - return mStringValue; - } - - std::string getStringValueEx() const - { - return mStringValueEx; - } - - private: - LLMediaBase* mSubject; - int mIntValue; - std::string mStringValue; - std::string mStringValueEx; -}; - -class LLMediaObserver -{ - public: - virtual ~LLMediaObserver() {} - - typedef LLMediaEvent EventType; - virtual void onMediaPreroll( const EventType& event_in ) { } - virtual void onMediaLoaded( const EventType& event_in ) { } - virtual void onMediaSizeChange( const EventType& event_in ) { } - virtual void onMediaContentsChange( const EventType& event_in ) { } - virtual void onMediaStatusTextChange( const EventType& event_in ) { } - virtual void onMediaTitleChange( const EventType &event_in ) { } - virtual void onNavigateBegin( const EventType& event_in ) { } - virtual void onNavigateComplete( const EventType& event_in ) { } - virtual void onUpdateProgress( const EventType& event_in ) { } - virtual void onStatusTextChange( const EventType& event_in ) { } - virtual void onLocationChange( const EventType& event_in ) { } - virtual void onClickLinkHref( const EventType& event_in ) { } - virtual void onClickLinkNoFollow( const EventType& event_in ) { } -}; - -#endif // LLMEDIAEOBSERVER_H diff --git a/linden/indra/llmessage/tests/commtest.h b/linden/indra/llmessage/tests/commtest.h new file mode 100644 index 000000000..cf1461ed2 --- /dev/null +++ b/linden/indra/llmessage/tests/commtest.h @@ -0,0 +1,83 @@ +/** + * @file commtest.h + * @author Nat Goodspeed + * @date 2009-01-09 + * @brief + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#if ! defined(LL_COMMTEST_H) +#define LL_COMMTEST_H + +#include "networkio.h" +#include "llevents.h" +#include "llsd.h" +#include "llhost.h" +#include "stringize.h" +#include + +/** + * This struct is shared by a couple of standalone comm tests (ADD_COMM_BUILD_TEST). + */ +struct commtest_data +{ + NetworkIO& netio; + LLEventPumps& pumps; + LLEventStream replyPump, errorPump; + LLSD result; + bool success; + LLHost host; + std::string server; + + commtest_data(): + netio(NetworkIO::instance()), + pumps(LLEventPumps::instance()), + replyPump("reply"), + errorPump("error"), + success(false), + host("127.0.0.1", 8000), + server(STRINGIZE("http://" << host.getString() << "/")) + { + replyPump.listen("self", boost::bind(&commtest_data::outcome, this, _1, true)); + errorPump.listen("self", boost::bind(&commtest_data::outcome, this, _1, false)); + } + + bool outcome(const LLSD& _result, bool _success) + { +// std::cout << "commtest_data::outcome(" << _result << ", " << _success << ")\n"; + result = _result; + success = _success; + // Break the wait loop in NetworkIO::pump(), otherwise devs get + // irritated at making the big monolithic test executable take longer + pumps.obtain("done").post(success); + return false; + } +}; + +#endif /* ! defined(LL_COMMTEST_H) */ diff --git a/linden/indra/llmessage/tests/llcurl_stub.cpp b/linden/indra/llmessage/tests/llcurl_stub.cpp new file mode 100644 index 000000000..c73a5659f --- /dev/null +++ b/linden/indra/llmessage/tests/llcurl_stub.cpp @@ -0,0 +1,100 @@ +/** + * @file llcurl_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llcurl.h" + +LLCurl::Responder::Responder() : mReferenceCount(0) +{ +} + +void LLCurl::Responder::completed(U32 status, std::basic_string, std::allocator > const &reason, + LLSD const& mContent) +{ + if (isGoodStatus(status)) + { + result(mContent); + } + else + { + error(status, reason, mContent); + } +} + +void LLCurl::Responder::completedHeader(unsigned, + std::basic_string, std::allocator > const&, + LLSD const&) +{ +} + +void LLCurl::Responder::completedRaw(unsigned, + std::basic_string, std::allocator > const&, + LLChannelDescriptors const&, + boost::shared_ptr const&) +{ +} + +void LLCurl::Responder::error(unsigned, + std::basic_string, std::allocator > const&, + LLSD const&) +{ +} + +LLCurl::Responder::~Responder () +{ +} + +void LLCurl::Responder::error(unsigned, + std::basic_string, std::allocator > const&) +{ +} + +void LLCurl::Responder::result(LLSD const&) +{ +} + +namespace boost +{ + void intrusive_ptr_add_ref(LLCurl::Responder* p) + { + ++p->mReferenceCount; + } + + void intrusive_ptr_release(LLCurl::Responder* p) + { + if(p && 0 == --p->mReferenceCount) + { + delete p; + } + } +}; + diff --git a/linden/indra/llmessage/tests/llhttpclientadapter_test.cpp b/linden/indra/llmessage/tests/llhttpclientadapter_test.cpp new file mode 100644 index 000000000..7065c9d7e --- /dev/null +++ b/linden/indra/llmessage/tests/llhttpclientadapter_test.cpp @@ -0,0 +1,170 @@ +/** + * @file + * @brief + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llhttpclientadapter.h" + +#include "../test/lltut.h" +#include "llhttpclient.h" +#include "llcurl_stub.cpp" + +float const HTTP_REQUEST_EXPIRY_SECS = 1.0F; + +std::vector get_urls; +std::vector > get_responders; +void LLHTTPClient::get(const std::string& url, boost::intrusive_ptr responder, const LLSD& headers, const F32 timeout) +{ + get_urls.push_back(url); + get_responders.push_back(responder); +} + +std::vector put_urls; +std::vector put_body; +std::vector > put_responders; + +void LLHTTPClient::put(const std::string& url, const LLSD& body, boost::intrusive_ptr responder, const LLSD& headers, const F32 timeout) +{ + put_urls.push_back(url); + put_responders.push_back(responder); + put_body.push_back(body); + +} + + +namespace tut +{ + struct LLHTTPClientAdapterData + { + LLHTTPClientAdapterData() + { + get_urls.clear(); + get_responders.clear(); + put_urls.clear(); + put_responders.clear(); + put_body.clear(); + } + }; + + typedef test_group factory; + typedef factory::object object; +} + +namespace +{ + tut::factory tf("LLHTTPClientAdapterData test"); +} + +namespace tut +{ + // Ensure we can create the object + template<> template<> + void object::test<1>() + { + LLHTTPClientAdapter adapter; + } + + // Does the get pass the appropriate arguments to the LLHTTPClient + template<> template<> + void object::test<2>() + { + LLHTTPClientAdapter adapter; + + boost::intrusive_ptr responder = new LLCurl::Responder(); + + adapter.get("Made up URL", responder); + ensure_equals(get_urls.size(), 1); + ensure_equals(get_urls[0], "Made up URL"); + } + + // Ensure the responder matches the one passed to get + template<> template<> + void object::test<3>() + { + LLHTTPClientAdapter adapter; + boost::intrusive_ptr responder = new LLCurl::Responder(); + + adapter.get("Made up URL", responder); + + ensure_equals(get_responders.size(), 1); + ensure_equals(get_responders[0].get(), responder.get()); + } + + // Ensure the correct url is used in the put + template<> template<> + void object::test<4>() + { + LLHTTPClientAdapter adapter; + + boost::intrusive_ptr responder = new LLCurl::Responder(); + + LLSD body; + body["TestBody"] = "Foobar"; + + adapter.put("Made up URL", body, responder); + ensure_equals(put_urls.size(), 1); + ensure_equals(put_urls[0], "Made up URL"); + } + + // Ensure the correct responder is used by put + template<> template<> + void object::test<5>() + { + LLHTTPClientAdapter adapter; + + boost::intrusive_ptr responder = new LLCurl::Responder(); + + LLSD body; + body["TestBody"] = "Foobar"; + + adapter.put("Made up URL", body, responder); + + ensure_equals(put_responders.size(), 1); + ensure_equals(put_responders[0].get(), responder.get()); + } + + // Ensure the message body is passed through the put properly + template<> template<> + void object::test<6>() + { + LLHTTPClientAdapter adapter; + + boost::intrusive_ptr responder = new LLCurl::Responder(); + + LLSD body; + body["TestBody"] = "Foobar"; + + adapter.put("Made up URL", body, responder); + + ensure_equals(put_body.size(), 1); + ensure_equals(put_body[0]["TestBody"].asString(), "Foobar"); + } +} + diff --git a/linden/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/linden/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp new file mode 100644 index 000000000..d57f17f27 --- /dev/null +++ b/linden/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -0,0 +1,165 @@ +/** + * @file lltrustedmessageservice_test.cpp + * @brief LLTrustedMessageService unit tests + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "lltemplatemessagedispatcher.h" +#include "lltut.h" + +#include "llhttpnode.h" +#include "llhost.h" +#include "message.h" +#include "llsd.h" + +#include "llhost.cpp" // Needed for copy operator +#include "net.cpp" // Needed by LLHost. + +LLMessageSystem * gMessageSystem = NULL; + +// sensor test doubles +bool gClearRecvWasCalled = false; +void LLMessageSystem::clearReceiveState(void) +{ + gClearRecvWasCalled = true; +} + +char gUdpDispatchedData[MAX_BUFFER_SIZE]; +bool gUdpDispatchWasCalled = false; +BOOL LLTemplateMessageReader::readMessage(const U8* data,class LLHost const &) +{ + gUdpDispatchWasCalled = true; + strcpy(gUdpDispatchedData, reinterpret_cast(data)); + return true; +} + +BOOL gValidateMessage = FALSE; +BOOL LLTemplateMessageReader::validateMessage(const U8*, S32 buffer_size, LLHost const &sender, bool trusted) +{ + return gValidateMessage; +} + +LLHost host; +const LLHost& LLMessageSystem::getSender() const +{ + return host; +} + +const char* gBinaryTemplateData = "BINARYTEMPLATEDATA"; +void fillVector(std::vector& vector_data, const char* data) +{ + vector_data.resize(strlen(data) + 1); + strcpy(reinterpret_cast(&vector_data[0]), data); +} + +namespace tut +{ + static LLTemplateMessageReader::message_template_number_map_t numberMap; + + struct LLTemplateMessageDispatcherData + { + LLTemplateMessageDispatcherData() + { + mMessageName = "MessageName"; + gUdpDispatchWasCalled = false; + gClearRecvWasCalled = false; + gValidateMessage = FALSE; + mMessage["body"]["binary-template-data"] = std::vector(); + } + + LLSD mMessage; + LLHTTPNode::ResponsePtr mResponsePtr; + std::string mMessageName; + }; + + typedef test_group factory; + typedef factory::object object; +} + +namespace +{ + tut::factory tf("LLTemplateMessageDispatcher test"); +} + +namespace tut +{ + // does an empty message stop processing? + template<> template<> + void object::test<1>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure(! gUdpDispatchWasCalled); + ensure(! gClearRecvWasCalled); + } + + // does the disaptch invoke the udp send method? + template<> template<> + void object::test<2>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + gValidateMessage = TRUE; + std::vector vector_data; + fillVector(vector_data, gBinaryTemplateData); + mMessage["body"]["binary-template-data"] = vector_data; + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure("udp dispatch was called", gUdpDispatchWasCalled); + } + + // what if the message wasn't valid? We would hope the message gets cleared! + template<> template<> + void object::test<3>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + std::vector vector_data; + fillVector(vector_data, gBinaryTemplateData); + mMessage["body"]["binary-template-data"] = vector_data; + gValidateMessage = FALSE; + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure("clear received message was called", gClearRecvWasCalled); + } + + // is the binary data passed through correctly? + template<> template<> + void object::test<4>() + { + LLTemplateMessageReader* pReader = NULL; + LLTemplateMessageDispatcher t(*pReader); + gValidateMessage = TRUE; + std::vector vector_data; + fillVector(vector_data, gBinaryTemplateData); + mMessage["body"]["binary-template-data"] = vector_data; + t.dispatch(mMessageName, mMessage, mResponsePtr); + ensure("data couriered correctly", strcmp(gBinaryTemplateData, gUdpDispatchedData) == 0); + } +} + diff --git a/linden/indra/llmessage/tests/lltesthttpclientadapter.cpp b/linden/indra/llmessage/tests/lltesthttpclientadapter.cpp new file mode 100644 index 000000000..6361f1cee --- /dev/null +++ b/linden/indra/llmessage/tests/lltesthttpclientadapter.cpp @@ -0,0 +1,67 @@ +/** + * @file + * @brief + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "lltesthttpclientadapter.h" + +LLTestHTTPClientAdapter::LLTestHTTPClientAdapter() +{ +} + +LLTestHTTPClientAdapter::~LLTestHTTPClientAdapter() +{ +} + +void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder) +{ + mGetUrl.push_back(url); + mGetResponder.push_back(responder); +} + +void LLTestHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) +{ + mPutUrl.push_back(url); + mPutBody.push_back(body); + mPutResponder.push_back(responder); +} + +U32 LLTestHTTPClientAdapter::putCalls() const +{ + return mPutUrl.size(); +} + +void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) +{ + mGetUrl.push_back(url); + mGetHeaders.push_back(headers); + mGetResponder.push_back(responder); +} + + diff --git a/linden/indra/llmessage/tests/lltesthttpclientadapter.h b/linden/indra/llmessage/tests/lltesthttpclientadapter.h new file mode 100644 index 000000000..ac2afa8ff --- /dev/null +++ b/linden/indra/llmessage/tests/lltesthttpclientadapter.h @@ -0,0 +1,63 @@ +/** + * @file + * @brief + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* Macro Definitions */ +#ifndef LL_LLTESTHTTPCLIENTADAPTER_H +#define LL_LLTESTHTTPCLIENTADAPTER_H + + +#include "linden_common.h" +#include "llhttpclientinterface.h" + +class LLTestHTTPClientAdapter : public LLHTTPClientInterface +{ +public: + LLTestHTTPClientAdapter(); + virtual ~LLTestHTTPClientAdapter(); + virtual void get(const std::string& url, LLCurl::ResponderPtr responder); + virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers); + + virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder); + U32 putCalls() const; + + std::vector mPutBody; + std::vector mGetHeaders; + std::vector mPutUrl; + std::vector mGetUrl; + std::vector mPutResponder; + std::vector mGetResponder; +}; + + + +#endif //LL_LLSIMULATORPRESENCESENDER_H + diff --git a/linden/indra/llmessage/tests/lltestmessagesender.cpp b/linden/indra/llmessage/tests/lltestmessagesender.cpp new file mode 100644 index 000000000..5e8a87f6f --- /dev/null +++ b/linden/indra/llmessage/tests/lltestmessagesender.cpp @@ -0,0 +1,44 @@ +/** + * @file + * @brief + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "lltestmessagesender.h" + +LLTestMessageSender::~LLTestMessageSender() +{ +} + + +S32 LLTestMessageSender::sendMessage(const LLHost& host, LLStoredMessagePtr message) +{ + mSendHosts.push_back(host); + mSendMessages.push_back(message); + return 0; +} diff --git a/linden/indra/llmessage/tests/lltestmessagesender.h b/linden/indra/llmessage/tests/lltestmessagesender.h new file mode 100644 index 000000000..f57210e77 --- /dev/null +++ b/linden/indra/llmessage/tests/lltestmessagesender.h @@ -0,0 +1,57 @@ +/** + * @file + * @brief + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* Macro Definitions */ +#ifndef LL_LLTESTMESSAGESENDER_H +#define LL_LLTESTMESSAGESENDER_H + + +#include "linden_common.h" +#include "llmessagesenderinterface.h" +#include + + + +class LLTestMessageSender : public LLMessageSenderInterface +{ +public: + virtual ~LLTestMessageSender(); + virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message); + + std::vector mSendHosts; + std::vector mSendMessages; +}; + + + +#endif //LL_LLTESTMESSAGESENDER_H + diff --git a/linden/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/linden/indra/llmessage/tests/lltrustedmessageservice_test.cpp new file mode 100644 index 000000000..0a3da4b46 --- /dev/null +++ b/linden/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -0,0 +1,146 @@ +/** + * @file lltrustedmessageservice_test.cpp + * @brief LLTrustedMessageService unit tests + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "lltrustedmessageservice.h" +#include "../test/lltut.h" + +#include "llhost.cpp" // LLHost is a value type for test purposes. +#include "net.cpp" // Needed by LLHost. + +#include "message.h" +#include "llmessageconfig.h" + +LLMessageSystem* gMessageSystem = NULL; + +LLMessageConfig::SenderTrust +LLMessageConfig::getSenderTrustedness(const std::string& msg_name) +{ + return LLMessageConfig::NOT_SET; +} + +void LLMessageSystem::receivedMessageFromTrustedSender() +{ +} + +bool LLMessageSystem::isTrustedSender(const LLHost& host) const +{ + return false; +} + +bool LLMessageSystem::isTrustedMessage(const std::string& name) const +{ + return false; +} + +bool messageDispatched = false; +bool messageDispatchedAsBinary = false; +LLSD lastLLSD; +std::string lastMessageName; + +void LLMessageSystem::dispatch(const std::string& msg_name, + const LLSD& message, + LLHTTPNode::ResponsePtr responsep) +{ + messageDispatched = true; + lastLLSD = message; + lastMessageName = msg_name; +} + +void LLMessageSystem::dispatchTemplate(const std::string& msg_name, + const LLSD& message, + LLHTTPNode::ResponsePtr responsep) +{ + lastLLSD = message; + lastMessageName = msg_name; + messageDispatchedAsBinary = true; +} + +namespace tut +{ + struct LLTrustedMessageServiceData + { + LLTrustedMessageServiceData() + { + LLSD emptyLLSD; + lastLLSD = emptyLLSD; + lastMessageName = "uninitialised message name"; + messageDispatched = false; + messageDispatchedAsBinary = false; + } + }; + + typedef test_group factory; + typedef factory::object object; +} + +namespace +{ + tut::factory tf("LLTrustedMessageServiceData test"); +} + +namespace tut +{ + // characterisation tests + + // 1) test that messages get forwarded with names etc. as current behaviour (something like LLMessageSystem::dispatch(name, data...) + + // test llsd messages are sent as normal using LLMessageSystem::dispatch() (eventually) + template<> template<> + void object::test<1>() + { + LLHTTPNode::ResponsePtr response; + LLSD input; + LLSD context; + LLTrustedMessageService adapter; + adapter.post(response, context, input); + // test original ting got called wit nowt, ya get me blood? + ensure_equals(messageDispatched, true); + ensure(lastLLSD.has("body")); + } + + // test that llsd wrapped binary-template-data messages are + // sent via LLMessageSystem::binaryDispatch() or similar + template<> template<> + void object::test<2>() + { + LLHTTPNode::ResponsePtr response; + LLSD input; + input["binary-template-data"] = "10001010110"; //make me a message here. + LLSD context; + LLTrustedMessageService adapter; + + adapter.post(response, context, input); + ensure("check template-binary-data message was dispatched as binary", messageDispatchedAsBinary); + ensure_equals(lastLLSD["body"]["binary-template-data"].asString(), "10001010110"); + // test somit got called with "10001010110" (something like LLMessageSystem::dispatchTemplate(blah)) + } +} diff --git a/linden/indra/llmessage/tests/networkio.h b/linden/indra/llmessage/tests/networkio.h new file mode 100644 index 000000000..0ebe369ea --- /dev/null +++ b/linden/indra/llmessage/tests/networkio.h @@ -0,0 +1,116 @@ +/** + * @file networkio.h + * @author Nat Goodspeed + * @date 2009-01-09 + * @brief + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#if ! defined(LL_NETWORKIO_H) +#define LL_NETWORKIO_H + +#include "llmemory.h" // LLSingleton +#include "llapr.h" +#include "llares.h" +#include "llpumpio.h" +#include "llhttpclient.h" + +/***************************************************************************** +* NetworkIO +*****************************************************************************/ +// Doing this initialization in a class constructor makes sense. But we don't +// want to redo it for each different test. Nor do we want to do it at static- +// init time. Use the lazy, on-demand initialization we get from LLSingleton. +class NetworkIO: public LLSingleton +{ +public: + NetworkIO(): + mServicePump(NULL), + mDone(false) + { + ll_init_apr(); + if (! gAPRPoolp) + { + throw std::runtime_error("Can't initialize APR"); + } + + // Create IO Pump to use for HTTP Requests. + mServicePump = new LLPumpIO(gAPRPoolp); + LLHTTPClient::setPump(*mServicePump); + if (ll_init_ares() == NULL || !gAres->isInitialized()) + { + throw std::runtime_error("Can't start DNS resolver"); + } + + // You can interrupt pump() without waiting the full timeout duration + // by posting an event to the LLEventPump named "done". + LLEventPumps::instance().obtain("done").listen("self", + boost::bind(&NetworkIO::done, this, _1)); + } + + bool pump(F32 timeout=10) + { + // Reset the done flag so we don't pop out prematurely + mDone = false; + // Evidently the IO structures underlying LLHTTPClient need to be + // "pumped". Do some stuff normally performed in the viewer's main + // loop. + LLTimer timer; + while (timer.getElapsedTimeF32() < timeout) + { + if (mDone) + { +// std::cout << "NetworkIO::pump(" << timeout << "): breaking loop after " +// << timer.getElapsedTimeF32() << " seconds\n"; + return true; + } + pumpOnce(); + } + return false; + } + + void pumpOnce() + { + gAres->process(); + mServicePump->pump(); + mServicePump->callback(); + } + + bool done(const LLSD&) + { + mDone = true; + return false; + } + +private: + LLPumpIO* mServicePump; + bool mDone; +}; + +#endif /* ! defined(LL_NETWORKIO_H) */ diff --git a/linden/indra/llmessage/tests/test_llsdmessage_peer.py b/linden/indra/llmessage/tests/test_llsdmessage_peer.py new file mode 100644 index 000000000..655169def --- /dev/null +++ b/linden/indra/llmessage/tests/test_llsdmessage_peer.py @@ -0,0 +1,153 @@ +#!/usr/bin/python +"""\ +@file test_llsdmessage_peer.py +@author Nat Goodspeed +@date 2008-10-09 +@brief This script asynchronously runs the executable (with args) specified on + the command line, returning its result code. While that executable is + running, we provide dummy local services for use by C++ tests. + +$LicenseInfo:firstyear=2008&license=viewergpl$ + +Copyright (c) 2008-2009, Linden Research, Inc. + +Second Life Viewer Source Code +The source code in this file ("Source Code") is provided by Linden Lab +to you under the terms of the GNU General Public License, version 2.0 +("GPL"), unless you have obtained a separate licensing agreement +("Other License"), formally executed by you and Linden Lab. Terms of +the GPL can be found in doc/GPL-license.txt in this distribution, or +online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + +There are special exceptions to the terms and conditions of the GPL as +it is applied to this Source Code. View the full text of the exception +in the file doc/FLOSS-exception.txt in this software distribution, or +online at +http://secondlifegrid.net/programs/open_source/licensing/flossexception + +By copying, modifying or distributing this software, you acknowledge +that you have read and understood your obligations described above, +and agree to abide by those obligations. + +ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +COMPLETENESS OR PERFORMANCE. +$/LicenseInfo$ +""" + +import os +import sys +from threading import Thread +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tests/ +sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) +from indra.util.fastest_elementtree import parse as xml_parse +from indra.base import llsd + +def debug(*args): + sys.stdout.writelines(args) + sys.stdout.flush() +# comment out the line below to enable debug output +debug = lambda *args: None + +class TestHTTPRequestHandler(BaseHTTPRequestHandler): + """This subclass of BaseHTTPRequestHandler is to receive and echo + LLSD-flavored messages sent by the C++ LLHTTPClient. + """ + def read(self): + # The following logic is adapted from the library module + # SimpleXMLRPCServer.py. + # Get arguments by reading body of request. + # We read this in chunks to avoid straining + # socket.read(); around the 10 or 15Mb mark, some platforms + # begin to have problems (bug #792570). + try: + size_remaining = int(self.headers["content-length"]) + except (KeyError, ValueError): + return "" + max_chunk_size = 10*1024*1024 + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + chunk = self.rfile.read(chunk_size) + L.append(chunk) + size_remaining -= len(chunk) + return ''.join(L) + # end of swiped read() logic + + def read_xml(self): + # This approach reads the entire POST data into memory first + return llsd.parse(self.read()) +## # This approach attempts to stream in the LLSD XML from self.rfile, +## # assuming that the underlying XML parser reads its input file +## # incrementally. Unfortunately I haven't been able to make it work. +## tree = xml_parse(self.rfile) +## debug("Finished raw parse\n") +## debug("parsed XML tree %s\n" % tree) +## debug("parsed root node %s\n" % tree.getroot()) +## debug("root node tag %s\n" % tree.getroot().tag) +## return llsd.to_python(tree.getroot()) + + def do_GET(self): + # Of course, don't attempt to read data. + self.answer(dict(reply="success", status=500, + reason="Your GET operation requested failure")) + + def do_POST(self): + # Read the provided POST data. + self.answer(self.read_xml()) + + def answer(self, data): + if "fail" not in self.path: + response = llsd.format_xml(data.get("reply", llsd.LLSD("success"))) + self.send_response(200) + self.send_header("Content-type", "application/llsd+xml") + self.send_header("Content-Length", str(len(response))) + self.end_headers() + self.wfile.write(response) + else: # fail requested + status = data.get("status", 500) + reason = data.get("reason", + self.responses.get(status, + ("fail requested", + "Your request specified failure status %s " + "without providing a reason" % status))[1]) + self.send_error(status, reason) + + def log_request(self, code, size=None): + # For present purposes, we don't want the request splattered onto + # stderr, as it would upset devs watching the test run + pass + + def log_error(self, format, *args): + # Suppress error output as well + pass + +class TestHTTPServer(Thread): + def run(self): + httpd = HTTPServer(('127.0.0.1', 8000), TestHTTPRequestHandler) + debug("Starting HTTP server...\n") + httpd.serve_forever() + +def main(*args): + # Start HTTP server thread. Note that this and all other comm server + # threads should be daemon threads: we'll let them run "forever," + # confident that the whole process will terminate when the main thread + # terminates, which will be when the test executable child process + # terminates. + httpThread = TestHTTPServer(name="httpd") + httpThread.setDaemon(True) + httpThread.start() + # choice of os.spawnv(): + # - [v vs. l] pass a list of args vs. individual arguments, + # - [no p] don't use the PATH because we specifically want to invoke the + # executable passed as our first arg, + # - [no e] child should inherit this process's environment. + debug("Running %s...\n" % (" ".join(args))) + sys.stdout.flush() + rc = os.spawnv(os.P_WAIT, args[0], args) + debug("%s returned %s\n" % (args[0], rc)) + return rc + +if __name__ == "__main__": + sys.exit(main(*sys.argv[1:])) diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt new file mode 100644 index 000000000..6706775d4 --- /dev/null +++ b/linden/indra/llplugin/CMakeLists.txt @@ -0,0 +1,55 @@ +# -*- cmake -*- + +project(llplugin) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLMath) +include(LLMessage) +include(LLRender) +include(LLXML) +include(LLWindow) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLMESSAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLXML_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} + ) + +set(llplugin_SOURCE_FILES + llpluginclassmedia.cpp + llplugininstance.cpp + llpluginmessage.cpp + llpluginmessagepipe.cpp + llpluginprocesschild.cpp + llpluginprocessparent.cpp + llpluginsharedmemory.cpp + ) + +set(llplugin_HEADER_FILES + CMakeLists.txt + + llpluginclassmedia.h + llpluginclassmediaowner.h + llplugininstance.h + llpluginmessage.h + llpluginmessageclasses.h + llpluginmessagepipe.h + llpluginprocesschild.h + llpluginprocessparent.h + llpluginsharedmemory.h + ) + +set_source_files_properties(${llplugin_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) + +add_library (llplugin ${llplugin_SOURCE_FILES}) + +add_subdirectory(slplugin) diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp new file mode 100644 index 000000000..a6f6f30bf --- /dev/null +++ b/linden/indra/llplugin/llpluginclassmedia.cpp @@ -0,0 +1,1162 @@ +/** + * @file llpluginclassmedia.cpp + * @brief LLPluginClassMedia handles a plugin which knows about the "media" message class. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "indra_constants.h" + +#include "llpluginclassmedia.h" +#include "llpluginmessageclasses.h" + +static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256; + +static int nextPowerOf2( int value ) +{ + int next_power_of_2 = 1; + while ( next_power_of_2 < value ) + { + next_power_of_2 <<= 1; + } + + return next_power_of_2; +} + +LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner) +{ + mOwner = owner; + mPlugin = NULL; + reset(); +} + + +LLPluginClassMedia::~LLPluginClassMedia() +{ + reset(); +} + +bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path) +{ + LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL; + LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL; + LL_DEBUGS("Plugin") << "user_data_path: " << user_data_path << LL_ENDL; + + mPlugin = new LLPluginProcessParent(this); + mPlugin->setSleepTime(mSleepTime); + mPlugin->init(launcher_filename, plugin_filename, debug, user_data_path); + + return true; +} + + +void LLPluginClassMedia::reset() +{ + if(mPlugin != NULL) + { + delete mPlugin; + mPlugin = NULL; + } + + mTextureParamsReceived = false; + mRequestedTextureDepth = 0; + mRequestedTextureInternalFormat = 0; + mRequestedTextureFormat = 0; + mRequestedTextureType = 0; + mRequestedTextureSwapBytes = false; + mRequestedTextureCoordsOpenGL = false; + mTextureSharedMemorySize = 0; + mTextureSharedMemoryName.clear(); + mDefaultMediaWidth = 0; + mDefaultMediaHeight = 0; + mNaturalMediaWidth = 0; + mNaturalMediaHeight = 0; + mSetMediaWidth = -1; + mSetMediaHeight = -1; + mRequestedMediaWidth = 0; + mRequestedMediaHeight = 0; + mFullMediaWidth = 0; + mFullMediaHeight = 0; + mTextureWidth = 0; + mTextureHeight = 0; + mMediaWidth = 0; + mMediaHeight = 0; + mDirtyRect = LLRect::null; + mAutoScaleMedia = false; + mRequestedVolume = 1.0f; + mPriority = PRIORITY_NORMAL; + mLowPrioritySizeLimit = LOW_PRIORITY_TEXTURE_SIZE_DEFAULT; + mAllowDownsample = false; + mPadding = 0; + mLastMouseX = 0; + mLastMouseY = 0; + mStatus = LLPluginClassMediaOwner::MEDIA_NONE; + mSleepTime = 1.0f / 100.0f; + mCanCut = false; + mCanCopy = false; + mCanPaste = false; + mMediaName.clear(); + mMediaDescription.clear(); + + // media_browser class + mNavigateURI.clear(); + mNavigateResultCode = -1; + mNavigateResultString.clear(); + mHistoryBackAvailable = false; + mHistoryForwardAvailable = false; + mStatusText.clear(); + mProgressPercent = 0; + + // media_time class + mCurrentTime = 0.0f; + mDuration = 0.0f; + mCurrentRate = 0.0f; + mLoadedDuration = 0.0f; +} + +void LLPluginClassMedia::idle(void) +{ + if(mPlugin) + { + mPlugin->idle(); + } + + if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL)) + { + // Can't process a size change at this time + } + else if((mRequestedMediaWidth != mMediaWidth) || (mRequestedMediaHeight != mMediaHeight)) + { + // Calculate the correct size for the media texture + mRequestedTextureHeight = mRequestedMediaHeight; + if(mPadding < 0) + { + // negative values indicate the plugin wants a power of 2 + mRequestedTextureWidth = nextPowerOf2(mRequestedMediaWidth); + } + else + { + mRequestedTextureWidth = mRequestedMediaWidth; + + if(mPadding > 1) + { + // Pad up to a multiple of the specified number of bytes per row + int rowbytes = mRequestedTextureWidth * mRequestedTextureDepth; + int pad = rowbytes % mPadding; + if(pad != 0) + { + rowbytes += mPadding - pad; + } + + if(rowbytes % mRequestedTextureDepth == 0) + { + mRequestedTextureWidth = rowbytes / mRequestedTextureDepth; + } + else + { + LL_WARNS("Plugin") << "Unable to pad texture width, padding size " << mPadding << "is not a multiple of pixel size " << mRequestedTextureDepth << LL_ENDL; + } + } + } + + + // Size change has been requested but not initiated yet. + size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth; + + // Add an extra line for padding, just in case. + newsize += mRequestedTextureWidth * mRequestedTextureDepth; + + if(newsize != mTextureSharedMemorySize) + { + if(!mTextureSharedMemoryName.empty()) + { + // Tell the plugin to remove the old memory segment + mPlugin->removeSharedMemory(mTextureSharedMemoryName); + mTextureSharedMemoryName.clear(); + } + + mTextureSharedMemorySize = newsize; + mTextureSharedMemoryName = mPlugin->addSharedMemory(mTextureSharedMemorySize); + if(!mTextureSharedMemoryName.empty()) + { + void *addr = mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName); + + // clear texture memory to avoid random screen visual fuzz from uninitialized texture data + memset( addr, 0x00, newsize ); + + // We could do this to force an update, but textureValid() will still be returning false until the first roundtrip to the plugin, + // so it may not be worthwhile. + // mDirtyRect.setOriginAndSize(0, 0, mRequestedMediaWidth, mRequestedMediaHeight); + } + } + + // This is our local indicator that a change is in progress. + mTextureWidth = -1; + mTextureHeight = -1; + mMediaWidth = -1; + mMediaHeight = -1; + + // This invalidates any existing dirty rect. + resetDirty(); + + // Send a size change message to the plugin + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change"); + message.setValue("name", mTextureSharedMemoryName); + message.setValueS32("width", mRequestedMediaWidth); + message.setValueS32("height", mRequestedMediaHeight); + message.setValueS32("texture_width", mRequestedTextureWidth); + message.setValueS32("texture_height", mRequestedTextureHeight); + mPlugin->sendMessage(message); // DO NOT just use sendMessage() here -- we want this to jump ahead of the queue. + + LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL; + } + } + + if(mPlugin && mPlugin->isRunning()) + { + // Send queued messages + while(!mSendQueue.empty()) + { + LLPluginMessage message = mSendQueue.front(); + mSendQueue.pop(); + mPlugin->sendMessage(message); + } + } +} + +int LLPluginClassMedia::getTextureWidth() const +{ + return nextPowerOf2(mTextureWidth); +} + +int LLPluginClassMedia::getTextureHeight() const +{ + return nextPowerOf2(mTextureHeight); +} + +unsigned char* LLPluginClassMedia::getBitsData() +{ + unsigned char *result = NULL; + if((mPlugin != NULL) && !mTextureSharedMemoryName.empty()) + { + result = (unsigned char*)mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName); + } + return result; +} + +void LLPluginClassMedia::setSize(int width, int height) +{ + if((width > 0) && (height > 0)) + { + mSetMediaWidth = width; + mSetMediaHeight = height; + } + else + { + mSetMediaWidth = -1; + mSetMediaHeight = -1; + } + + setSizeInternal(); +} + +void LLPluginClassMedia::setSizeInternal(void) +{ + if((mSetMediaWidth > 0) && (mSetMediaHeight > 0)) + { + mRequestedMediaWidth = mSetMediaWidth; + mRequestedMediaHeight = mSetMediaHeight; + } + else if((mNaturalMediaWidth > 0) && (mNaturalMediaHeight > 0)) + { + mRequestedMediaWidth = mNaturalMediaWidth; + mRequestedMediaHeight = mNaturalMediaHeight; + } + else + { + mRequestedMediaWidth = mDefaultMediaWidth; + mRequestedMediaHeight = mDefaultMediaHeight; + } + + // Save these for size/interest calculations + mFullMediaWidth = mRequestedMediaWidth; + mFullMediaHeight = mRequestedMediaHeight; + + if(mAllowDownsample) + { + switch(mPriority) + { + case PRIORITY_SLIDESHOW: + case PRIORITY_LOW: + // Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit + while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit)) + { + mRequestedMediaWidth /= 2; + mRequestedMediaHeight /= 2; + } + break; + + default: + // Don't adjust texture size + break; + } + } + + if(mAutoScaleMedia) + { + mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth); + mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight); + } + + if(mRequestedMediaWidth > 2048) + mRequestedMediaWidth = 2048; + + if(mRequestedMediaHeight > 2048) + mRequestedMediaHeight = 2048; +} + +void LLPluginClassMedia::setAutoScale(bool auto_scale) +{ + if(auto_scale != mAutoScaleMedia) + { + mAutoScaleMedia = auto_scale; + setSizeInternal(); + } +} + +bool LLPluginClassMedia::textureValid(void) +{ + if( + !mTextureParamsReceived || + mTextureWidth <= 0 || + mTextureHeight <= 0 || + mMediaWidth <= 0 || + mMediaHeight <= 0 || + mRequestedMediaWidth != mMediaWidth || + mRequestedMediaHeight != mMediaHeight || + getBitsData() == NULL + ) + return false; + + return true; +} + +bool LLPluginClassMedia::getDirty(LLRect *dirty_rect) +{ + bool result = !mDirtyRect.isNull(); + + if(dirty_rect != NULL) + { + *dirty_rect = mDirtyRect; + } + + return result; +} + +void LLPluginClassMedia::resetDirty(void) +{ + mDirtyRect = LLRect::null; +} + +std::string LLPluginClassMedia::translateModifiers(MASK modifiers) +{ + std::string result; + + + if(modifiers & MASK_CONTROL) + { + result += "control|"; + } + + if(modifiers & MASK_ALT) + { + result += "alt|"; + } + + if(modifiers & MASK_SHIFT) + { + result += "shift|"; + } + + // TODO: should I deal with platform differences here or in callers? + // TODO: how do we deal with the Mac "command" key? +/* + if(modifiers & MASK_SOMETHING) + { + result += "meta|"; + } +*/ + return result; +} + +void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers) +{ + if(type == MOUSE_EVENT_MOVE) + { + if((x == mLastMouseX) && (y == mLastMouseY)) + { + // Don't spam unnecessary mouse move events. + return; + } + + mLastMouseX = x; + mLastMouseY = y; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "mouse_event"); + std::string temp; + switch(type) + { + case MOUSE_EVENT_DOWN: temp = "down"; break; + case MOUSE_EVENT_UP: temp = "up"; break; + case MOUSE_EVENT_MOVE: temp = "move"; break; + case MOUSE_EVENT_DOUBLE_CLICK: temp = "double_click"; break; + } + message.setValue("event", temp); + + message.setValueS32("button", button); + + message.setValueS32("x", x); + + // Incoming coordinates are OpenGL-style ((0,0) = lower left), so flip them here if the plugin has requested it. + if(!mRequestedTextureCoordsOpenGL) + { + // TODO: Should I use mMediaHeight or mRequestedMediaHeight here? + y = mMediaHeight - y; + } + message.setValueS32("y", y); + + message.setValue("modifiers", translateModifiers(modifiers)); + + sendMessage(message); +} + +bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers) +{ + bool result = true; + + // FIXME: + // HACK: we don't have an easy way to tell if the plugin is going to handle a particular keycode. + // For now, return false for the ones the webkit plugin won't handle properly. + + switch(key_code) + { + case KEY_BACKSPACE: + case KEY_TAB: + case KEY_RETURN: + case KEY_PAD_RETURN: + case KEY_SHIFT: + case KEY_CONTROL: + case KEY_ALT: + case KEY_CAPSLOCK: + case KEY_ESCAPE: + case KEY_PAGE_UP: + case KEY_PAGE_DOWN: + case KEY_END: + case KEY_HOME: + case KEY_LEFT: + case KEY_UP: + case KEY_RIGHT: + case KEY_DOWN: + case KEY_INSERT: + case KEY_DELETE: + // These will be handled + break; + + default: + // regular ASCII characters will also be handled + if(key_code >= KEY_SPECIAL) + { + // Other "special" codes will not work properly. + result = false; + } + break; + } + + if(result) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "key_event"); + std::string temp; + switch(type) + { + case KEY_EVENT_DOWN: temp = "down"; break; + case KEY_EVENT_UP: temp = "up"; break; + case KEY_EVENT_REPEAT: temp = "repeat"; break; + } + message.setValue("event", temp); + + message.setValueS32("key", key_code); + + message.setValue("modifiers", translateModifiers(modifiers)); + + sendMessage(message); + } + + return result; +} + +void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event"); + + message.setValueS32("x", x); + message.setValueS32("y", y); + message.setValue("modifiers", translateModifiers(modifiers)); + + sendMessage(message); +} + +bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event"); + + message.setValue("text", text); + message.setValue("modifiers", translateModifiers(modifiers)); + + sendMessage(message); + + return true; +} + +void LLPluginClassMedia::loadURI(const std::string &uri) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri"); + + message.setValue("uri", uri); + + sendMessage(message); +} + +const char* LLPluginClassMedia::priorityToString(EPriority priority) +{ + const char* result = "UNKNOWN"; + switch(priority) + { + case PRIORITY_UNLOADED: result = "unloaded"; break; + case PRIORITY_STOPPED: result = "stopped"; break; + case PRIORITY_HIDDEN: result = "hidden"; break; + case PRIORITY_SLIDESHOW: result = "slideshow"; break; + case PRIORITY_LOW: result = "low"; break; + case PRIORITY_NORMAL: result = "normal"; break; + case PRIORITY_HIGH: result = "high"; break; + } + + return result; +} + +void LLPluginClassMedia::setPriority(EPriority priority) +{ + if(mPriority != priority) + { + mPriority = priority; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_priority"); + + std::string priority_string = priorityToString(priority); + switch(priority) + { + case PRIORITY_UNLOADED: + mSleepTime = 1.0f; + break; + case PRIORITY_STOPPED: + mSleepTime = 1.0f; + break; + case PRIORITY_HIDDEN: + mSleepTime = 1.0f; + break; + case PRIORITY_SLIDESHOW: + mSleepTime = 1.0f; + break; + case PRIORITY_LOW: + mSleepTime = 1.0f / 25.0f; + break; + case PRIORITY_NORMAL: + mSleepTime = 1.0f / 50.0f; + break; + case PRIORITY_HIGH: + mSleepTime = 1.0f / 100.0f; + break; + } + + message.setValue("priority", priority_string); + + sendMessage(message); + + if(mPlugin) + { + mPlugin->setSleepTime(mSleepTime); + } + + LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL; + + // This may affect the calculated size, so recalculate it here. + setSizeInternal(); + } +} + +void LLPluginClassMedia::setLowPrioritySizeLimit(int size) +{ + int power = nextPowerOf2(size); + if(mLowPrioritySizeLimit != power) + { + mLowPrioritySizeLimit = power; + + // This may affect the calculated size, so recalculate it here. + setSizeInternal(); + } +} + +F64 LLPluginClassMedia::getCPUUsage() +{ + F64 result = 0.0f; + + if(mPlugin) + { + result = mPlugin->getCPUUsage(); + } + + return result; +} + +void LLPluginClassMedia::cut() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut"); + sendMessage(message); +} + +void LLPluginClassMedia::copy() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_copy"); + sendMessage(message); +} + +void LLPluginClassMedia::paste() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_paste"); + sendMessage(message); +} + +/* virtual */ +void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) +{ + std::string message_class = message.getClass(); + + if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + std::string message_name = message.getName(); + if(message_name == "texture_params") + { + mRequestedTextureDepth = message.getValueS32("depth"); + mRequestedTextureInternalFormat = message.getValueU32("internalformat"); + mRequestedTextureFormat = message.getValueU32("format"); + mRequestedTextureType = message.getValueU32("type"); + mRequestedTextureSwapBytes = message.getValueBoolean("swap_bytes"); + mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl"); + + // These two are optional, and will default to 0 if they're not specified. + mDefaultMediaWidth = message.getValueS32("default_width"); + mDefaultMediaHeight = message.getValueS32("default_height"); + + mAllowDownsample = message.getValueBoolean("allow_downsample"); + mPadding = message.getValueS32("padding"); + + setSizeInternal(); + + mTextureParamsReceived = true; + } + else if(message_name == "updated") + { + if(message.hasValue("left")) + { + LLRect newDirtyRect; + newDirtyRect.mLeft = message.getValueS32("left"); + newDirtyRect.mTop = message.getValueS32("top"); + newDirtyRect.mRight = message.getValueS32("right"); + newDirtyRect.mBottom = message.getValueS32("bottom"); + + // The plugin is likely to have top and bottom switched, due to vertical flip and OpenGL coordinate confusion. + // If they're backwards, swap them. + if(newDirtyRect.mTop < newDirtyRect.mBottom) + { + S32 temp = newDirtyRect.mTop; + newDirtyRect.mTop = newDirtyRect.mBottom; + newDirtyRect.mBottom = temp; + } + + if(mDirtyRect.isNull()) + { + mDirtyRect = newDirtyRect; + } + else + { + mDirtyRect.unionWith(newDirtyRect); + } + + LL_DEBUGS("Plugin") << "adjusted incoming rect is: (" + << newDirtyRect.mLeft << ", " + << newDirtyRect.mTop << ", " + << newDirtyRect.mRight << ", " + << newDirtyRect.mBottom << "), new dirty rect is: (" + << mDirtyRect.mLeft << ", " + << mDirtyRect.mTop << ", " + << mDirtyRect.mRight << ", " + << mDirtyRect.mBottom << ")" + << LL_ENDL; + + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CONTENT_UPDATED); + } + + + bool time_duration_updated = false; + int previous_percent = mProgressPercent; + + if(message.hasValue("current_time")) + { + mCurrentTime = message.getValueReal("current_time"); + time_duration_updated = true; + } + if(message.hasValue("duration")) + { + mDuration = message.getValueReal("duration"); + time_duration_updated = true; + } + + if(message.hasValue("current_rate")) + { + mCurrentRate = message.getValueReal("current_rate"); + } + + if(message.hasValue("loaded_duration")) + { + mLoadedDuration = message.getValueReal("loaded_duration"); + time_duration_updated = true; + } + else + { + // If the message doesn't contain a loaded_duration param, assume it's equal to duration + mLoadedDuration = mDuration; + } + + // Calculate a percentage based on the loaded duration and total duration. + if(mDuration != 0.0f) // Don't divide by zero. + { + mProgressPercent = (int)((mLoadedDuration * 100.0f)/mDuration); + } + + if(time_duration_updated) + { + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED); + } + + if(previous_percent != mProgressPercent) + { + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED); + } + } + else if(message_name == "media_status") + { + std::string status = message.getValue("status"); + + LL_DEBUGS("Plugin") << "Status changed to: " << status << LL_ENDL; + + if(status == "loading") + { + mStatus = LLPluginClassMediaOwner::MEDIA_LOADING; + } + else if(status == "loaded") + { + mStatus = LLPluginClassMediaOwner::MEDIA_LOADED; + } + else if(status == "error") + { + mStatus = LLPluginClassMediaOwner::MEDIA_ERROR; + } + else if(status == "playing") + { + mStatus = LLPluginClassMediaOwner::MEDIA_PLAYING; + } + else if(status == "paused") + { + mStatus = LLPluginClassMediaOwner::MEDIA_PAUSED; + } + else if(status == "done") + { + mStatus = LLPluginClassMediaOwner::MEDIA_DONE; + } + else + { + // empty string or any unknown string + mStatus = LLPluginClassMediaOwner::MEDIA_NONE; + } + } + else if(message_name == "size_change_request") + { + S32 width = message.getValueS32("width"); + S32 height = message.getValueS32("height"); + std::string name = message.getValue("name"); + + // TODO: check that name matches? + mNaturalMediaWidth = width; + mNaturalMediaHeight = height; + + setSizeInternal(); + } + else if(message_name == "size_change_response") + { + std::string name = message.getValue("name"); + + // TODO: check that name matches? + + mTextureWidth = message.getValueS32("texture_width"); + mTextureHeight = message.getValueS32("texture_height"); + mMediaWidth = message.getValueS32("width"); + mMediaHeight = message.getValueS32("height"); + + // This invalidates any existing dirty rect. + resetDirty(); + + // TODO: should we verify that the plugin sent back the right values? + // Two size changes in a row may cause them to not match, due to queueing, etc. + + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_SIZE_CHANGED); + } + else if(message_name == "cursor_changed") + { + mCursorName = message.getValue("name"); + + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CURSOR_CHANGED); + } + else if(message_name == "edit_state") + { + if(message.hasValue("cut")) + { + mCanCut = message.getValueBoolean("cut"); + } + if(message.hasValue("copy")) + { + mCanCopy = message.getValueBoolean("copy"); + } + if(message.hasValue("paste")) + { + mCanPaste = message.getValueBoolean("paste"); + } + } + else if(message_name == "name_text") + { + mMediaName = message.getValue("name"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED); + } + else + { + LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) + { + std::string message_name = message.getName(); + if(message_name == "navigate_begin") + { + mNavigateURI = message.getValue("uri"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_BEGIN); + } + else if(message_name == "navigate_complete") + { + mNavigateURI = message.getValue("uri"); + mNavigateResultCode = message.getValueS32("result_code"); + mNavigateResultString = message.getValue("result_string"); + mHistoryBackAvailable = message.getValueBoolean("history_back_available"); + mHistoryForwardAvailable = message.getValueBoolean("history_forward_available"); + + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE); + } + else if(message_name == "progress") + { + mProgressPercent = message.getValueS32("percent"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED); + } + else if(message_name == "status_text") + { + mStatusText = message.getValue("status"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_STATUS_TEXT_CHANGED); + } + else if(message_name == "location_changed") + { + mLocation = message.getValue("uri"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LOCATION_CHANGED); + } + else if(message_name == "click_href") + { + mClickURL = message.getValue("uri"); + mClickTarget = message.getValue("target"); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); + } + else if(message_name == "click_nofollow") + { + mClickURL = message.getValue("uri"); + mClickTarget.clear(); + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); + } + else + { + LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + std::string message_name = message.getName(); + + // This class hasn't defined any incoming messages yet. +// if(message_name == "message_name") +// { +// } +// else + { + LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; + } + } + +} + +/* virtual */ +void LLPluginClassMedia::pluginLaunchFailed() +{ + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH); +} + +/* virtual */ +void LLPluginClassMedia::pluginDied() +{ + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED); +} + +void LLPluginClassMedia::mediaEvent(LLPluginClassMediaOwner::EMediaEvent event) +{ + if(mOwner) + { + mOwner->handleMediaEvent(this, event); + } +} + +void LLPluginClassMedia::sendMessage(const LLPluginMessage &message) +{ + if(mPlugin && mPlugin->isRunning()) + { + mPlugin->sendMessage(message); + } + else + { + // The plugin isn't set up yet -- queue this message to be sent after initialization. + mSendQueue.push(message); + } +} + +//////////////////////////////////////////////////////////// +// MARK: media_browser class functions +bool LLPluginClassMedia::pluginSupportsMediaBrowser(void) +{ + std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER); + return !version.empty(); +} + +void LLPluginClassMedia::focus(bool focused) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus"); + + message.setValueBoolean("focused", focused); + + sendMessage(message); +} + +void LLPluginClassMedia::clear_cache() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cache"); + sendMessage(message); +} + +void LLPluginClassMedia::clear_cookies() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cookies"); + sendMessage(message); +} + +void LLPluginClassMedia::enable_cookies(bool enable) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies"); + sendMessage(message); +} + +void LLPluginClassMedia::proxy_setup(bool enable, const std::string &host, int port) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_setup"); + + message.setValueBoolean("enable", enable); + message.setValue("host", host); + message.setValueS32("port", port); + + sendMessage(message); +} + +void LLPluginClassMedia::browse_stop() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_stop"); + sendMessage(message); +} + +void LLPluginClassMedia::browse_reload(bool ignore_cache) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_reload"); + + message.setValueBoolean("ignore_cache", ignore_cache); + + sendMessage(message); +} + +void LLPluginClassMedia::browse_forward() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_forward"); + sendMessage(message); +} + +void LLPluginClassMedia::browse_back() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_back"); + sendMessage(message); +} + +void LLPluginClassMedia::set_status_redirect(int code, const std::string &url) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_status_redirect"); + + message.setValueS32("code", code); + message.setValue("url", url); + + sendMessage(message); +} + +void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_user_agent"); + + message.setValue("user_agent", user_agent); + + sendMessage(message); +} + +void LLPluginClassMedia::crashPlugin() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash"); + + sendMessage(message); +} + +void LLPluginClassMedia::hangPlugin() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hang"); + + sendMessage(message); +} + + +//////////////////////////////////////////////////////////// +// MARK: media_time class functions +bool LLPluginClassMedia::pluginSupportsMediaTime(void) +{ + std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME); + return !version.empty(); +} + +void LLPluginClassMedia::stop() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "stop"); + sendMessage(message); +} + +void LLPluginClassMedia::start(float rate) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "start"); + + message.setValueReal("rate", rate); + + sendMessage(message); +} + +void LLPluginClassMedia::pause() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "pause"); + sendMessage(message); +} + +void LLPluginClassMedia::seek(float time) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek"); + + message.setValueReal("time", time); + + sendMessage(message); +} + +void LLPluginClassMedia::setLoop(bool loop) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_loop"); + + message.setValueBoolean("loop", loop); + + sendMessage(message); +} + +void LLPluginClassMedia::setVolume(float volume) +{ + if(volume != mRequestedVolume) + { + mRequestedVolume = volume; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_volume"); + + message.setValueReal("volume", volume); + + sendMessage(message); + } +} + +float LLPluginClassMedia::getVolume() +{ + return mRequestedVolume; +} + +void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history) +{ + // Send URL history to plugin + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "init_history"); + message.setValueLLSD("history", url_history); + sendMessage(message); + + LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL; +} + diff --git a/linden/indra/llplugin/llpluginclassmedia.h b/linden/indra/llplugin/llpluginclassmedia.h new file mode 100644 index 000000000..c45010e82 --- /dev/null +++ b/linden/indra/llplugin/llpluginclassmedia.h @@ -0,0 +1,352 @@ +/** + * @file llpluginclassmedia.h + * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINCLASSMEDIA_H +#define LL_LLPLUGINCLASSMEDIA_H + +#include "llgltypes.h" +#include "llpluginprocessparent.h" +#include "llrect.h" +#include "llpluginclassmediaowner.h" +#include + + +class LLPluginClassMedia : public LLPluginProcessParentOwner +{ + LOG_CLASS(LLPluginClassMedia); +public: + LLPluginClassMedia(LLPluginClassMediaOwner *owner); + virtual ~LLPluginClassMedia(); + + // local initialization, called by the media manager when creating a source + virtual bool init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path); + + // undoes everything init() didm called by the media manager when destroying a source + virtual void reset(); + + void idle(void); + + // All of these may return 0 or an actual valid value. + // Callers need to check the return for 0, and not use the values in that case. + int getWidth() const { return (mMediaWidth > 0) ? mMediaWidth : 0; }; + int getHeight() const { return (mMediaHeight > 0) ? mMediaHeight : 0; }; + int getNaturalWidth() const { return mNaturalMediaWidth; }; + int getNaturalHeight() const { return mNaturalMediaHeight; }; + int getSetWidth() const { return mSetMediaWidth; }; + int getSetHeight() const { return mSetMediaHeight; }; + int getBitsWidth() const { return (mTextureWidth > 0) ? mTextureWidth : 0; }; + int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; }; + int getTextureWidth() const; + int getTextureHeight() const; + int getFullWidth() const { return mFullMediaWidth; }; + int getFullHeight() const { return mFullMediaHeight; }; + + // This may return NULL. Callers need to check for and handle this case. + unsigned char* getBitsData(); + + // gets the format details of the texture data + // These may return 0 if they haven't been set up yet. The caller needs to detect this case. + int getTextureDepth() const { return mRequestedTextureDepth; }; + int getTextureFormatInternal() const { return mRequestedTextureInternalFormat; }; + int getTextureFormatPrimary() const { return mRequestedTextureFormat; }; + int getTextureFormatType() const { return mRequestedTextureType; }; + bool getTextureFormatSwapBytes() const { return mRequestedTextureSwapBytes; }; + bool getTextureCoordsOpenGL() const { return mRequestedTextureCoordsOpenGL; }; + + void setSize(int width, int height); + void setAutoScale(bool auto_scale); + + // Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent. + // This will initially be false, and will also be false for some time after setSize while the resize is processed. + // Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values + // until you call idle() again. + bool textureValid(void); + + bool getDirty(LLRect *dirty_rect = NULL); + void resetDirty(void); + + typedef enum + { + MOUSE_EVENT_DOWN, + MOUSE_EVENT_UP, + MOUSE_EVENT_MOVE, + MOUSE_EVENT_DOUBLE_CLICK + }EMouseEventType; + + void mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers); + + typedef enum + { + KEY_EVENT_DOWN, + KEY_EVENT_UP, + KEY_EVENT_REPEAT + }EKeyEventType; + + bool keyEvent(EKeyEventType type, int key_code, MASK modifiers); + + void scrollEvent(int x, int y, MASK modifiers); + + // Text may be unicode (utf8 encoded) + bool textInput(const std::string &text, MASK modifiers); + + void loadURI(const std::string &uri); + + // "Loading" means uninitialized or any state prior to fully running (processing commands) + bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; }; + + // "Running" means the steady state -- i.e. processing messages + bool isPluginRunning(void) { return mPlugin?mPlugin->isRunning():false; }; + + // "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally) + bool isPluginExited(void) { return mPlugin?mPlugin->isDone():false; }; + + std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); }; + + bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; }; + void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); }; + + // Inherited from LLPluginProcessParentOwner + /* virtual */ void receivePluginMessage(const LLPluginMessage &message); + /* virtual */ void pluginLaunchFailed(); + /* virtual */ void pluginDied(); + + + typedef enum + { + PRIORITY_UNLOADED, // media plugin isn't even loaded. + PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all. + PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc. + PRIORITY_SLIDESHOW, // media is in the far distance, updates very infrequently + PRIORITY_LOW, // media is in the distance, may be rendered at reduced size + PRIORITY_NORMAL, // normal (default) priority + PRIORITY_HIGH // media has user focus and/or is taking up most of the screen + }EPriority; + + static const char* priorityToString(EPriority priority); + void setPriority(EPriority priority); + void setLowPrioritySizeLimit(int size); + + F64 getCPUUsage(); + + // Valid after a MEDIA_EVENT_CURSOR_CHANGED event + std::string getCursorName() const { return mCursorName; }; + + LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; } + + void cut(); + bool canCut() const { return mCanCut; }; + + void copy(); + bool canCopy() const { return mCanCopy; }; + + void paste(); + bool canPaste() const { return mCanPaste; }; + + /////////////////////////////////// + // media browser class functions + bool pluginSupportsMediaBrowser(void); + + void focus(bool focused); + void clear_cache(); + void clear_cookies(); + void enable_cookies(bool enable); + void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0); + void browse_stop(); + void browse_reload(bool ignore_cache = false); + void browse_forward(); + void browse_back(); + void set_status_redirect(int code, const std::string &url); + void setBrowserUserAgent(const std::string& user_agent); + + // This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE + std::string getNavigateURI() const { return mNavigateURI; }; + + // These are valid after MEDIA_EVENT_NAVIGATE_COMPLETE + S32 getNavigateResultCode() const { return mNavigateResultCode; }; + std::string getNavigateResultString() const { return mNavigateResultString; }; + bool getHistoryBackAvailable() const { return mHistoryBackAvailable; }; + bool getHistoryForwardAvailable() const { return mHistoryForwardAvailable; }; + + // This is valid after MEDIA_EVENT_PROGRESS_UPDATED + int getProgressPercent() const { return mProgressPercent; }; + + // This is valid after MEDIA_EVENT_STATUS_TEXT_CHANGED + std::string getStatusText() const { return mStatusText; }; + + // This is valid after MEDIA_EVENT_LOCATION_CHANGED + std::string getLocation() const { return mLocation; }; + + // This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW + std::string getClickURL() const { return mClickURL; }; + + // This is valid after MEDIA_EVENT_CLICK_LINK_HREF + std::string getClickTarget() const { return mClickTarget; }; + + std::string getMediaName() const { return mMediaName; }; + std::string getMediaDescription() const { return mMediaDescription; }; + + // Crash the plugin. If you use this outside of a testbed, you will be punished. + void crashPlugin(); + + // Hang the plugin. If you use this outside of a testbed, you will be punished. + void hangPlugin(); + + /////////////////////////////////// + // media time class functions + bool pluginSupportsMediaTime(void); + void stop(); + void start(float rate = 0.0f); + void pause(); + void seek(float time); + void setLoop(bool loop); + void setVolume(float volume); + float getVolume(); + + F64 getCurrentTime(void) const { return mCurrentTime; }; + F64 getDuration(void) const { return mDuration; }; + F64 getCurrentPlayRate(void) { return mCurrentRate; }; + F64 getLoadedDuration(void) const { return mLoadedDuration; }; + + // Initialize the URL history of the plugin by sending + // "init_history" message + void initializeUrlHistory(const LLSD& url_history); + +protected: + + LLPluginClassMediaOwner *mOwner; + + // Notify this object's owner that an event has occurred. + void mediaEvent(LLPluginClassMediaOwner::EMediaEvent event); + + void sendMessage(const LLPluginMessage &message); // Send message internally, either queueing or sending directly. + std::queue mSendQueue; // Used to queue messages while the plugin initializes. + + void setSizeInternal(void); + + bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true + S32 mRequestedTextureDepth; + LLGLenum mRequestedTextureInternalFormat; + LLGLenum mRequestedTextureFormat; + LLGLenum mRequestedTextureType; + bool mRequestedTextureSwapBytes; + bool mRequestedTextureCoordsOpenGL; + + std::string mTextureSharedMemoryName; + size_t mTextureSharedMemorySize; + + // True to scale requested media up to the full size of the texture (i.e. next power of two) + bool mAutoScaleMedia; + + // default media size for the plugin, from the texture_params message. + int mDefaultMediaWidth; + int mDefaultMediaHeight; + + // Size that has been requested by the plugin itself + int mNaturalMediaWidth; + int mNaturalMediaHeight; + + // Size that has been requested with setSize() + int mSetMediaWidth; + int mSetMediaHeight; + + // Full calculated media size (before auto-scale and downsample calculations) + int mFullMediaWidth; + int mFullMediaHeight; + + // Actual media size being set (after auto-scale) + int mRequestedMediaWidth; + int mRequestedMediaHeight; + + // Texture size calculated from actual media size + int mRequestedTextureWidth; + int mRequestedTextureHeight; + + // Size that the plugin has acknowledged + int mTextureWidth; + int mTextureHeight; + int mMediaWidth; + int mMediaHeight; + + float mRequestedVolume; + + // Priority of this media stream + EPriority mPriority; + int mLowPrioritySizeLimit; + + bool mAllowDownsample; + int mPadding; + + + LLPluginProcessParent *mPlugin; + + LLRect mDirtyRect; + + std::string translateModifiers(MASK modifiers); + + std::string mCursorName; + int mLastMouseX; + int mLastMouseY; + + LLPluginClassMediaOwner::EMediaStatus mStatus; + + F64 mSleepTime; + + bool mCanCut; + bool mCanCopy; + bool mCanPaste; + + std::string mMediaName; + std::string mMediaDescription; + + ///////////////////////////////////////// + // media_browser class + std::string mNavigateURI; + S32 mNavigateResultCode; + std::string mNavigateResultString; + bool mHistoryBackAvailable; + bool mHistoryForwardAvailable; + std::string mStatusText; + int mProgressPercent; + std::string mLocation; + std::string mClickURL; + std::string mClickTarget; + + ///////////////////////////////////////// + // media_time class + F64 mCurrentTime; + F64 mDuration; + F64 mCurrentRate; + F64 mLoadedDuration; + +}; + +#endif // LL_LLPLUGINCLASSMEDIA_H diff --git a/linden/indra/llplugin/llpluginclassmediaowner.h b/linden/indra/llplugin/llpluginclassmediaowner.h new file mode 100644 index 000000000..182eb92d3 --- /dev/null +++ b/linden/indra/llplugin/llpluginclassmediaowner.h @@ -0,0 +1,82 @@ +/** + * @file llpluginclassmediaowner.h + * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINCLASSMEDIAOWNER_H +#define LL_LLPLUGINCLASSMEDIAOWNER_H + +#include "llpluginprocessparent.h" +#include "llrect.h" +#include + +class LLPluginClassMedia; + +class LLPluginClassMediaOwner +{ +public: + typedef enum + { + MEDIA_EVENT_CONTENT_UPDATED, // contents/dirty rect have updated + MEDIA_EVENT_TIME_DURATION_UPDATED, // current time and/or duration have updated + MEDIA_EVENT_SIZE_CHANGED, // media size has changed + MEDIA_EVENT_CURSOR_CHANGED, // plugin has requested a cursor change + + MEDIA_EVENT_NAVIGATE_BEGIN, // browser has begun navigation + MEDIA_EVENT_NAVIGATE_COMPLETE, // browser has finished navigation + MEDIA_EVENT_PROGRESS_UPDATED, // browser has updated loading progress + MEDIA_EVENT_STATUS_TEXT_CHANGED, // browser has updated the status text + MEDIA_EVENT_NAME_CHANGED, // browser has updated the name of the media (typically tag) + MEDIA_EVENT_LOCATION_CHANGED, // browser location (URL) has changed (maybe due to internal navagation/frames/etc) + MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are + MEDIA_EVENT_CLICK_LINK_NOFOLLOW, + + MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch + MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly + + } EMediaEvent; + + typedef enum + { + MEDIA_NONE, // Uninitialized -- no useful state + MEDIA_LOADING, // loading or navigating + MEDIA_LOADED, // navigation/preroll complete + MEDIA_ERROR, // navigation/preroll failed + MEDIA_PLAYING, // playing (only for time-based media) + MEDIA_PAUSED, // paused (only for time-based media) + MEDIA_DONE // finished playing (only for time-based media) + + } EMediaStatus; + + virtual ~LLPluginClassMediaOwner() {}; + virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {}; +}; + +#endif // LL_LLPLUGINCLASSMEDIAOWNER_H diff --git a/linden/indra/llplugin/llplugininstance.cpp b/linden/indra/llplugin/llplugininstance.cpp new file mode 100644 index 000000000..5185b3659 --- /dev/null +++ b/linden/indra/llplugin/llplugininstance.cpp @@ -0,0 +1,172 @@ +/** + * @file llplugininstance.cpp + * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llplugininstance.h" + +#include "llapr.h" + +/** Virtual destructor. */ +LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() +{ +} + +/** + * TODO:DOC describe how it's used + */ +const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoint"; + +/** + * Constructor. + * + * @param[in] owner Plugin instance. TODO:DOC is this a good description of what "owner" is? + */ +LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) : + mDSOHandle(NULL), + mPluginUserData(NULL), + mPluginSendMessageFunction(NULL) +{ + mOwner = owner; +} + +/** + * Destructor. + */ +LLPluginInstance::~LLPluginInstance() +{ + if(mDSOHandle != NULL) + { + apr_dso_unload(mDSOHandle); + mDSOHandle = NULL; + } +} + +/** + * Dynamically loads the plugin and runs the plugin's init function. + * + * @param[in] plugin_file Name of plugin dll/dylib/so. TODO:DOC is this correct? see .h + * @return 0 if successful, APR error code or error code from the plugin's init function on failure. + */ +int LLPluginInstance::load(std::string &plugin_file) +{ + pluginInitFunction init_function = NULL; + + int result = apr_dso_load(&mDSOHandle, + plugin_file.c_str(), + gAPRPoolp); + if(result != APR_SUCCESS) + { + char buf[1024]; + apr_dso_error(mDSOHandle, buf, sizeof(buf)); + + LL_WARNS("Plugin") << "apr_dso_load of " << plugin_file << " failed with error " << result << " , additional info string: " << buf << LL_ENDL; + + } + + if(result == APR_SUCCESS) + { + result = apr_dso_sym((apr_dso_handle_sym_t*)&init_function, + mDSOHandle, + PLUGIN_INIT_FUNCTION_NAME); + + if(result != APR_SUCCESS) + { + LL_WARNS("Plugin") << "apr_dso_sym failed with error " << result << LL_ENDL; + } + } + + if(result == APR_SUCCESS) + { + result = init_function(staticReceiveMessage, (void*)this, &mPluginSendMessageFunction, &mPluginUserData); + + if(result != APR_SUCCESS) + { + LL_WARNS("Plugin") << "call to init function failed with error " << result << LL_ENDL; + } + } + + return (int)result; +} + +/** + * Sends a message to the plugin. + * + * @param[in] message Message + */ +void LLPluginInstance::sendMessage(const std::string &message) +{ + if(mPluginSendMessageFunction) + { + LL_DEBUGS("Plugin") << "sending message to plugin: \"" << message << "\"" << LL_ENDL; + mPluginSendMessageFunction(message.c_str(), &mPluginUserData); + } + else + { + LL_WARNS("Plugin") << "dropping message: \"" << message << "\"" << LL_ENDL; + } +} + +/** + * Idle. TODO:DOC what's the purpose of this? + * + */ +void LLPluginInstance::idle(void) +{ +} + +// static +void LLPluginInstance::staticReceiveMessage(const char *message_string, void **user_data) +{ + // TODO: validate that the user_data argument is still a valid LLPluginInstance pointer + // we could also use a key that's looked up in a map (instead of a direct pointer) for safety, but that's probably overkill + LLPluginInstance *self = (LLPluginInstance*)*user_data; + self->receiveMessage(message_string); +} + +/** + * Plugin receives message from plugin loader shell. + * + * @param[in] message_string Message + */ +void LLPluginInstance::receiveMessage(const char *message_string) +{ + if(mOwner) + { + LL_DEBUGS("Plugin") << "processing incoming message: \"" << message_string << "\"" << LL_ENDL; + mOwner->receivePluginMessage(message_string); + } + else + { + LL_WARNS("Plugin") << "dropping incoming message: \"" << message_string << "\"" << LL_ENDL; + } +} diff --git a/linden/indra/llplugin/llplugininstance.h b/linden/indra/llplugin/llplugininstance.h new file mode 100644 index 000000000..0b53b5fe4 --- /dev/null +++ b/linden/indra/llplugin/llplugininstance.h @@ -0,0 +1,104 @@ +/** + * @file llplugininstance.h + * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGININSTANCE_H +#define LL_LLPLUGININSTANCE_H + +#include "llstring.h" +#include "llapr.h" + +#include "apr_dso.h" + +/** + * @brief LLPluginInstanceMessageListener receives messages sent from the plugin loader shell to the plugin. + */ +class LLPluginInstanceMessageListener +{ +public: + virtual ~LLPluginInstanceMessageListener(); + /** Plugin receives message from plugin loader shell. */ + virtual void receivePluginMessage(const std::string &message) = 0; +}; + +/** + * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing. + */ +class LLPluginInstance +{ + LOG_CLASS(LLPluginInstance); +public: + LLPluginInstance(LLPluginInstanceMessageListener *owner); + virtual ~LLPluginInstance(); + + // Load a plugin dll/dylib/so + // Returns 0 if successful, APR error code or error code returned from the plugin's init function on failure. + int load(std::string &plugin_file); + + // Sends a message to the plugin. + void sendMessage(const std::string &message); + + // TODO:DOC is this comment obsolete? can't find "send_count" anywhere in indra tree. + // send_count is the maximum number of message to process from the send queue. If negative, it will drain the queue completely. + // The receive queue is always drained completely. + // Returns the total number of messages processed from both queues. + void idle(void); + + /** The signature of the function for sending a message from plugin to plugin loader shell. + * + * @param[in] message_string Null-terminated C string + * @param[in] user_data The opaque reference that the callee supplied during setup. + */ + typedef void (*sendMessageFunction) (const char *message_string, void **user_data); + + /** The signature of the plugin init function. TODO:DOC check direction (pluging loader shell to plugin?) + * + * @param[in] host_user_data Data from plugin loader shell. + * @param[in] plugin_send_function Function for sending from the plugin loader shell to plugin. + */ + typedef int (*pluginInitFunction) (sendMessageFunction host_send_func, void *host_user_data, sendMessageFunction *plugin_send_func, void **plugin_user_data); + + /** Name of plugin init function */ + static const char *PLUGIN_INIT_FUNCTION_NAME; + +private: + static void staticReceiveMessage(const char *message_string, void **user_data); + void receiveMessage(const char *message_string); + + apr_dso_handle_t *mDSOHandle; + + void *mPluginUserData; + sendMessageFunction mPluginSendMessageFunction; + + LLPluginInstanceMessageListener *mOwner; +}; + +#endif // LL_LLPLUGININSTANCE_H diff --git a/linden/indra/llplugin/llpluginmessage.cpp b/linden/indra/llplugin/llpluginmessage.cpp new file mode 100644 index 000000000..67ac99572 --- /dev/null +++ b/linden/indra/llplugin/llpluginmessage.cpp @@ -0,0 +1,442 @@ +/** + * @file llpluginmessage.cpp + * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llpluginmessage.h" +#include "llsdserialize.h" +#include "u64.h" + +/** + * Constructor. + */ +LLPluginMessage::LLPluginMessage() +{ +} + +/** + * Constructor. + * + * @param[in] p Existing message + */ +LLPluginMessage::LLPluginMessage(const LLPluginMessage &p) +{ + mMessage = p.mMessage; +} + +/** + * Constructor. + * + * @param[in] message_class Message class + * @param[in] message_name Message name + */ +LLPluginMessage::LLPluginMessage(const std::string &message_class, const std::string &message_name) +{ + setMessage(message_class, message_name); +} + + +/** + * Destructor. + */ +LLPluginMessage::~LLPluginMessage() +{ +} + +/** + * Reset all internal state. + */ +void LLPluginMessage::clear() +{ + mMessage = LLSD::emptyMap(); + mMessage["params"] = LLSD::emptyMap(); +} + +/** + * Sets the message class and name. Also has the side-effect of clearing any key-value pairs in the message. + * + * @param[in] message_class Message class + * @param[in] message_name Message name + */ +void LLPluginMessage::setMessage(const std::string &message_class, const std::string &message_name) +{ + clear(); + mMessage["class"] = message_class; + mMessage["name"] = message_name; +} + +/** + * Sets a key/value pair in the message, where the value is a string. + * + * @param[in] key Key + * @param[in] value String value + */ +void LLPluginMessage::setValue(const std::string &key, const std::string &value) +{ + mMessage["params"][key] = value; +} + +/** + * Sets a key/value pair in the message, where the value is LLSD. + * + * @param[in] key Key + * @param[in] value LLSD value + */ +void LLPluginMessage::setValueLLSD(const std::string &key, const LLSD &value) +{ + mMessage["params"][key] = value; +} + +/** + * Sets a key/value pair in the message, where the value is signed 32-bit. + * + * @param[in] key Key + * @param[in] value 32-bit signed value + */ +void LLPluginMessage::setValueS32(const std::string &key, S32 value) +{ + mMessage["params"][key] = value; +} + +/** + * Sets a key/value pair in the message, where the value is unsigned 32-bit. The value is stored as a string beginning with "0x". + * + * @param[in] key Key + * @param[in] value 32-bit unsigned value + */ +void LLPluginMessage::setValueU32(const std::string &key, U32 value) +{ + std::stringstream temp; + temp << "0x" << std::hex << value; + setValue(key, temp.str()); +} + +/** + * Sets a key/value pair in the message, where the value is a bool. + * + * @param[in] key Key + * @param[in] value Boolean value + */ +void LLPluginMessage::setValueBoolean(const std::string &key, bool value) +{ + mMessage["params"][key] = value; +} + +/** + * Sets a key/value pair in the message, where the value is a double. + * + * @param[in] key Key + * @param[in] value Boolean value + */ +void LLPluginMessage::setValueReal(const std::string &key, F64 value) +{ + mMessage["params"][key] = value; +} + +/** + * Sets a key/value pair in the message, where the value is a pointer. The pointer is stored as a string. + * + * @param[in] key Key + * @param[in] value Pointer value + */ +void LLPluginMessage::setValuePointer(const std::string &key, void* value) +{ + std::stringstream temp; + // iostreams should output pointer values in hex with an initial 0x by default. + temp << value; + setValue(key, temp.str()); +} + +/** + * Gets the message class. + * + * @return Message class + */ +std::string LLPluginMessage::getClass(void) const +{ + return mMessage["class"]; +} + +/** + * Gets the message name. + * + * @return Message name + */ +std::string LLPluginMessage::getName(void) const +{ + return mMessage["name"]; +} + +/** + * Returns true if the specified key exists in this message (useful for optional parameters). + * + * @param[in] key Key + * + * @return True if key exists, false otherwise. + */ +bool LLPluginMessage::hasValue(const std::string &key) const +{ + bool result = false; + + if(mMessage["params"].has(key)) + { + result = true; + } + + return result; +} + +/** + * Gets the value of a key as a string. If the key does not exist, an empty string will be returned. + * + * @param[in] key Key + * + * @return String value of key if key exists, empty string if key does not exist. + */ +std::string LLPluginMessage::getValue(const std::string &key) const +{ + std::string result; + + if(mMessage["params"].has(key)) + { + result = mMessage["params"][key].asString(); + } + + return result; +} + +/** + * Gets the value of a key as LLSD. If the key does not exist, a null LLSD will be returned. + * + * @param[in] key Key + * + * @return LLSD value of key if key exists, null LLSD if key does not exist. + */ +LLSD LLPluginMessage::getValueLLSD(const std::string &key) const +{ + LLSD result; + + if(mMessage["params"].has(key)) + { + result = mMessage["params"][key]; + } + + return result; +} + +/** + * Gets the value of a key as signed 32-bit int. If the key does not exist, 0 will be returned. + * + * @param[in] key Key + * + * @return Signed 32-bit int value of key if key exists, 0 if key does not exist. + */ +S32 LLPluginMessage::getValueS32(const std::string &key) const +{ + S32 result = 0; + + if(mMessage["params"].has(key)) + { + result = mMessage["params"][key].asInteger(); + } + + return result; +} + +/** + * Gets the value of a key as unsigned 32-bit int. If the key does not exist, 0 will be returned. + * + * @param[in] key Key + * + * @return Unsigned 32-bit int value of key if key exists, 0 if key does not exist. + */ +U32 LLPluginMessage::getValueU32(const std::string &key) const +{ + U32 result = 0; + + if(mMessage["params"].has(key)) + { + std::string value = mMessage["params"][key].asString(); + + result = (U32)strtoul(value.c_str(), NULL, 16); + } + + return result; +} + +/** + * Gets the value of a key as a bool. If the key does not exist, false will be returned. + * + * @param[in] key Key + * + * @return Boolean value of key if it exists, false otherwise. + */ +bool LLPluginMessage::getValueBoolean(const std::string &key) const +{ + bool result = false; + + if(mMessage["params"].has(key)) + { + result = mMessage["params"][key].asBoolean(); + } + + return result; +} + +/** + * Gets the value of a key as a double. If the key does not exist, 0 will be returned. + * + * @param[in] key Key + * + * @return Value as a double if key exists, 0 otherwise. + */ +F64 LLPluginMessage::getValueReal(const std::string &key) const +{ + F64 result = 0.0f; + + if(mMessage["params"].has(key)) + { + result = mMessage["params"][key].asReal(); + } + + return result; +} + +/** + * Gets the value of a key as a pointer. If the key does not exist, NULL will be returned. + * + * @param[in] key Key + * + * @return Pointer value if key exists, NULL otherwise. + */ +void* LLPluginMessage::getValuePointer(const std::string &key) const +{ + void* result = NULL; + + if(mMessage["params"].has(key)) + { + std::string value = mMessage["params"][key].asString(); + + result = (void*)llstrtou64(value.c_str(), NULL, 16); + } + + return result; +} + +/** + * Flatten the message into a string. + * + * @return Message as a string. + */ +std::string LLPluginMessage::generate(void) const +{ + std::ostringstream result; + + // Pretty XML may be slightly easier to deal with while debugging... +// LLSDSerialize::toXML(mMessage, result); + LLSDSerialize::toPrettyXML(mMessage, result); + + return result.str(); +} + +/** + * Parse an incoming message into component parts. Clears all existing state before starting the parse. + * + * @return Returns -1 on failure, otherwise returns the number of key/value pairs in the incoming message. + */ +int LLPluginMessage::parse(const std::string &message) +{ + // clear any previous state + clear(); + + std::istringstream input(message); + + S32 parse_result = LLSDSerialize::fromXML(mMessage, input); + + return (int)parse_result; +} + + +/** + * Destructor + */ +LLPluginMessageListener::~LLPluginMessageListener() +{ + // TODO: should listeners have a way to ensure they're removed from dispatcher lists when deleted? +} + + +/** + * Destructor + */ +LLPluginMessageDispatcher::~LLPluginMessageDispatcher() +{ + +} + +/** + * Add a message listener. TODO:DOC need more info on what uses this. when are multiple listeners needed? + * + * @param[in] listener Message listener + */ +void LLPluginMessageDispatcher::addPluginMessageListener(LLPluginMessageListener *listener) +{ + mListeners.insert(listener); +} + +/** + * Remove a message listener. + * + * @param[in] listener Message listener + */ +void LLPluginMessageDispatcher::removePluginMessageListener(LLPluginMessageListener *listener) +{ + mListeners.erase(listener); +} + +/** + * Distribute a message to all message listeners. + * + * @param[in] message Message + */ +void LLPluginMessageDispatcher::dispatchPluginMessage(const LLPluginMessage &message) +{ + for (listener_set_t::iterator it = mListeners.begin(); + it != mListeners.end(); + ) + { + LLPluginMessageListener* listener = *it; + listener->receivePluginMessage(message); + // In case something deleted an entry. + it = mListeners.upper_bound(listener); + } +} diff --git a/linden/indra/llplugin/llpluginmessage.h b/linden/indra/llplugin/llpluginmessage.h new file mode 100644 index 000000000..8bcb8960f --- /dev/null +++ b/linden/indra/llplugin/llpluginmessage.h @@ -0,0 +1,142 @@ +/** + * @file llpluginmessage.h + * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINMESSAGE_H +#define LL_LLPLUGINMESSAGE_H + +#include "llsd.h" + +/** + * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins. + */ +class LLPluginMessage +{ + LOG_CLASS(LLPluginMessage); +public: + LLPluginMessage(); + LLPluginMessage(const LLPluginMessage &p); + LLPluginMessage(const std::string &message_class, const std::string &message_name); + ~LLPluginMessage(); + + // reset all internal state + void clear(void); + + // Sets the message class and name + // Also has the side-effect of clearing any key/value pairs in the message. + void setMessage(const std::string &message_class, const std::string &message_name); + + // Sets a key/value pair in the message + void setValue(const std::string &key, const std::string &value); + void setValueLLSD(const std::string &key, const LLSD &value); + void setValueS32(const std::string &key, S32 value); + void setValueU32(const std::string &key, U32 value); + void setValueBoolean(const std::string &key, bool value); + void setValueReal(const std::string &key, F64 value); + void setValuePointer(const std::string &key, void *value); + + std::string getClass(void) const; + std::string getName(void) const; + + // Returns true if the specified key exists in this message (useful for optional parameters) + bool hasValue(const std::string &key) const; + + // get the value of a particular key as a string. If the key doesn't exist in the message, an empty string will be returned. + std::string getValue(const std::string &key) const; + + // get the value of a particular key as LLSD. If the key doesn't exist in the message, a null LLSD will be returned. + LLSD getValueLLSD(const std::string &key) const; + + // get the value of a key as a S32. If the value wasn't set as a S32, behavior is undefined. + S32 getValueS32(const std::string &key) const; + + // get the value of a key as a U32. Since there isn't an LLSD type for this, we use a hexadecimal string instead. + U32 getValueU32(const std::string &key) const; + + // get the value of a key as a Boolean. + bool getValueBoolean(const std::string &key) const; + + // get the value of a key as a float. + F64 getValueReal(const std::string &key) const; + + // get the value of a key as a pointer. + void* getValuePointer(const std::string &key) const; + + // Flatten the message into a string + std::string generate(void) const; + + // Parse an incoming message into component parts + // (this clears out all existing state before starting the parse) + // Returns -1 on failure, otherwise returns the number of key/value pairs in the message. + int parse(const std::string &message); + + +private: + + LLSD mMessage; + +}; + +/** + * @brief Listener for plugin messages. + */ +class LLPluginMessageListener +{ +public: + virtual ~LLPluginMessageListener(); + /** Plugin receives message from plugin loader shell. */ + virtual void receivePluginMessage(const LLPluginMessage &message) = 0; + +}; + +/** + * @brief Dispatcher for plugin messages. + * + * Manages the set of plugin message listeners and distributes messages to plugin message listeners. + */ +class LLPluginMessageDispatcher +{ +public: + virtual ~LLPluginMessageDispatcher(); + + void addPluginMessageListener(LLPluginMessageListener *); + void removePluginMessageListener(LLPluginMessageListener *); +protected: + void dispatchPluginMessage(const LLPluginMessage &message); + + /** A set of message listeners. */ + typedef std::set<LLPluginMessageListener*> listener_set_t; + /** The set of message listeners. */ + listener_set_t mListeners; +}; + + +#endif // LL_LLPLUGINMESSAGE_H diff --git a/linden/indra/llplugin/llpluginmessageclasses.h b/linden/indra/llplugin/llpluginmessageclasses.h new file mode 100644 index 000000000..1f60d5eb8 --- /dev/null +++ b/linden/indra/llplugin/llpluginmessageclasses.h @@ -0,0 +1,57 @@ +/** + * @file llpluginmessageclasses.h + * @brief This file defines the versions of existing message classes for LLPluginMessage. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINMESSAGECLASSES_H +#define LL_LLPLUGINMESSAGECLASSES_H + +// Version strings for each plugin message class. +// Backwards-compatible changes (i.e. changes which only add new messges) should increment the minor version (i.e. "1.0" -> "1.1"). +// Non-backwards-compatible changes (which delete messages or change their semantics) should increment the major version (i.e. "1.1" -> "2.0"). +// Plugins will supply the set of message classes they understand, with version numbers, as part of their init_response message. +// The contents and semantics of the base:init message must NEVER change in a non-backwards-compatible way, as a special case. + +#define LLPLUGIN_MESSAGE_CLASS_INTERNAL "internal" +#define LLPLUGIN_MESSAGE_CLASS_INTERNAL_VERSION "1.0" + +#define LLPLUGIN_MESSAGE_CLASS_BASE "base" +#define LLPLUGIN_MESSAGE_CLASS_BASE_VERSION "1.0" + +#define LLPLUGIN_MESSAGE_CLASS_MEDIA "media" +#define LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION "1.0" + +#define LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER "media_browser" +#define LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION "1.0" + +#define LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME "media_time" +#define LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION "1.0" + +#endif // LL_LLPLUGINMESSAGECLASSES_H diff --git a/linden/indra/llplugin/llpluginmessagepipe.cpp b/linden/indra/llplugin/llpluginmessagepipe.cpp new file mode 100644 index 000000000..209f49fe8 --- /dev/null +++ b/linden/indra/llplugin/llpluginmessagepipe.cpp @@ -0,0 +1,316 @@ +/** + * @file llpluginmessagepipe.cpp + * @brief Classes that implement connections from the plugin system to pipes/pumps. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llpluginmessagepipe.h" +#include "llbufferstream.h" + +#include "llapr.h" + +static const char MESSAGE_DELIMITER = '\0'; + +LLPluginMessagePipeOwner::LLPluginMessagePipeOwner() : + mMessagePipe(NULL), + mSocketError(APR_SUCCESS) +{ +} + +// virtual +LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner() +{ + killMessagePipe(); +} + +// virtual +apr_status_t LLPluginMessagePipeOwner::socketError(apr_status_t error) +{ + mSocketError = error; + return error; +}; + +//virtual +void LLPluginMessagePipeOwner::setMessagePipe(LLPluginMessagePipe *read_pipe) +{ + // Save a reference to this pipe + mMessagePipe = read_pipe; +} + +bool LLPluginMessagePipeOwner::canSendMessage(void) +{ + return (mMessagePipe != NULL); +} + +bool LLPluginMessagePipeOwner::writeMessageRaw(const std::string &message) +{ + bool result = true; + if(mMessagePipe != NULL) + { + result = mMessagePipe->addMessage(message); + } + else + { + LL_WARNS("Plugin") << "dropping message: " << message << LL_ENDL; + result = false; + } + + return result; +} + +void LLPluginMessagePipeOwner::killMessagePipe(void) +{ + if(mMessagePipe != NULL) + { + delete mMessagePipe; + mMessagePipe = NULL; + } +} + +LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket) +{ + mOwner = owner; + mOwner->setMessagePipe(this); + mSocket = socket; +} + +LLPluginMessagePipe::~LLPluginMessagePipe() +{ + if(mOwner != NULL) + { + mOwner->setMessagePipe(NULL); + } +} + +bool LLPluginMessagePipe::addMessage(const std::string &message) +{ + // queue the message for later output + mOutput += message; + mOutput += MESSAGE_DELIMITER; // message separator + + return true; +} + +void LLPluginMessagePipe::clearOwner(void) +{ + // The owner is done with this pipe. The next call to process_impl should send any remaining data and exit. + mOwner = NULL; +} + +void LLPluginMessagePipe::setSocketTimeout(apr_interval_time_t timeout_usec) +{ + // We never want to sleep forever, so force negative timeouts to become non-blocking. + + // according to this page: http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-13.html + // blocking/non-blocking with apr sockets is somewhat non-portable. + + if(timeout_usec <= 0) + { + // Make the socket non-blocking + apr_socket_opt_set(mSocket->getSocket(), APR_SO_NONBLOCK, 1); + apr_socket_timeout_set(mSocket->getSocket(), 0); + } + else + { + // Make the socket blocking-with-timeout + apr_socket_opt_set(mSocket->getSocket(), APR_SO_NONBLOCK, 1); + apr_socket_timeout_set(mSocket->getSocket(), timeout_usec); + } +} + +bool LLPluginMessagePipe::pump(F64 timeout) +{ + bool result = true; + + if(mSocket) + { + apr_status_t status; + apr_size_t size; + + if(!mOutput.empty()) + { + // write any outgoing messages + size = (apr_size_t)mOutput.size(); + + setSocketTimeout(0); + +// LL_INFOS("Plugin") << "before apr_socket_send, size = " << size << LL_ENDL; + + status = apr_socket_send( + mSocket->getSocket(), + (const char*)mOutput.data(), + &size); + +// LL_INFOS("Plugin") << "after apr_socket_send, size = " << size << LL_ENDL; + + if(status == APR_SUCCESS) + { + // success + mOutput = mOutput.substr(size); + } + else if(APR_STATUS_IS_EAGAIN(status)) + { + // Socket buffer is full... + // remove the written part from the buffer and try again later. + mOutput = mOutput.substr(size); + } + else + { + // some other error + // Treat this as fatal. + ll_apr_warn_status(status); + + if(mOwner) + { + mOwner->socketError(status); + } + result = false; + } + } + + // FIXME: For some reason, the apr timeout stuff isn't working properly on windows. + // Until such time as we figure out why, don't try to use the socket timeout -- just sleep here instead. +#if LL_WINDOWS + if(result) + { + if(timeout != 0.0f) + { + ms_sleep((int)(timeout * 1000.0f)); + timeout = 0.0f; + } + } +#endif + + // Check for incoming messages + if(result) + { + char input_buf[1024]; + apr_size_t request_size; + + // Start out by reading one byte, so that any data received will wake us up. + request_size = 1; + + // and use the timeout so we'll sleep if no data is available. + setSocketTimeout((apr_interval_time_t)(timeout * 1000000)); + + while(1) + { + size = request_size; + +// LL_INFOS("Plugin") << "before apr_socket_recv, size = " << size << LL_ENDL; + + status = apr_socket_recv( + mSocket->getSocket(), + input_buf, + &size); + +// LL_INFOS("Plugin") << "after apr_socket_recv, size = " << size << LL_ENDL; + + if(size > 0) + mInput.append(input_buf, size); + + if(status == APR_SUCCESS) + { +// llinfos << "success, read " << size << llendl; + + if(size != request_size) + { + // This was a short read, so we're done. + break; + } + } + else if(APR_STATUS_IS_TIMEUP(status)) + { +// llinfos << "TIMEUP, read " << size << llendl; + + // Timeout was hit. Since the initial read is 1 byte, this should never be a partial read. + break; + } + else if(APR_STATUS_IS_EAGAIN(status)) + { +// llinfos << "EAGAIN, read " << size << llendl; + + // We've been doing partial reads, and we're done now. + break; + } + else + { + // some other error + // Treat this as fatal. + ll_apr_warn_status(status); + + if(mOwner) + { + mOwner->socketError(status); + } + result = false; + break; + } + + // Second and subsequent reads should not use the timeout + setSocketTimeout(0); + // and should try to fill the input buffer + request_size = sizeof(input_buf); + } + + processInput(); + } + } + + if(!result) + { + // If we got an error, we're done. + LL_INFOS("Plugin") << "Error from socket, cleaning up." << LL_ENDL; + delete this; + } + + return result; +} + +void LLPluginMessagePipe::processInput(void) +{ + // Look for input delimiter(s) in the input buffer. + int start = 0; + int delim; + while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos) + { + // Let the owner process this message + mOwner->receiveMessageRaw(mInput.substr(start, delim - start)); + + start = delim + 1; + } + + // Remove delivered messages from the input buffer. + if(start != 0) + mInput = mInput.substr(start); + +} + diff --git a/linden/indra/llplugin/llpluginmessagepipe.h b/linden/indra/llplugin/llpluginmessagepipe.h new file mode 100644 index 000000000..9bf17810c --- /dev/null +++ b/linden/indra/llplugin/llpluginmessagepipe.h @@ -0,0 +1,92 @@ +/** + * @file llpluginmessagepipe.h + * @brief Classes that implement connections from the plugin system to pipes/pumps. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINMESSAGEPIPE_H +#define LL_LLPLUGINMESSAGEPIPE_H + +#include "lliosocket.h" + +class LLPluginMessagePipe; + +// Inherit from this to be able to receive messages from the LLPluginMessagePipe +class LLPluginMessagePipeOwner +{ + LOG_CLASS(LLPluginMessagePipeOwner); +public: + LLPluginMessagePipeOwner(); + virtual ~LLPluginMessagePipeOwner(); + // called with incoming messages + virtual void receiveMessageRaw(const std::string &message) = 0; + // called when the socket has an error + virtual apr_status_t socketError(apr_status_t error); + + // called from LLPluginMessagePipe to manage the connection with LLPluginMessagePipeOwner -- do not use! + virtual void setMessagePipe(LLPluginMessagePipe *message_pipe) ; + +protected: + // returns false if writeMessageRaw() would drop the message + bool canSendMessage(void); + // call this to send a message over the pipe + bool writeMessageRaw(const std::string &message); + // call this to close the pipe + void killMessagePipe(void); + + LLPluginMessagePipe *mMessagePipe; + apr_status_t mSocketError; +}; + +class LLPluginMessagePipe +{ + LOG_CLASS(LLPluginMessagePipe); +public: + LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket); + virtual ~LLPluginMessagePipe(); + + bool addMessage(const std::string &message); + void clearOwner(void); + + bool pump(F64 timeout = 0.0f); + +protected: + void processInput(void); + + // used internally by pump() + void setSocketTimeout(apr_interval_time_t timeout_usec); + + std::string mInput; + std::string mOutput; + + LLPluginMessagePipeOwner *mOwner; + LLSocket::ptr_t mSocket; +}; + +#endif // LL_LLPLUGINMESSAGE_H diff --git a/linden/indra/llplugin/llpluginprocesschild.cpp b/linden/indra/llplugin/llpluginprocesschild.cpp new file mode 100644 index 000000000..9b5eafce9 --- /dev/null +++ b/linden/indra/llplugin/llpluginprocesschild.cpp @@ -0,0 +1,490 @@ +/** + * @file llpluginprocesschild.cpp + * @brief LLPluginProcessChild handles the child side of the external-process plugin API. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llpluginprocesschild.h" +#include "llplugininstance.h" +#include "llpluginmessagepipe.h" +#include "llpluginmessageclasses.h" + +static const F32 HEARTBEAT_SECONDS = 1.0f; +static const F32 PLUGIN_IDLE_SECONDS = 1.0f / 100.0f; // Each call to idle will give the plugin this much time. + +LLPluginProcessChild::LLPluginProcessChild() +{ + mInstance = NULL; + mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); + mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz + mCPUElapsed = 0.0f; +} + +LLPluginProcessChild::~LLPluginProcessChild() +{ + if(mInstance != NULL) + { + sendMessageToPlugin(LLPluginMessage("base", "cleanup")); + delete mInstance; + mInstance = NULL; + } +} + +void LLPluginProcessChild::killSockets(void) +{ + killMessagePipe(); + mSocket.reset(); +} + +void LLPluginProcessChild::init(U32 launcher_port) +{ + mLauncherHost = LLHost("127.0.0.1", launcher_port); + setState(STATE_INITIALIZED); +} + +void LLPluginProcessChild::idle(void) +{ + bool idle_again; + do + { + if(mSocketError != APR_SUCCESS) + { + LL_INFOS("Plugin") << "message pipe is in error state, moving to STATE_ERROR"<< LL_ENDL; + setState(STATE_ERROR); + } + + if((mState > STATE_INITIALIZED) && (mMessagePipe == NULL)) + { + // The pipe has been closed -- we're done. + // TODO: This could be slightly more subtle, but I'm not sure it needs to be. + LL_INFOS("Plugin") << "message pipe went away, moving to STATE_ERROR"<< LL_ENDL; + setState(STATE_ERROR); + } + + // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). + // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. + // When in doubt, don't do it. + idle_again = false; + + if(mInstance != NULL) + { + // Provide some time to the plugin + mInstance->idle(); + } + + switch(mState) + { + case STATE_UNINITIALIZED: + break; + + case STATE_INITIALIZED: + if(mSocket->blockingConnect(mLauncherHost)) + { + // This automatically sets mMessagePipe + new LLPluginMessagePipe(this, mSocket); + + setState(STATE_CONNECTED); + } + else + { + // connect failed + setState(STATE_ERROR); + } + break; + + case STATE_CONNECTED: + sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hello")); + setState(STATE_PLUGIN_LOADING); + break; + + case STATE_PLUGIN_LOADING: + if(!mPluginFile.empty()) + { + mInstance = new LLPluginInstance(this); + if(mInstance->load(mPluginFile) == 0) + { + mHeartbeat.start(); + mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS); + mCPUElapsed = 0.0f; + setState(STATE_PLUGIN_LOADED); + } + else + { + setState(STATE_ERROR); + } + } + break; + + case STATE_PLUGIN_LOADED: + { + setState(STATE_PLUGIN_INITIALIZING); + LLPluginMessage message("base", "init"); + message.setValue("user_data_path", mUserDataPath); + sendMessageToPlugin(message); + } + break; + + case STATE_PLUGIN_INITIALIZING: + // waiting for init_response... + break; + + case STATE_RUNNING: + if(mInstance != NULL) + { + // Provide some time to the plugin + LLPluginMessage message("base", "idle"); + message.setValueReal("time", PLUGIN_IDLE_SECONDS); + sendMessageToPlugin(message); + + mInstance->idle(); + + if(mHeartbeat.hasExpired()) + { + + // This just proves that we're not stuck down inside the plugin code. + LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat"); + + // Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle. + // Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation. + // If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation. + heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64()); + + sendMessageToParent(heartbeat); + + mHeartbeat.reset(); + mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS); + mCPUElapsed = 0.0f; + } + } + // receivePluginMessage will transition to STATE_UNLOADING + break; + + case STATE_UNLOADING: + if(mInstance != NULL) + { + sendMessageToPlugin(LLPluginMessage("base", "cleanup")); + delete mInstance; + mInstance = NULL; + } + setState(STATE_UNLOADED); + break; + + case STATE_UNLOADED: + killSockets(); + setState(STATE_DONE); + break; + + case STATE_ERROR: + // Close the socket to the launcher + killSockets(); + // TODO: Where do we go from here? Just exit()? + setState(STATE_DONE); + break; + + case STATE_DONE: + // just sit here. + break; + } + + } while (idle_again); +} + +void LLPluginProcessChild::sleep(F64 seconds) +{ + if(mMessagePipe) + { + mMessagePipe->pump(seconds); + } + else + { + ms_sleep((int)(seconds * 1000.0f)); + } +} + +void LLPluginProcessChild::pump(void) +{ + if(mMessagePipe) + { + mMessagePipe->pump(0.0f); + } + else + { + // Should we warn here? + } +} + + +bool LLPluginProcessChild::isRunning(void) +{ + bool result = false; + + if(mState == STATE_RUNNING) + result = true; + + return result; +} + +bool LLPluginProcessChild::isDone(void) +{ + bool result = false; + + switch(mState) + { + case STATE_DONE: + result = true; + break; + default: + break; + } + + return result; +} + +void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message) +{ + std::string buffer = message.generate(); + + LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL; + LLTimer elapsed; + + mInstance->sendMessage(buffer); + + mCPUElapsed += elapsed.getElapsedTimeF64(); +} + +void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message) +{ + std::string buffer = message.generate(); + + LL_DEBUGS("Plugin") << "Sending to parent: " << buffer << LL_ENDL; + + writeMessageRaw(buffer); +} + +void LLPluginProcessChild::receiveMessageRaw(const std::string &message) +{ + // Incoming message from the TCP Socket + + LL_DEBUGS("Plugin") << "Received from parent: " << message << LL_ENDL; + + bool passMessage = true; + + // FIXME: how should we handle queueing here? + + { + // Decode this message + LLPluginMessage parsed; + parsed.parse(message); + + std::string message_class = parsed.getClass(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) + { + passMessage = false; + + std::string message_name = parsed.getName(); + if(message_name == "load_plugin") + { + mPluginFile = parsed.getValue("file"); + mUserDataPath = parsed.getValue("user_data_path"); + } + else if(message_name == "shm_add") + { + std::string name = parsed.getValue("name"); + size_t size = (size_t)parsed.getValueS32("size"); + + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + if(iter != mSharedMemoryRegions.end()) + { + // Need to remove the old region first + LL_WARNS("Plugin") << "Adding a duplicate shared memory segment!" << LL_ENDL; + } + else + { + // This is a new region + LLPluginSharedMemory *region = new LLPluginSharedMemory; + if(region->attach(name, size)) + { + mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region)); + + std::stringstream addr; + addr << region->getMappedAddress(); + + // Send the add notification to the plugin + LLPluginMessage message("base", "shm_added"); + message.setValue("name", name); + message.setValueS32("size", (S32)size); + message.setValuePointer("address", region->getMappedAddress()); + sendMessageToPlugin(message); + + // and send the response to the parent + message.setMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add_response"); + message.setValue("name", name); + sendMessageToParent(message); + } + else + { + LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; + } + } + + } + else if(message_name == "shm_remove") + { + std::string name = parsed.getValue("name"); + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + if(iter != mSharedMemoryRegions.end()) + { + // forward the remove request to the plugin -- its response will trigger us to detach the segment. + LLPluginMessage message("base", "shm_remove"); + message.setValue("name", name); + sendMessageToPlugin(message); + } + else + { + LL_WARNS("Plugin") << "shm_remove for unknown memory segment!" << LL_ENDL; + } + } + else if(message_name == "sleep_time") + { + mSleepTime = parsed.getValueReal("time"); + } + else if(message_name == "crash") + { + // Crash the plugin + LL_ERRS("Plugin") << "Plugin crash requested." << LL_ENDL; + } + else if(message_name == "hang") + { + // Hang the plugin + LL_WARNS("Plugin") << "Plugin hang requested." << LL_ENDL; + while(1) + { + // wheeeeeeeee...... + } + } + else + { + LL_WARNS("Plugin") << "Unknown internal message from parent: " << message_name << LL_ENDL; + } + } + } + + if(passMessage && mInstance != NULL) + { + LLTimer elapsed; + + mInstance->sendMessage(message); + + mCPUElapsed += elapsed.getElapsedTimeF64(); + } +} + +/* virtual */ +void LLPluginProcessChild::receivePluginMessage(const std::string &message) +{ + LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL; + + // Incoming message from the plugin instance + bool passMessage = true; + + // FIXME: how should we handle queueing here? + + // Intercept certain base messages (responses to ones sent by this class) + { + // Decode this message + LLPluginMessage parsed; + parsed.parse(message); + std::string message_class = parsed.getClass(); + if(message_class == "base") + { + std::string message_name = parsed.getName(); + if(message_name == "init_response") + { + // The plugin has finished initializing. + setState(STATE_RUNNING); + + // Don't pass this message up to the parent + passMessage = false; + + LLPluginMessage new_message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin_response"); + LLSD versions = parsed.getValueLLSD("versions"); + new_message.setValueLLSD("versions", versions); + + if(parsed.hasValue("plugin_version")) + { + std::string plugin_version = parsed.getValue("plugin_version"); + new_message.setValueLLSD("plugin_version", plugin_version); + } + + // Let the parent know it's loaded and initialized. + sendMessageToParent(new_message); + } + else if(message_name == "shm_remove_response") + { + // Don't pass this message up to the parent + passMessage = false; + + std::string name = parsed.getValue("name"); + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + if(iter != mSharedMemoryRegions.end()) + { + // detach the shared memory region + iter->second->detach(); + + // and remove it from our map + mSharedMemoryRegions.erase(iter); + + // Finally, send the response to the parent. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove_response"); + message.setValue("name", name); + sendMessageToParent(message); + } + else + { + LL_WARNS("Plugin") << "shm_remove_response for unknown memory segment!" << LL_ENDL; + } + } + } + } + + if(passMessage) + { + LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL; + writeMessageRaw(message); + } +} + + +void LLPluginProcessChild::setState(EState state) +{ + LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; + mState = state; +}; diff --git a/linden/indra/llplugin/llpluginprocesschild.h b/linden/indra/llplugin/llpluginprocesschild.h new file mode 100644 index 000000000..16a1ae84e --- /dev/null +++ b/linden/indra/llplugin/llpluginprocesschild.h @@ -0,0 +1,112 @@ +/** + * @file llpluginprocesschild.h + * @brief LLPluginProcessChild handles the child side of the external-process plugin API. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINPROCESSCHILD_H +#define LL_LLPLUGINPROCESSCHILD_H + +#include "llpluginmessage.h" +#include "llpluginmessagepipe.h" +#include "llplugininstance.h" +#include "llhost.h" +#include "llpluginsharedmemory.h" + +class LLPluginInstance; + +class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInstanceMessageListener +{ + LOG_CLASS(LLPluginProcessChild); +public: + LLPluginProcessChild(); + ~LLPluginProcessChild(); + + void init(U32 launcher_port); + void idle(void); + void sleep(F64 seconds); + void pump(); + + // returns true if the plugin is in the steady state (processing messages) + bool isRunning(void); + + // returns true if the plugin is unloaded or we're in an unrecoverable error state. + bool isDone(void); + + void killSockets(void); + + F64 getSleepTime(void) const { return mSleepTime; }; + + void sendMessageToPlugin(const LLPluginMessage &message); + void sendMessageToParent(const LLPluginMessage &message); + + // Inherited from LLPluginMessagePipeOwner + /* virtual */ void receiveMessageRaw(const std::string &message); + + // Inherited from LLPluginInstanceMessageListener + /* virtual */ void receivePluginMessage(const std::string &message); + +private: + + enum EState + { + STATE_UNINITIALIZED, + STATE_INITIALIZED, // init() has been called + STATE_CONNECTED, // connected back to launcher + STATE_PLUGIN_LOADING, // plugin library needs to be loaded + STATE_PLUGIN_LOADED, // plugin library has been loaded + STATE_PLUGIN_INITIALIZING, // plugin is processing init message + STATE_RUNNING, // steady state (processing messages) + STATE_UNLOADING, // plugin has sent shutdown_response and needs to be unloaded + STATE_UNLOADED, // plugin has been unloaded + STATE_ERROR, // generic bailout state + STATE_DONE // state machine will sit in this state after either error or normal termination. + }; + EState mState; + void setState(EState state); + + LLHost mLauncherHost; + LLSocket::ptr_t mSocket; + + std::string mPluginFile; + + std::string mUserDataPath; + + LLPluginInstance *mInstance; + + typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType; + sharedMemoryRegionsType mSharedMemoryRegions; + + LLTimer mHeartbeat; + F64 mSleepTime; + F64 mCPUElapsed; + +}; + +#endif // LL_LLPLUGINPROCESSCHILD_H diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp new file mode 100644 index 000000000..bd36d11e8 --- /dev/null +++ b/linden/indra/llplugin/llpluginprocessparent.cpp @@ -0,0 +1,714 @@ +/** + * @file llpluginprocessparent.cpp + * @brief LLPluginProcessParent handles the parent side of the external-process plugin API. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llpluginprocessparent.h" +#include "llpluginmessagepipe.h" +#include "llpluginmessageclasses.h" + +#include "llapr.h" + +//virtual +LLPluginProcessParentOwner::~LLPluginProcessParentOwner() +{ + +} + +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) +{ + mOwner = owner; + mBoundPort = 0; + mState = STATE_UNINITIALIZED; + mDisableTimeout = false; + mDebug = false; + + mPluginLaunchTimeout = 60.0f; + mPluginLockupTimeout = 30.0f; + + // Don't start the timer here -- start it when we actually launch the plugin process. + mHeartbeat.stop(); +} + +LLPluginProcessParent::~LLPluginProcessParent() +{ + LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; + + // Destroy any remaining shared memory regions + sharedMemoryRegionsType::iterator iter; + while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end()) + { + // destroy the shared memory region + iter->second->destroy(); + + // and remove it from our map + mSharedMemoryRegions.erase(iter); + } + + // orphaning the process means it won't be killed when the LLProcessLauncher is destructed. + // This is what we want -- it should exit cleanly once it notices the sockets have been closed. + mProcess.orphan(); + killSockets(); +} + +void LLPluginProcessParent::killSockets(void) +{ + killMessagePipe(); + mListenSocket.reset(); + mSocket.reset(); +} + +void LLPluginProcessParent::errorState(void) +{ + if(mState < STATE_RUNNING) + setState(STATE_LAUNCH_FAILURE); + else + setState(STATE_ERROR); +} + +void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path) +{ + mProcess.setExecutable(launcher_filename); + mPluginFile = plugin_filename; + mCPUUsage = 0.0f; + mDebug = debug; + mUserDataPath = user_data_path; + + setState(STATE_INITIALIZED); +} + +bool LLPluginProcessParent::accept() +{ + bool result = false; + + apr_status_t status = APR_EGENERAL; + apr_socket_t *new_socket = NULL; + + status = apr_socket_accept( + &new_socket, + mListenSocket->getSocket(), + gAPRPoolp); + + + if(status == APR_SUCCESS) + { +// llinfos << "SUCCESS" << llendl; + // Success. Create a message pipe on the new socket + + // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! + apr_pool_t* new_pool = NULL; + status = apr_pool_create(&new_pool, gAPRPoolp); + + mSocket = LLSocket::create(new_socket, new_pool); + new LLPluginMessagePipe(this, mSocket); + + result = true; + } + else if(APR_STATUS_IS_EAGAIN(status)) + { +// llinfos << "EAGAIN" << llendl; + + // No incoming connections. This is not an error. + status = APR_SUCCESS; + } + else + { +// llinfos << "Error:" << llendl; + ll_apr_warn_status(status); + + // Some other error. + errorState(); + } + + return result; +} + +void LLPluginProcessParent::idle(void) +{ + bool idle_again; + + do + { + // Give time to network processing + if(mMessagePipe) + { + if(!mMessagePipe->pump()) + { +// LL_WARNS("Plugin") << "Message pipe hit an error state" << LL_ENDL; + errorState(); + } + } + + if((mSocketError != APR_SUCCESS) && (mState <= STATE_RUNNING)) + { + // The socket is in an error state -- the plugin is gone. + LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; + errorState(); + } + + // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). + // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return. + // When in doubt, don't do it. + idle_again = false; + switch(mState) + { + case STATE_UNINITIALIZED: + break; + + case STATE_INITIALIZED: + { + + apr_status_t status = APR_SUCCESS; + apr_sockaddr_t* addr = NULL; + mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); + mBoundPort = 0; + + // This code is based on parts of LLSocket::create() in lliosocket.cpp. + + status = apr_sockaddr_info_get( + &addr, + "127.0.0.1", + APR_INET, + 0, // port 0 = ephemeral ("find me a port") + 0, + gAPRPoolp); + + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // This allows us to reuse the address on quick down/up. This is unlikely to create problems. + ll_apr_warn_status(apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_REUSEADDR, 1)); + + status = apr_socket_bind(mListenSocket->getSocket(), addr); + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // Get the actual port the socket was bound to + { + apr_sockaddr_t* bound_addr = NULL; + if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket()))) + { + killSockets(); + errorState(); + break; + } + mBoundPort = bound_addr->port; + + if(mBoundPort == 0) + { + LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL; + + killSockets(); + errorState(); + break; + } + } + + LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL; + + // Make the listen socket non-blocking + status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1); + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + apr_socket_timeout_set(mListenSocket->getSocket(), 0); + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // If it's a stream based socket, we need to tell the OS + // to keep a queue of incoming connections for ACCEPT. + status = apr_socket_listen( + mListenSocket->getSocket(), + 10); // FIXME: Magic number for queue size + + if(ll_apr_warn_status(status)) + { + killSockets(); + errorState(); + break; + } + + // If we got here, we're listening. + setState(STATE_LISTENING); + } + break; + + case STATE_LISTENING: + { + // Launch the plugin process. + + // Only argument to the launcher is the port number we're listening on + std::stringstream stream; + stream << mBoundPort; + mProcess.addArgument(stream.str()); + if(mProcess.launch() != 0) + { + errorState(); + } + else + { + if(mDebug) + { + #if LL_DARWIN + // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue. + + // The command we're constructing would look like this on the command line: + // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell' + + std::stringstream cmd; + + mDebugger.setExecutable("/usr/bin/osascript"); + mDebugger.addArgument("-e"); + mDebugger.addArgument("tell application \"Terminal\""); + mDebugger.addArgument("-e"); + cmd << "set win to do script \"gdb -pid " << mProcess.getProcessID() << "\""; + mDebugger.addArgument(cmd.str()); + mDebugger.addArgument("-e"); + mDebugger.addArgument("do script \"continue\" in win"); + mDebugger.addArgument("-e"); + mDebugger.addArgument("end tell"); + mDebugger.launch(); + + #endif + } + + // This will allow us to time out if the process never starts. + mHeartbeat.start(); + mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout); + setState(STATE_LAUNCHED); + } + } + break; + + case STATE_LAUNCHED: + // waiting for the plugin to connect + if(pluginLockedUpOrQuit()) + { + errorState(); + } + else + { + // Check for the incoming connection. + if(accept()) + { + // Stop listening on the server port + mListenSocket.reset(); + setState(STATE_CONNECTED); + } + } + break; + + case STATE_CONNECTED: + // waiting for hello message from the plugin + + if(pluginLockedUpOrQuit()) + { + errorState(); + } + break; + + case STATE_HELLO: + LL_DEBUGS("Plugin") << "received hello message" << llendl; + + // Send the message to load the plugin + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); + message.setValue("file", mPluginFile); + message.setValue("user_data_path", mUserDataPath); + sendMessage(message); + } + + setState(STATE_LOADING); + break; + + case STATE_LOADING: + // The load_plugin_response message will kick us from here into STATE_RUNNING + if(pluginLockedUpOrQuit()) + { + errorState(); + } + break; + + case STATE_RUNNING: + if(pluginLockedUpOrQuit()) + { + errorState(); + } + break; + + case STATE_EXITING: + if(!mProcess.isRunning()) + { + setState(STATE_CLEANUP); + } + else if(pluginLockedUp()) + { + LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << llendl; + errorState(); + } + break; + + case STATE_LAUNCH_FAILURE: + if(mOwner != NULL) + { + mOwner->pluginLaunchFailed(); + } + setState(STATE_CLEANUP); + break; + + case STATE_ERROR: + if(mOwner != NULL) + { + mOwner->pluginDied(); + } + setState(STATE_CLEANUP); + break; + + case STATE_CLEANUP: + // Don't do a kill here anymore -- closing the sockets is the new 'kill'. + mProcess.orphan(); + killSockets(); + setState(STATE_DONE); + break; + + + case STATE_DONE: + // just sit here. + break; + + } + + } while (idle_again); +} + +bool LLPluginProcessParent::isLoading(void) +{ + bool result = false; + + if(mState <= STATE_LOADING) + result = true; + + return result; +} + +bool LLPluginProcessParent::isRunning(void) +{ + bool result = false; + + if(mState == STATE_RUNNING) + result = true; + + return result; +} + +bool LLPluginProcessParent::isDone(void) +{ + bool result = false; + + if(mState == STATE_DONE) + result = true; + + return result; +} + +void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send) +{ + if(force_send || (sleep_time != mSleepTime)) + { + // Cache the time locally + mSleepTime = sleep_time; + + if(canSendMessage()) + { + // and send to the plugin. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "sleep_time"); + message.setValueReal("time", mSleepTime); + sendMessage(message); + } + else + { + // Too early to send -- the load_plugin_response message will trigger us to send mSleepTime later. + } + } +} + +void LLPluginProcessParent::sendMessage(const LLPluginMessage &message) +{ + + std::string buffer = message.generate(); + LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL; + writeMessageRaw(buffer); +} + + +void LLPluginProcessParent::receiveMessageRaw(const std::string &message) +{ + LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL; + + // FIXME: should this go into a queue instead? + + LLPluginMessage parsed; + if(parsed.parse(message) != -1) + { + receiveMessage(parsed); + } +} + +void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) +{ + std::string message_class = message.getClass(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) + { + // internal messages should be handled here + std::string message_name = message.getName(); + if(message_name == "hello") + { + if(mState == STATE_CONNECTED) + { + // Plugin host has launched. Tell it which plugin to load. + setState(STATE_HELLO); + } + else + { + LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; + errorState(); + } + + } + else if(message_name == "load_plugin_response") + { + if(mState == STATE_LOADING) + { + // Plugin has been loaded. + + mPluginVersionString = message.getValue("plugin_version"); + LL_INFOS("Plugin") << "plugin version string: " << mPluginVersionString << LL_ENDL; + + // Check which message classes/versions the plugin supports. + // TODO: check against current versions + // TODO: kill plugin on major mismatches? + mMessageClassVersions = message.getValueLLSD("versions"); + LLSD::map_iterator iter; + for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++) + { + LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL; + } + + // Send initial sleep time + setSleepTime(mSleepTime, true); + + setState(STATE_RUNNING); + } + else + { + LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; + errorState(); + } + } + else if(message_name == "heartbeat") + { + // this resets our timer. + mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); + + mCPUUsage = message.getValueReal("cpu_usage"); + + LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL; + + } + else if(message_name == "shm_add_response") + { + // Nothing to do here. + } + else if(message_name == "shm_remove_response") + { + std::string name = message.getValue("name"); + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + + if(iter != mSharedMemoryRegions.end()) + { + // destroy the shared memory region + iter->second->destroy(); + + // and remove it from our map + mSharedMemoryRegions.erase(iter); + } + } + else + { + LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL; + } + } + else + { + if(mOwner != NULL) + { + mOwner->receivePluginMessage(message); + } + } +} + +std::string LLPluginProcessParent::addSharedMemory(size_t size) +{ + std::string name; + + LLPluginSharedMemory *region = new LLPluginSharedMemory; + + // This is a new region + if(region->create(size)) + { + name = region->getName(); + + mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region)); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add"); + message.setValue("name", name); + message.setValueS32("size", (S32)size); + sendMessage(message); + } + else + { + LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; + + // Don't leak + delete region; + } + + return name; +} + +void LLPluginProcessParent::removeSharedMemory(const std::string &name) +{ + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + + if(iter != mSharedMemoryRegions.end()) + { + // This segment exists. Send the message to the child to unmap it. The response will cause the parent to unmap our end. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove"); + message.setValue("name", name); + sendMessage(message); + } + else + { + LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL; + } +} +size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name) +{ + size_t result = 0; + + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + if(iter != mSharedMemoryRegions.end()) + { + result = iter->second->getSize(); + } + + return result; +} +void *LLPluginProcessParent::getSharedMemoryAddress(const std::string &name) +{ + void *result = NULL; + + sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name); + if(iter != mSharedMemoryRegions.end()) + { + result = iter->second->getMappedAddress(); + } + + return result; +} + +std::string LLPluginProcessParent::getMessageClassVersion(const std::string &message_class) +{ + std::string result; + + if(mMessageClassVersions.has(message_class)) + { + result = mMessageClassVersions[message_class].asString(); + } + + return result; +} + +std::string LLPluginProcessParent::getPluginVersion(void) +{ + return mPluginVersionString; +} + +void LLPluginProcessParent::setState(EState state) +{ + LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; + mState = state; +}; + +bool LLPluginProcessParent::pluginLockedUpOrQuit() +{ + bool result = false; + + if(!mDisableTimeout && !mDebug) + { + if(!mProcess.isRunning()) + { + LL_WARNS("Plugin") << "child exited" << llendl; + result = true; + } + else if(pluginLockedUp()) + { + LL_WARNS("Plugin") << "timeout" << llendl; + result = true; + } + } + + return result; +} + +bool LLPluginProcessParent::pluginLockedUp() +{ + // If the timer is running and has expired, the plugin has locked up. + return (mHeartbeat.getStarted() && mHeartbeat.hasExpired()); +} + diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h new file mode 100644 index 000000000..00c60b5d8 --- /dev/null +++ b/linden/indra/llplugin/llpluginprocessparent.h @@ -0,0 +1,169 @@ +/** + * @file llpluginprocessparent.h + * @brief LLPluginProcessParent handles the parent side of the external-process plugin API. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINPROCESSPARENT_H +#define LL_LLPLUGINPROCESSPARENT_H + +#include "llapr.h" +#include "llprocesslauncher.h" +#include "llpluginmessage.h" +#include "llpluginmessagepipe.h" +#include "llpluginsharedmemory.h" + +#include "lliosocket.h" + +class LLPluginProcessParentOwner +{ +public: + virtual ~LLPluginProcessParentOwner(); + virtual void receivePluginMessage(const LLPluginMessage &message) = 0; + // This will only be called when the plugin has died unexpectedly + virtual void pluginLaunchFailed() {}; + virtual void pluginDied() {}; +}; + +class LLPluginProcessParent : public LLPluginMessagePipeOwner +{ + LOG_CLASS(LLPluginProcessParent); +public: + LLPluginProcessParent(LLPluginProcessParentOwner *owner); + ~LLPluginProcessParent(); + + void init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path); + void idle(void); + + // returns true if the plugin is on its way to steady state + bool isLoading(void); + + // returns true if the plugin is in the steady state (processing messages) + bool isRunning(void); + + // returns true if the process has exited or we've had a fatal error + bool isDone(void); + + void killSockets(void); + + // Go to the proper error state + void errorState(void); + + void setSleepTime(F64 sleep_time, bool force_send = false); + F64 getSleepTime(void) const { return mSleepTime; }; + + void sendMessage(const LLPluginMessage &message); + + void receiveMessage(const LLPluginMessage &message); + + // Inherited from LLPluginMessagePipeOwner + void receiveMessageRaw(const std::string &message); + + // This adds a memory segment shared with the client, generating a name for the segment. The name generated is guaranteed to be unique on the host. + // The caller must call removeSharedMemory first (and wait until getSharedMemorySize returns 0 for the indicated name) before re-adding a segment with the same name. + std::string addSharedMemory(size_t size); + // Negotiates for the removal of a shared memory segment. It is the caller's responsibility to ensure that nothing touches the memory + // after this has been called, since the segment will be unmapped shortly thereafter. + void removeSharedMemory(const std::string &name); + size_t getSharedMemorySize(const std::string &name); + void *getSharedMemoryAddress(const std::string &name); + + // Returns the version string the plugin indicated for the message class, or an empty string if that class wasn't in the list. + std::string getMessageClassVersion(const std::string &message_class); + + std::string getPluginVersion(void); + + bool getDisableTimeout() { return mDisableTimeout; }; + void setDisableTimeout(bool disable) { mDisableTimeout = disable; }; + + void setLaunchTimeout(F32 timeout) { mPluginLaunchTimeout = timeout; }; + void setLockupTimeout(F32 timeout) { mPluginLockupTimeout = timeout; }; + + F64 getCPUUsage() { return mCPUUsage; }; + +private: + + enum EState + { + STATE_UNINITIALIZED, + STATE_INITIALIZED, // init() has been called + STATE_LISTENING, // listening for incoming connection + STATE_LAUNCHED, // process has been launched + STATE_CONNECTED, // process has connected + STATE_HELLO, // first message from the plugin process has been received + STATE_LOADING, // process has been asked to load the plugin + STATE_RUNNING, // + STATE_LAUNCH_FAILURE, // Failure before plugin loaded + STATE_ERROR, // generic bailout state + STATE_CLEANUP, // clean everything up + STATE_EXITING, // Tried to kill process, waiting for it to exit + STATE_DONE // + + }; + EState mState; + void setState(EState state); + + bool pluginLockedUp(); + bool pluginLockedUpOrQuit(); + + bool accept(); + + LLSocket::ptr_t mListenSocket; + LLSocket::ptr_t mSocket; + U32 mBoundPort; + + LLProcessLauncher mProcess; + + std::string mPluginFile; + + std::string mUserDataPath; + + LLPluginProcessParentOwner *mOwner; + + typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType; + sharedMemoryRegionsType mSharedMemoryRegions; + + LLSD mMessageClassVersions; + std::string mPluginVersionString; + + LLTimer mHeartbeat; + F64 mSleepTime; + F64 mCPUUsage; + + bool mDisableTimeout; + bool mDebug; + + LLProcessLauncher mDebugger; + + F32 mPluginLaunchTimeout; // Somewhat longer timeout for initial launch. + F32 mPluginLockupTimeout; // If we don't receive a heartbeat in this many seconds, we declare the plugin locked up. + +}; + +#endif // LL_LLPLUGINPROCESSPARENT_H diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp new file mode 100644 index 000000000..2be46481d --- /dev/null +++ b/linden/indra/llplugin/llpluginsharedmemory.cpp @@ -0,0 +1,506 @@ +/** + * @file llpluginsharedmemory.cpp + * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llpluginsharedmemory.h" + +// on Mac and Linux, we use the native shm_open/mmap interface by using +// #define USE_SHM_OPEN_SHARED_MEMORY 1 +// in the appropriate sections below. + +// For Windows, use: +// #define USE_WIN32_SHARED_MEMORY 1 + +// If we ever want to fall back to the apr implementation for a platform, use: +// #define USE_APR_SHARED_MEMORY 1 + +#if LL_WINDOWS +// #define USE_APR_SHARED_MEMORY 1 + #define USE_WIN32_SHARED_MEMORY 1 +#elif LL_DARWIN + #define USE_SHM_OPEN_SHARED_MEMORY 1 +#elif LL_LINUX + #define USE_SHM_OPEN_SHARED_MEMORY 1 +#endif + + +// FIXME: This path thing is evil and unacceptable. +#if LL_WINDOWS + #define APR_SHARED_MEMORY_PREFIX_STRING "C:\\LLPlugin_" + // Apparnently using the "Global\\" prefix here only works from administrative accounts under Vista. + // Other options I've seen referenced are "Local\\" and "Session\\". + #define WIN32_SHARED_MEMORY_PREFIX_STRING "Local\\LL_" +#else + // mac and linux + #define APR_SHARED_MEMORY_PREFIX_STRING "/tmp/LLPlugin_" + #define SHM_OPEN_SHARED_MEMORY_PREFIX_STRING "/LL" +#endif + +#if USE_APR_SHARED_MEMORY + #include "llapr.h" + #include "apr_shm.h" +#elif USE_SHM_OPEN_SHARED_MEMORY + #include <sys/fcntl.h> + #include <sys/mman.h> + #include <errno.h> +#elif USE_WIN32_SHARED_MEMORY +#include <windows.h> +#endif // USE_APR_SHARED_MEMORY + + +int LLPluginSharedMemory::sSegmentNumber = 0; + +std::string LLPluginSharedMemory::createName(void) +{ + std::stringstream newname; + +#if LL_WINDOWS + newname << GetCurrentProcessId(); +#else // LL_WINDOWS + newname << getpid(); +#endif // LL_WINDOWS + + newname << "_" << sSegmentNumber++; + + return newname.str(); +} + +/** + * @brief LLPluginSharedMemoryImpl is the platform-dependent implementation of LLPluginSharedMemory. TODO:DOC is this necessary/sufficient? kinda obvious. + * + */ +class LLPluginSharedMemoryPlatformImpl +{ +public: + LLPluginSharedMemoryPlatformImpl(); + ~LLPluginSharedMemoryPlatformImpl(); + +#if USE_APR_SHARED_MEMORY + apr_shm_t* mAprSharedMemory; +#elif USE_SHM_OPEN_SHARED_MEMORY + int mSharedMemoryFD; +#elif USE_WIN32_SHARED_MEMORY + HANDLE mMapFile; +#endif + +}; + +/** + * Constructor. Creates a shared memory segment. + */ +LLPluginSharedMemory::LLPluginSharedMemory() +{ + mSize = 0; + mMappedAddress = NULL; + mNeedsDestroy = false; + + mImpl = new LLPluginSharedMemoryPlatformImpl; +} + +/** + * Destructor. Uses destroy() and detach() to ensure shared memory segment is cleaned up. + */ +LLPluginSharedMemory::~LLPluginSharedMemory() +{ + if(mNeedsDestroy) + destroy(); + else + detach(); + + unlink(); + + delete mImpl; +} + +#if USE_APR_SHARED_MEMORY +// MARK: apr implementation + +LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl() +{ + mAprSharedMemory = NULL; +} + +LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl() +{ + +} + +bool LLPluginSharedMemory::map(void) +{ + mMappedAddress = apr_shm_baseaddr_get(mImpl->mAprSharedMemory); + if(mMappedAddress == NULL) + { + return false; + } + + return true; +} + +bool LLPluginSharedMemory::unmap(void) +{ + // This is a no-op under apr. + return true; +} + +bool LLPluginSharedMemory::close(void) +{ + // This is a no-op under apr. + return true; +} + +bool LLPluginSharedMemory::unlink(void) +{ + // This is a no-op under apr. + return true; +} + + +bool LLPluginSharedMemory::create(size_t size) +{ + mName = APR_SHARED_MEMORY_PREFIX_STRING; + mName += createName(); + mSize = size; + + apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp ); + + if(ll_apr_warn_status(status)) + { + return false; + } + + mNeedsDestroy = true; + + return map(); +} + +bool LLPluginSharedMemory::destroy(void) +{ + if(mImpl->mAprSharedMemory) + { + apr_status_t status = apr_shm_destroy(mImpl->mAprSharedMemory); + if(ll_apr_warn_status(status)) + { + // TODO: Is this a fatal error? I think not... + } + mImpl->mAprSharedMemory = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::attach(const std::string &name, size_t size) +{ + mName = name; + mSize = size; + + apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp ); + + if(ll_apr_warn_status(status)) + { + return false; + } + + return map(); +} + + +bool LLPluginSharedMemory::detach(void) +{ + if(mImpl->mAprSharedMemory) + { + apr_status_t status = apr_shm_detach(mImpl->mAprSharedMemory); + if(ll_apr_warn_status(status)) + { + // TODO: Is this a fatal error? I think not... + } + mImpl->mAprSharedMemory = NULL; + } + + return true; +} + + +#elif USE_SHM_OPEN_SHARED_MEMORY +// MARK: shm_open/mmap implementation + +LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl() +{ + mSharedMemoryFD = -1; +} + +LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl() +{ +} + +bool LLPluginSharedMemory::map(void) +{ + mMappedAddress = ::mmap(NULL, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, mImpl->mSharedMemoryFD, 0); + if(mMappedAddress == NULL) + { + return false; + } + + LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL; + + return true; +} + +bool LLPluginSharedMemory::unmap(void) +{ + if(mMappedAddress != NULL) + { + LL_DEBUGS("Plugin") << "calling munmap(" << mMappedAddress << ", " << mSize << ")" << LL_ENDL; + if(::munmap(mMappedAddress, mSize) == -1) + { + // TODO: Is this a fatal error? I think not... + } + + mMappedAddress = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::close(void) +{ + if(mImpl->mSharedMemoryFD != -1) + { + LL_DEBUGS("Plugin") << "calling close(" << mImpl->mSharedMemoryFD << ")" << LL_ENDL; + if(::close(mImpl->mSharedMemoryFD) == -1) + { + // TODO: Is this a fatal error? I think not... + } + + mImpl->mSharedMemoryFD = -1; + } + return true; +} + +bool LLPluginSharedMemory::unlink(void) +{ + if(!mName.empty()) + { + if(::shm_unlink(mName.c_str()) == -1) + { + return false; + } + } + + return true; +} + + +bool LLPluginSharedMemory::create(size_t size) +{ + mName = SHM_OPEN_SHARED_MEMORY_PREFIX_STRING; + mName += createName(); + mSize = size; + + // Preemptive unlink, just in case something didn't get cleaned up. + unlink(); + + mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if(mImpl->mSharedMemoryFD == -1) + { + return false; + } + + mNeedsDestroy = true; + + if(::ftruncate(mImpl->mSharedMemoryFD, mSize) == -1) + { + return false; + } + + + return map(); +} + +bool LLPluginSharedMemory::destroy(void) +{ + unmap(); + close(); + + return true; +} + + +bool LLPluginSharedMemory::attach(const std::string &name, size_t size) +{ + mName = name; + mSize = size; + + mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_RDWR, S_IRUSR | S_IWUSR); + if(mImpl->mSharedMemoryFD == -1) + { + return false; + } + + // unlink here so the segment will be cleaned up automatically after the last close. + unlink(); + + return map(); +} + +bool LLPluginSharedMemory::detach(void) +{ + unmap(); + close(); + return true; +} + +#elif USE_WIN32_SHARED_MEMORY +// MARK: Win32 CreateFileMapping-based implementation + +// Reference: http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx + +LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl() +{ + mMapFile = NULL; +} + +LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl() +{ + +} + +bool LLPluginSharedMemory::map(void) +{ + mMappedAddress = MapViewOfFile( + mImpl->mMapFile, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + mSize); + + if(mMappedAddress == NULL) + { + LL_WARNS("Plugin") << "MapViewOfFile failed: " << GetLastError() << LL_ENDL; + return false; + } + + LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL; + + return true; +} + +bool LLPluginSharedMemory::unmap(void) +{ + if(mMappedAddress != NULL) + { + UnmapViewOfFile(mMappedAddress); + mMappedAddress = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::close(void) +{ + if(mImpl->mMapFile != NULL) + { + CloseHandle(mImpl->mMapFile); + mImpl->mMapFile = NULL; + } + + return true; +} + +bool LLPluginSharedMemory::unlink(void) +{ + // This is a no-op on Windows. + return true; +} + + +bool LLPluginSharedMemory::create(size_t size) +{ + mName = WIN32_SHARED_MEMORY_PREFIX_STRING; + mName += createName(); + mSize = size; + + mImpl->mMapFile = CreateFileMappingA( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // max. object size + mSize, // buffer size + mName.c_str()); // name of mapping object + + if(mImpl->mMapFile == NULL) + { + LL_WARNS("Plugin") << "CreateFileMapping failed: " << GetLastError() << LL_ENDL; + return false; + } + + mNeedsDestroy = true; + + return map(); +} + +bool LLPluginSharedMemory::destroy(void) +{ + unmap(); + close(); + return true; +} + +bool LLPluginSharedMemory::attach(const std::string &name, size_t size) +{ + mName = name; + mSize = size; + + mImpl->mMapFile = OpenFileMappingA( + FILE_MAP_ALL_ACCESS, // read/write access + FALSE, // do not inherit the name + mName.c_str()); // name of mapping object + + if(mImpl->mMapFile == NULL) + { + LL_WARNS("Plugin") << "OpenFileMapping failed: " << GetLastError() << LL_ENDL; + return false; + } + + return map(); +} + +bool LLPluginSharedMemory::detach(void) +{ + unmap(); + close(); + return true; +} + + + +#endif diff --git a/linden/indra/llplugin/llpluginsharedmemory.h b/linden/indra/llplugin/llpluginsharedmemory.h new file mode 100644 index 000000000..2dc550ea8 --- /dev/null +++ b/linden/indra/llplugin/llpluginsharedmemory.h @@ -0,0 +1,130 @@ +/** + * @file llpluginsharedmemory.h + * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPLUGINSHAREDMEMORY_H +#define LL_LLPLUGINSHAREDMEMORY_H + +class LLPluginSharedMemoryPlatformImpl; + +/** + * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. + * + */ +class LLPluginSharedMemory +{ + LOG_CLASS(LLPluginSharedMemory); +public: + LLPluginSharedMemory(); + ~LLPluginSharedMemory(); + + // Parent will use create/destroy, child will use attach/detach. + // Message transactions will ensure child attaches after parent creates and detaches before parent destroys. + + /** + * Creates a shared memory segment, with a name which is guaranteed to be unique on the host at the current time. Used by parent. + * Message transactions will (? TODO:DOC - should? must?) ensure child attaches after parent creates and detaches before parent destroys. + * + * @param[in] size Shared memory size in TODO:DOC units = bytes?. + * + * @return False for failure, true for success. + */ + bool create(size_t size); + /** + * Destroys a shared memory segment. Used by parent. + * Message transactions will (? TODO:DOC - should? must?) ensure child attaches after parent creates and detaches before parent destroys. + * + * @return True. TODO:DOC - always returns true. Is this the intended behavior? + */ + bool destroy(void); + + /** + * Creates and attaches a name to a shared memory segment. TODO:DOC what's the difference between attach() and create()? + * + * @param[in] name Name to attach to memory segment + * @param[in] size Size of memory segment TODO:DOC in bytes? + * + * @return False on failure, true otherwise. + */ + bool attach(const std::string &name, size_t size); + /** + * Detaches shared memory segment. + * + * @return False on failure, true otherwise. + */ + bool detach(void); + + /** + * Checks if shared memory is mapped to a non-null address. + * + * @return True if memory address is non-null, false otherwise. + */ + bool isMapped(void) const { return (mMappedAddress != NULL); }; + /** + * Get pointer to shared memory. + * + * @return Pointer to shared memory. + */ + void *getMappedAddress(void) const { return mMappedAddress; }; + /** + * Get size of shared memory. + * + * @return Size of shared memory in bytes. TODO:DOC are bytes the correct unit? + */ + size_t getSize(void) const { return mSize; }; + /** + * Get name of shared memory. + * + * @return Name of shared memory. + */ + std::string getName() const { return mName; }; + +private: + bool map(void); + bool unmap(void); + bool close(void); + bool unlink(void); + + std::string mName; + size_t mSize; + void *mMappedAddress; + bool mNeedsDestroy; + + LLPluginSharedMemoryPlatformImpl *mImpl; + + static int sSegmentNumber; + static std::string createName(); + +}; + + + +#endif // LL_LLPLUGINSHAREDMEMORY_H diff --git a/linden/indra/llplugin/slplugin/CMakeLists.txt b/linden/indra/llplugin/slplugin/CMakeLists.txt new file mode 100644 index 000000000..4a7d670c2 --- /dev/null +++ b/linden/indra/llplugin/slplugin/CMakeLists.txt @@ -0,0 +1,55 @@ +project(SLPlugin) + +include(00-Common) +include(LLCommon) +include(LLPlugin) +include(Linking) +include(PluginAPI) +include(LLMessage) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${LLMESSAGE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} +) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(CARBON_LIBRARY Carbon) +endif (DARWIN) + + +### SLPlugin + +set(SLPlugin_SOURCE_FILES + slplugin.cpp + ) + +add_executable(SLPlugin + WIN32 + ${SLPlugin_SOURCE_FILES} +) + +target_link_libraries(SLPlugin + ${LLPLUGIN_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +add_dependencies(SLPlugin + ${LLPLUGIN_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +if (DARWIN) + # Mac version needs to link against carbon, and also needs an embedded plist (to set LSBackgroundOnly) + target_link_libraries(SLPlugin ${CARBON_LIBRARY}) + set_target_properties( + SLPlugin + PROPERTIES + LINK_FLAGS "-Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist" + ) +endif (DARWIN) + diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp new file mode 100644 index 000000000..fa3924b6f --- /dev/null +++ b/linden/indra/llplugin/slplugin/slplugin.cpp @@ -0,0 +1,288 @@ +/** + * @file slplugin.cpp + * @brief Loader shell for plugins, intended to be launched by the plugin host application, which directly loads a plugin dynamic library. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "linden_common.h" + +#include "llpluginprocesschild.h" +#include "llpluginmessage.h" +#include "llerrorcontrol.h" +#include "llapr.h" +#include "llstring.h" + +#if LL_DARWIN + #include <Carbon/Carbon.h> +#endif + +#if LL_DARWIN || LL_LINUX + #include <signal.h> +#endif + +/* + On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly flag in the Info.plist. + + Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags: + + -sectcreate __TEXT __info_plist /path/to/slplugin_info.plist + + which means adding this to the gcc flags: + + -Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist + +*/ + +#if LL_DARWIN || LL_LINUX +// Signal handlers to make crashes not show an OS dialog... +static void crash_handler(int sig) +{ + // Just exit cleanly. + // TODO: add our own crash reporting + _exit(1); +} +#endif + +#if LL_WINDOWS +#include <windows.h> +//////////////////////////////////////////////////////////////////////////////// +// Our exception handler - will probably just exit and the host application +// will miss the heartbeat and log the error in the usual fashion. +LONG WINAPI myWin32ExceptionHandler( struct _EXCEPTION_POINTERS* exception_infop ) +{ + //std::cerr << "This plugin (" << __FILE__ << ") - "; + //std::cerr << "intercepted an unhandled exception and will exit immediately." << std::endl; + + // TODO: replace exception handler before we exit? + return EXCEPTION_EXECUTE_HANDLER; +} + +// Taken from : http://blog.kalmbachnet.de/?postid=75 +// The MSVC 2005 CRT forces the call of the default-debugger (normally Dr.Watson) +// even with the other exception handling code. This (terrifying) piece of code +// patches things so that doesn't happen. +LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter( + LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter ) +{ + return NULL; +} + +BOOL PreventSetUnhandledExceptionFilter() +{ +// WARNING: This won't work on 64-bit Windows systems so we turn it off it. +// It should work for any flavor of 32-bit Windows we care about. +// If it's off, sometimes you will see an OS message when a plugin crashes +#ifndef _WIN64 + HMODULE hKernel32 = LoadLibraryA( "kernel32.dll" ); + if ( NULL == hKernel32 ) + return FALSE; + + void *pOrgEntry = GetProcAddress( hKernel32, "SetUnhandledExceptionFilter" ); + if( NULL == pOrgEntry ) + return FALSE; + + unsigned char newJump[ 100 ]; + DWORD dwOrgEntryAddr = (DWORD)pOrgEntry; + dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far + void *pNewFunc = &MyDummySetUnhandledExceptionFilter; + DWORD dwNewEntryAddr = (DWORD) pNewFunc; + DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr; + + newJump[ 0 ] = 0xE9; // JMP absolute + memcpy( &newJump[ 1 ], &dwRelativeAddr, sizeof( pNewFunc ) ); + SIZE_T bytesWritten; + BOOL bRet = WriteProcessMemory( GetCurrentProcess(), pOrgEntry, newJump, sizeof( pNewFunc ) + 1, &bytesWritten ); + return bRet; +#else + return FALSE; +#endif +} + +//////////////////////////////////////////////////////////////////////////////// +// Hook our exception handler and replace the system one +void initExceptionHandler() +{ + LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; + + // save old exception handler in case we need to restore it at the end + prev_filter = SetUnhandledExceptionFilter( myWin32ExceptionHandler ); + PreventSetUnhandledExceptionFilter(); +} + +bool checkExceptionHandler() +{ + bool ok = true; + LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; + prev_filter = SetUnhandledExceptionFilter(myWin32ExceptionHandler); + + PreventSetUnhandledExceptionFilter(); + + if (prev_filter != myWin32ExceptionHandler) + { + LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with " << prev_filter << "!" << LL_ENDL; + ok = false; + } + + if (prev_filter == NULL) + { + ok = FALSE; + if (myWin32ExceptionHandler == NULL) + { + LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL; + } + else + { + LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with NULL!" << LL_ENDL; + } + } + + return ok; +} +#endif + +// If this application on Windows platform is a console application, a console is always +// created which is bad. Making it a Windows "application" via CMake settings but not +// adding any code to explicitly create windows does the right thing. +#if LL_WINDOWS +int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) +#else +int main(int argc, char **argv) +#endif +{ + ll_init_apr(); + + // Set up llerror logging + { + LLError::initForApplication("."); + LLError::setDefaultLevel(LLError::LEVEL_INFO); +// LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG); +// LLError::logToFile("slplugin.log"); + } + +#if LL_WINDOWS + if( strlen( lpCmdLine ) == 0 ) + { + LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL; + }; + + U32 port = 0; + if(!LLStringUtil::convertToU32(lpCmdLine, port)) + { + LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL; + }; + + // Insert our exception handler into the system so this plugin doesn't + // display a crash message if something bad happens. The host app will + // see the missing heartbeat and log appropriately. + initExceptionHandler(); +#elif LL_DARWIN || LL_LINUX + if(argc < 2) + { + LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL; + } + + U32 port = 0; + if(!LLStringUtil::convertToU32(argv[1], port)) + { + LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL; + } + + // Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown. + signal(SIGILL, &crash_handler); // illegal instruction +# if LL_DARWIN + signal(SIGEMT, &crash_handler); // emulate instruction executed +# endif // LL_DARWIN + signal(SIGFPE, &crash_handler); // floating-point exception + signal(SIGBUS, &crash_handler); // bus error + signal(SIGSEGV, &crash_handler); // segmentation violation + signal(SIGSYS, &crash_handler); // non-existent system call invoked +#endif + + LLPluginProcessChild *plugin = new LLPluginProcessChild(); + + plugin->init(port); + + LLTimer timer; + timer.start(); + +#if LL_WINDOWS + checkExceptionHandler(); +#endif + + while(!plugin->isDone()) + { + timer.reset(); + plugin->idle(); +#if LL_DARWIN + { + // Some plugins (webkit at least) will want an event loop. This qualifies. + EventRecord evt; + WaitNextEvent(0, &evt, 0, NULL); + } +#endif + F64 elapsed = timer.getElapsedTimeF64(); + F64 remaining = plugin->getSleepTime() - elapsed; + + if(remaining <= 0.0f) + { + // We've already used our full allotment. +// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, not sleeping" << LL_ENDL; + + // Still need to service the network... + plugin->pump(); + } + else + { + +// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL; +// timer.reset(); + + // This also services the network as needed. + plugin->sleep(remaining); + +// LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" << LL_ENDL; + } + +#if LL_WINDOWS + // More agressive checking of interfering exception handlers. + // Doesn't appear to be required so far - even for plugins + // that do crash with a single call to the intercept + // exception handler such as QuickTime. + //checkExceptionHandler(); +#endif + } + + delete plugin; + + ll_cleanup_apr(); + + return 0; +} + diff --git a/linden/indra/llplugin/slplugin/slplugin_info.plist b/linden/indra/llplugin/slplugin/slplugin_info.plist new file mode 100644 index 000000000..b1daf8742 --- /dev/null +++ b/linden/indra/llplugin/slplugin/slplugin_info.plist @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>LSBackgroundOnly</key> + <true/> +</dict> +</plist> diff --git a/linden/indra/llui/CMakeLists.txt b/linden/indra/llui/CMakeLists.txt index a0f80b4d7..e6b3b636a 100644 --- a/linden/indra/llui/CMakeLists.txt +++ b/linden/indra/llui/CMakeLists.txt @@ -3,11 +3,9 @@ project(llui) include(00-Common) -include(LLAudio) include(LLCommon) include(LLImage) include(LLMath) -include(LLMedia) include(LLMessage) include(LLRender) include(LLWindow) @@ -15,11 +13,9 @@ include(LLVFS) include(LLXML) include_directories( - ${LLAUDIO_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} ${LLIMAGE_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} - ${LLMEDIA_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} @@ -141,3 +137,14 @@ set_source_files_properties(${llui_HEADER_FILES} list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES}) add_library (llui ${llui_SOURCE_FILES}) +# Libraries on which this library depends, needed for Linux builds +# Sort by high-level to low-level +target_link_libraries(llui + llrender + llwindow + llimage + llvfs # ugh, just for LLDir + llxml + llcommon # must be after llimage, llwindow, llrender + llmath + ) diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp index 1a6c705ff..702e34e72 100644 --- a/linden/indra/llui/llbutton.cpp +++ b/linden/indra/llui/llbutton.cpp @@ -840,6 +840,11 @@ void LLButton::setColor(const LLColor4& color) setImageColor(color); } +void LLButton::setAlpha(F32 alpha) +{ + mImageColor.setAlpha(alpha); + mDisabledImageColor.setAlpha(alpha * 0.5f); +} void LLButton::setImageDisabled(LLPointer<LLUIImage> image) { diff --git a/linden/indra/llui/llbutton.h b/linden/indra/llui/llbutton.h index 724b77541..2174d952c 100644 --- a/linden/indra/llui/llbutton.h +++ b/linden/indra/llui/llbutton.h @@ -136,7 +136,8 @@ class LLButton void setImageColor(const std::string& color_control); void setImageColor(const LLColor4& c); - virtual void setColor(const LLColor4& c); + /*virtual*/ void setColor(const LLColor4& c); + /*virtual*/ void setAlpha(F32 alpha); void setImages(const std::string &image_name, const std::string &selected_name); void setDisabledImages(const std::string &image_name, const std::string &selected_name); diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index f6451a1c6..bb42ca34c 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp @@ -1459,9 +1459,9 @@ void LLFloater::draw() { if (hasFocus() && getDefaultButton()->getEnabled()) { - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); + LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); // is this button a direct descendent and not a nested widget (e.g. checkbox)? - BOOL focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && focus_ctrl->getParent() == this; + BOOL focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && dynamic_cast<LLButton*>(focus_ctrl)->getParent() == this; // only enable default button when current focus is not a button getDefaultButton()->setBorderEnabled(!focus_is_child_button); } @@ -1481,7 +1481,7 @@ void LLFloater::draw() else { // draw children - LLView* focused_child = gFocusMgr.getKeyboardFocus(); + LLView* focused_child = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus()); BOOL focused_child_visible = FALSE; if (focused_child && focused_child->getParent() == this) { @@ -2239,7 +2239,7 @@ BOOL LLFloaterView::allChildrenClosed() LLView* viewp = *it; LLFloater* floaterp = (LLFloater*)viewp; - if (floaterp->getVisible() && !floaterp->isDead() && floaterp->canClose()) + if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) { return false; } diff --git a/linden/indra/llui/llfocusmgr.cpp b/linden/indra/llui/llfocusmgr.cpp index 661ffdd46..96b01b98f 100644 --- a/linden/indra/llui/llfocusmgr.cpp +++ b/linden/indra/llui/llfocusmgr.cpp @@ -38,6 +38,68 @@ const F32 FOCUS_FADE_TIME = 0.3f; +// NOTE: the LLFocusableElement implementation has been here from lluictrl.cpp. + +LLFocusableElement::LLFocusableElement() +: mFocusLostCallback(NULL), + mFocusReceivedCallback(NULL), + mFocusChangedCallback(NULL), + mFocusCallbackUserData(NULL) +{ +} + +// virtual +BOOL LLFocusableElement::handleKey(KEY key, MASK mask, BOOL called_from_parent) +{ + return FALSE; +} + +// virtual +BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) +{ + return FALSE; +} + +// virtual +LLFocusableElement::~LLFocusableElement() +{ +} + +void LLFocusableElement::onFocusReceived() +{ + if( mFocusReceivedCallback ) + { + mFocusReceivedCallback( this, mFocusCallbackUserData ); + } + if( mFocusChangedCallback ) + { + mFocusChangedCallback( this, mFocusCallbackUserData ); + } +} + +void LLFocusableElement::onFocusLost() +{ + if( mFocusLostCallback ) + { + mFocusLostCallback( this, mFocusCallbackUserData ); + } + + if( mFocusChangedCallback ) + { + mFocusChangedCallback( this, mFocusCallbackUserData ); + } +} + +BOOL LLFocusableElement::hasFocus() const +{ + return gFocusMgr.getKeyboardFocus() == this; +} + +void LLFocusableElement::setFocus(BOOL b) +{ +} + + LLFocusMgr gFocusMgr; LLFocusMgr::LLFocusMgr() @@ -87,11 +149,13 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) } -void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystrokes_only) +void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) { if (mLockedView && (new_focus == NULL || - (new_focus != mLockedView && !new_focus->hasAncestor(mLockedView)))) + (new_focus != mLockedView + && dynamic_cast<LLView*>(new_focus) + && !dynamic_cast<LLView*>(new_focus)->hasAncestor(mLockedView)))) { // don't allow focus to go to anything that is not the locked focus // or one of its descendants @@ -121,7 +185,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke mFocusTimer.reset(); #ifdef _DEBUG - mKeyboardFocusName = new_focus ? new_focus->getName() : std::string("none"); + LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus); + mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none"); #endif // If we've got a default keyboard focus, and the caller is @@ -131,8 +196,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke mDefaultKeyboardFocus->setFocus(TRUE); } - LLView* focus_subtree = mKeyboardFocus; - LLView* viewp = mKeyboardFocus; + LLView* focus_subtree = dynamic_cast<LLView*>(mKeyboardFocus); + LLView* viewp = dynamic_cast<LLView*>(mKeyboardFocus); // find root-most focus root while(viewp) { @@ -146,7 +211,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke if (focus_subtree) { - mFocusHistory[focus_subtree->getHandle()] = mKeyboardFocus ? mKeyboardFocus->getHandle() : LLHandle<LLView>(); + LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus); + mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>(); } } @@ -160,7 +226,7 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke // Returns TRUE is parent or any descedent of parent has keyboard focus. BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const { - LLView* focus_view = mKeyboardFocus; + LLView* focus_view = dynamic_cast<LLView*>(mKeyboardFocus); while( focus_view ) { if( focus_view == parent ) @@ -190,7 +256,7 @@ BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const return FALSE; } -void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLView* focus ) +void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus ) { // should be ok to unlock here, as you have to know the locked view // in order to unlock it @@ -313,7 +379,7 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view ) void LLFocusMgr::lockFocus() { - mLockedView = mKeyboardFocus; + mLockedView = dynamic_cast<LLUICtrl*>(mKeyboardFocus); } void LLFocusMgr::unlockFocus() diff --git a/linden/indra/llui/llfocusmgr.h b/linden/indra/llui/llfocusmgr.h index aaeb25a87..88ede1aff 100644 --- a/linden/indra/llui/llfocusmgr.h +++ b/linden/indra/llui/llfocusmgr.h @@ -37,10 +37,39 @@ #include "llstring.h" #include "llframetimer.h" -#include "llview.h" +#include "llui.h" class LLUICtrl; class LLMouseHandler; +class LLView; + +class LLFocusableElement +{ + friend class LLFocusMgr; // allow access to focus change handlers +public: + LLFocusableElement(); + virtual ~LLFocusableElement(); + + virtual void setFocus( BOOL b ); + virtual BOOL hasFocus() const; + + void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } + void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; } + void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } + + // These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus. + virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); + +protected: + virtual void onFocusReceived(); + virtual void onFocusLost(); + void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata ); + void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata ); + void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata ); + void* mFocusCallbackUserData; +}; + class LLFocusMgr { @@ -55,11 +84,11 @@ class LLFocusMgr BOOL childHasMouseCapture( const LLView* parent ) const; // Keyboard Focus - void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus. - LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; } - LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; } + void setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus. + LLFocusableElement* getKeyboardFocus() const { return mKeyboardFocus; } + LLFocusableElement* getLastKeyboardFocus() const { return mLastKeyboardFocus; } BOOL childHasKeyboardFocus( const LLView* parent ) const; - void removeKeyboardFocusWithoutCallback( const LLView* focus ); + void removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus ); BOOL getKeystrokesOnly() { return mKeystrokesOnly; } void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; } @@ -75,8 +104,8 @@ class LLFocusMgr // If setKeyboardFocus(NULL) is called, and there is a non-NULL default // keyboard focus view, focus goes there. JC - void setDefaultKeyboardFocus(LLUICtrl* default_focus) { mDefaultKeyboardFocus = default_focus; } - LLUICtrl* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; } + void setDefaultKeyboardFocus(LLFocusableElement* default_focus) { mDefaultKeyboardFocus = default_focus; } + LLFocusableElement* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; } // Top View @@ -98,9 +127,9 @@ class LLFocusMgr LLMouseHandler* mMouseCaptor; // Mouse events are premptively routed to this object // Keyboard Focus - LLUICtrl* mKeyboardFocus; // Keyboard events are preemptively routed to this object - LLUICtrl* mLastKeyboardFocus; // who last had focus - LLUICtrl* mDefaultKeyboardFocus; + LLFocusableElement* mKeyboardFocus; // Keyboard events are preemptively routed to this object + LLFocusableElement* mLastKeyboardFocus; // who last had focus + LLFocusableElement* mDefaultKeyboardFocus; BOOL mKeystrokesOnly; // Top View diff --git a/linden/indra/llui/lliconctrl.cpp b/linden/indra/llui/lliconctrl.cpp index e73c8fe69..0df960e88 100644 --- a/linden/indra/llui/lliconctrl.cpp +++ b/linden/indra/llui/lliconctrl.cpp @@ -112,6 +112,12 @@ void LLIconCtrl::draw() LLUICtrl::draw(); } +// virtual +void LLIconCtrl::setAlpha(F32 alpha) +{ + mColor.setAlpha(alpha); +} + // virtual void LLIconCtrl::setValue(const LLSD& value ) { diff --git a/linden/indra/llui/lliconctrl.h b/linden/indra/llui/lliconctrl.h index 50778cf22..2506fb209 100644 --- a/linden/indra/llui/lliconctrl.h +++ b/linden/indra/llui/lliconctrl.h @@ -65,6 +65,8 @@ class LLIconCtrl virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; + /*virtual*/ void setAlpha(F32 alpha); + void setColor(const LLColor4& color) { mColor = color; } virtual LLXMLNodePtr getXML(bool save_children = true) const; diff --git a/linden/indra/llui/llmultisliderctrl.cpp b/linden/indra/llui/llmultisliderctrl.cpp index b76c2f677..f9ec6d5ee 100644 --- a/linden/indra/llui/llmultisliderctrl.cpp +++ b/linden/indra/llui/llmultisliderctrl.cpp @@ -34,9 +34,6 @@ #include "llmultisliderctrl.h" -#include "audioengine.h" -#include "sound_ids.h" - #include "llmath.h" #include "llfontgl.h" #include "llgl.h" diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index 709342b70..26137d7b1 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp @@ -203,6 +203,12 @@ void LLPanel::draw() LLView::draw(); } +/*virtual*/ +void LLPanel::setAlpha(F32 alpha) +{ + mBgColorOpaque.setAlpha(alpha); +} + void LLPanel::updateDefaultBtn() { // This method does not call LLView::draw() so callers will need @@ -213,8 +219,7 @@ void LLPanel::updateDefaultBtn() { if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) { - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); - LLButton* buttonp = dynamic_cast<LLButton*>(focus_ctrl); + LLButton* buttonp = dynamic_cast<LLButton*>(gFocusMgr.getKeyboardFocus()); BOOL focus_is_child_button = buttonp && buttonp->getCommitOnReturn(); // only enable default button when current focus is not a return-capturing button mDefaultBtn->setBorderEnabled(!focus_is_child_button); @@ -276,7 +281,7 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask ) { BOOL handled = FALSE; - LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); // handle user hitting ESC to defocus if (key == KEY_ESCAPE) @@ -800,6 +805,14 @@ void LLPanel::childSetColor(const std::string& id, const LLColor4& color) child->setColor(color); } } +void LLPanel::childSetAlpha(const std::string& id, F32 alpha) +{ + LLUICtrl* child = getChild<LLUICtrl>(id, true); + if (child) + { + child->setAlpha(alpha); + } +} LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const std::string& id) const { diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h index 756d02ef7..378b3578f 100644 --- a/linden/indra/llui/llpanel.h +++ b/linden/indra/llui/llpanel.h @@ -82,6 +82,8 @@ class LLPanel : public LLUICtrl, public boost::signals::trackable // From LLFocusableElement /*virtual*/ void setFocus( BOOL b ); + virtual void setAlpha(F32 alpha); + // New virtuals virtual void refresh(); // called in setFocus() @@ -174,6 +176,7 @@ class LLPanel : public LLUICtrl, public boost::signals::trackable void childSetUserData(const std::string& id, void* userdata); void childSetColor(const std::string& id, const LLColor4& color); + void childSetAlpha(const std::string& id, F32 alpha); LLCtrlSelectionInterface* childGetSelectionInterface(const std::string& id) const; LLCtrlListInterface* childGetListInterface(const std::string& id) const; diff --git a/linden/indra/llui/llsliderctrl.cpp b/linden/indra/llui/llsliderctrl.cpp index 8a13ed42d..51d43fbb7 100644 --- a/linden/indra/llui/llsliderctrl.cpp +++ b/linden/indra/llui/llsliderctrl.cpp @@ -34,8 +34,6 @@ #include "llsliderctrl.h" -#include "audioengine.h" - #include "llmath.h" #include "llfontgl.h" #include "llgl.h" diff --git a/linden/indra/llui/llspinctrl.cpp b/linden/indra/llui/llspinctrl.cpp index 7eccaca09..e66b20ee1 100644 --- a/linden/indra/llui/llspinctrl.cpp +++ b/linden/indra/llui/llspinctrl.cpp @@ -45,7 +45,6 @@ #include "lltextbox.h" #include "llkeyboard.h" #include "llmath.h" -#include "audioengine.h" #include "llcontrol.h" #include "llfocusmgr.h" #include "llresmgr.h" diff --git a/linden/indra/llui/lltextparser.cpp b/linden/indra/llui/lltextparser.cpp index 925b118f0..707dd0afd 100644 --- a/linden/indra/llui/lltextparser.cpp +++ b/linden/indra/llui/lltextparser.cpp @@ -1,6 +1,5 @@ /** - * @file lltexteditor.cpp - * @brief LLTextEditor base class + * @file lltextparser.cpp * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -32,6 +31,8 @@ #include "linden_common.h" +#include "lltextparser.h" + #include "llsd.h" #include "llsdserialize.h" #include "llerror.h" @@ -40,22 +41,12 @@ #include "message.h" #include "llmath.h" #include "v4color.h" -#include "audioengine.h" -#include "llwindow.h" #include "lldir.h" -#include "lltextparser.h" -//#include "lltexttospeech.h" - // Routines used for parsing text for TextParsers and html LLTextParser* LLTextParser::sInstance = NULL; -// -// Constants -// -const F32 SOUND_GAIN = 1.0f; - // // Member Functions // @@ -76,38 +67,7 @@ LLTextParser* LLTextParser::getInstance() return sInstance; } -void LLTextParser::triggerAlerts(LLUUID agent_id, LLVector3d position, std::string text, LLWindow* viewer_window) -{ -// bool spoken=FALSE; - for (S32 i=0;i<mHighlights.size();i++) - { - if (findPattern(text,mHighlights[i]) >= 0 ) - { - if(gAudiop) - { - if ((std::string)mHighlights[i]["sound_lluuid"] != LLUUID::null.asString()) - { - gAudiop->triggerSound(mHighlights[i]["sound_lluuid"].asUUID(), agent_id, SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, position); - } -/* - if (!spoken) - { - LLTextToSpeech* text_to_speech = NULL; - text_to_speech = LLTextToSpeech::getInstance(); - spoken = text_to_speech->speak((LLString)mHighlights[i]["voice"],text); - } - */ - } - if (mHighlights[i]["flash"]) - { - if (viewer_window && viewer_window->getMinimized()) - { - viewer_window->flashIcon(5.f); - } - } - } - } -} +// Moved triggerAlerts() to llfloaterchat.cpp to break llui/llaudio library dependency. S32 LLTextParser::findPattern(const std::string &text, LLSD highlight) { diff --git a/linden/indra/llui/lltextparser.h b/linden/indra/llui/lltextparser.h index d69e3a260..32343a2da 100644 --- a/linden/indra/llui/lltextparser.h +++ b/linden/indra/llui/lltextparser.h @@ -34,12 +34,8 @@ #ifndef LL_LLTEXTPARSER_H #define LL_LLTEXTPARSER_H -#include <vector> -#include "linden_common.h" +#include "llsd.h" -#include "lltextparser.h" - -class LLSD; class LLUUID; class LLVector3d; class LLColor4; @@ -59,7 +55,6 @@ class LLTextParser S32 findPattern(const std::string &text, LLSD highlight); LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color,S32 part=WHOLE, S32 index=0); bool parseFullLineHighlights(const std::string &text, LLColor4 *color); - void triggerAlerts(LLUUID agent_id, LLVector3d position, std::string text, LLWindow* viewer_window); std::string getFileName(); LLSD loadFromDisk(); diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp index 57ce13c9c..75a446782 100644 --- a/linden/indra/llui/llui.cpp +++ b/linden/indra/llui/llui.cpp @@ -38,7 +38,6 @@ #include <map> // Linden library includes -#include "audioengine.h" #include "v2math.h" #include "v4color.h" #include "llrender.h" diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp index 9d97312ab..3f4ab5e45 100644 --- a/linden/indra/llui/lluictrl.cpp +++ b/linden/indra/llui/lluictrl.cpp @@ -39,54 +39,7 @@ static LLRegisterWidget<LLUICtrl> r("ui_ctrl"); -LLFocusableElement::LLFocusableElement() -: mFocusLostCallback(NULL), - mFocusReceivedCallback(NULL), - mFocusChangedCallback(NULL), - mFocusCallbackUserData(NULL) -{ -} - -//virtual -LLFocusableElement::~LLFocusableElement() -{ -} - -void LLFocusableElement::onFocusReceived() -{ - if( mFocusReceivedCallback ) - { - mFocusReceivedCallback( this, mFocusCallbackUserData ); - } - if( mFocusChangedCallback ) - { - mFocusChangedCallback( this, mFocusCallbackUserData ); - } -} - -void LLFocusableElement::onFocusLost() -{ - if( mFocusLostCallback ) - { - mFocusLostCallback( this, mFocusCallbackUserData ); - } - - if( mFocusChangedCallback ) - { - mFocusChangedCallback( this, mFocusCallbackUserData ); - } -} - -BOOL LLFocusableElement::hasFocus() const -{ - return FALSE; -} - -void LLFocusableElement::setFocus(BOOL b) -{ -} - - +// NOTE: the LLFocusableElement implementation has been moved to llfocusmgr.cpp, to mirror the header where the class is defined. LLUICtrl::LLUICtrl() : mCommitCallback(NULL), @@ -212,7 +165,7 @@ void LLUICtrl::onFocusReceived() // find first view in hierarchy above new focus that is a LLUICtrl LLView* viewp = getParent(); - LLUICtrl* last_focus = gFocusMgr.getLastKeyboardFocus(); + LLUICtrl* last_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getLastKeyboardFocus()); while (viewp && !viewp->isCtrl()) { @@ -590,6 +543,10 @@ void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) ) // virtual void LLUICtrl::setColor(const LLColor4& color) { } +// virtual + +void LLUICtrl::setAlpha(F32 alpha) +{ } // virtual void LLUICtrl::setMinValue(LLSD min_value) diff --git a/linden/indra/llui/lluictrl.h b/linden/indra/llui/lluictrl.h index db41af847..be8e86336 100644 --- a/linden/indra/llui/lluictrl.h +++ b/linden/indra/llui/lluictrl.h @@ -39,31 +39,8 @@ #include "llsd.h" -class LLFocusableElement -{ - friend class LLFocusMgr; // allow access to focus change handlers -public: - LLFocusableElement(); - virtual ~LLFocusableElement(); - - virtual void setFocus( BOOL b ); - virtual BOOL hasFocus() const; - - void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } - void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; } - void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } - -protected: - virtual void onFocusReceived(); - virtual void onFocusLost(); - void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata ); - void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata ); - void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata ); - void* mFocusCallbackUserData; -}; - class LLUICtrl -: public LLView, public LLFocusableElement +: public LLView { public: typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); @@ -117,6 +94,7 @@ class LLUICtrl virtual void clear(); virtual void setDoubleClickCallback( void (*cb)(void*) ); virtual void setColor(const LLColor4& color); + virtual void setAlpha(F32 alpha); virtual void setMinValue(LLSD min_value); virtual void setMaxValue(LLSD max_value); diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index 8de376fb4..1f7669613 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp @@ -136,11 +136,6 @@ LLView::~LLView() { //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; // llassert(LLView::sIsDrawing == FALSE); - if( gFocusMgr.getKeyboardFocus() == this ) - { - llwarns << "View holding keyboard focus deleted: " << getName() << ". Keyboard focus removed." << llendl; - gFocusMgr.removeKeyboardFocusWithoutCallback( this ); - } if( hasMouseCapture() ) { @@ -1327,7 +1322,7 @@ void LLView::draw() LLRect screenRect; // draw focused control on top of everything else - LLView* focus_view = gFocusMgr.getKeyboardFocus(); + LLUICtrl* focus_view = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (focus_view && focus_view->getParent() != this) { focus_view = NULL; diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h index 7e09dfa44..1c8ab3154 100644 --- a/linden/indra/llui/llview.h +++ b/linden/indra/llui/llview.h @@ -53,6 +53,7 @@ #include "stdenums.h" #include "lluistring.h" #include "llcursortypes.h" +#include "llfocusmgr.h" const U32 FOLLOWS_NONE = 0x00; const U32 FOLLOWS_LEFT = 0x01; @@ -207,7 +208,7 @@ class LLRegisterWidget } }; -class LLView : public LLMouseHandler, public LLMortician +class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement { public: @@ -398,9 +399,11 @@ class LLView : public LLMouseHandler, public LLMortician virtual BOOL canSnapTo(const LLView* other_view); virtual void snappedTo(const LLView* snap_view); + + // inherited from LLFocusableElement + /* virtual */ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + /* virtual */ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); - virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); - virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, @@ -421,8 +424,9 @@ class LLView : public LLMouseHandler, public LLMortician BOOL getSaveToXML() const { return mSaveToXML; } void setSaveToXML(BOOL b) { mSaveToXML = b; } - virtual void onFocusLost(); - virtual void onFocusReceived(); + // inherited from LLFocusableElement + /* virtual */ void onFocusLost(); + /* virtual */ void onFocusReceived(); typedef enum e_hit_test_type { diff --git a/linden/indra/llvfs/CMakeLists.txt b/linden/indra/llvfs/CMakeLists.txt index cc0297e3d..d6a0bbc08 100644 --- a/linden/indra/llvfs/CMakeLists.txt +++ b/linden/indra/llvfs/CMakeLists.txt @@ -4,7 +4,6 @@ project(llvfs) include(00-Common) include(LLCommon) -include(UnixInstall) include_directories( ${LLCOMMON_INCLUDE_DIRS} @@ -58,6 +57,7 @@ set_source_files_properties(${llvfs_HEADER_FILES} list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES}) add_library (llvfs ${llvfs_SOURCE_FILES}) +add_dependencies(llvfs prepare) if (DARWIN) include(CMakeFindFrameworks) diff --git a/linden/indra/llvfs/lldir.cpp b/linden/indra/llvfs/lldir.cpp index af5559315..5567fddde 100644 --- a/linden/indra/llvfs/lldir.cpp +++ b/linden/indra/llvfs/lldir.cpp @@ -294,6 +294,10 @@ const std::string LLDir::getSkinBaseDir() const return dir; } +const std::string &LLDir::getLLPluginDir() const +{ + return mLLPluginDir; +} std::string LLDir::getExpandedFilename(ELLPath location, const std::string& filename) const { @@ -465,6 +469,8 @@ std::string LLDir::getDirName(const std::string& filepath) const std::string LLDir::getExtension(const std::string& filepath) const { + if (filepath.empty()) + return std::string(); std::string basename = getBaseFileName(filepath, false); std::size_t offset = basename.find_last_of('.'); std::string exten = (offset == std::string::npos || offset == 0) ? "" : basename.substr(offset+1); diff --git a/linden/indra/llvfs/lldir.h b/linden/indra/llvfs/lldir.h index 21dcf5bd7..55574d623 100644 --- a/linden/indra/llvfs/lldir.h +++ b/linden/indra/llvfs/lldir.h @@ -80,6 +80,10 @@ class LLDir virtual BOOL fileExists(const std::string &filename) const = 0; const std::string findFile(const std::string &filename, const std::string searchPath1 = "", const std::string searchPath2 = "", const std::string searchPath3 = "") const; + + virtual std::string getLLPluginLauncher() = 0; // full path and name for the plugin shell + virtual std::string getLLPluginFilename(std::string base_name) = 0; // full path and name to the plugin DSO for this base_name (i.e. 'FOO' -> '/bar/baz/libFOO.so') + const std::string &getExecutablePathAndName() const; // Full pathname of the executable const std::string &getAppName() const; // install directory under progams/ ie "SecondLife" const std::string &getExecutableDir() const; // Directory where the executable is located @@ -100,6 +104,7 @@ class LLDir const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default const std::string getSkinBaseDir() const; // folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins + const std::string &getLLPluginDir() const; // Directory containing plugins and plugin shell // Expanded filename std::string getExpandedFilename(ELLPath location, const std::string &filename) const; @@ -156,6 +161,7 @@ class LLDir std::string mSkinDir; // Location for current skin info. std::string mDefaultSkinDir; // Location for default skin info. std::string mUserSkinDir; // Location for user-modified skin info. + std::string mLLPluginDir; // Location for plugins and plugin shell }; void dir_exists_or_crash(const std::string &dir_name); diff --git a/linden/indra/llvfs/lldir_linux.cpp b/linden/indra/llvfs/lldir_linux.cpp index 8ff8c5d1c..ec0a4f468 100644 --- a/linden/indra/llvfs/lldir_linux.cpp +++ b/linden/indra/llvfs/lldir_linux.cpp @@ -94,11 +94,7 @@ LLDir_Linux::LLDir_Linux() mExecutablePathAndName = ""; mExecutableDir = tmp_str; mWorkingDir = tmp_str; -#ifdef APP_RO_DATA_DIR - mAppRODataDir = APP_RO_DATA_DIR; -#else mAppRODataDir = tmp_str; -#endif mOSUserDir = getCurrentUserHome(tmp_str); mOSUserAppDir = ""; mLindenUserDir = tmp_str; @@ -128,6 +124,33 @@ LLDir_Linux::LLDir_Linux() } } + mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; + +#ifdef APP_RO_DATA_DIR + const char* appRODataDir = APP_RO_DATA_DIR; + if(appRODataDir[0] == '/') + { + // We have a full path to the data directory. + mAppRODataDir = appRODataDir; + } + else if(appRODataDir[0] != '\0') + { + // We have a relative path to the data directory. Search + // for it in each potential install prefix containing the + // executable. + for(std::string prefix = getDirName(mExecutableDir); + !prefix.empty(); prefix = getDirName(prefix)) + { + std::string dir = prefix + "/" + appRODataDir; + if(fileExists(dir + "/app_settings")) + { + mAppRODataDir = dir; + break; + } + } + } +#endif + // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something. mTempDir = "/tmp"; } @@ -370,3 +393,15 @@ BOOL LLDir_Linux::fileExists(const std::string &filename) const } } + +/*virtual*/ std::string LLDir_Linux::getLLPluginLauncher() +{ + return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() + + "SLPlugin"; +} + +/*virtual*/ std::string LLDir_Linux::getLLPluginFilename(std::string base_name) +{ + return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() + + "lib" + base_name + ".so"; +} diff --git a/linden/indra/llvfs/lldir_linux.h b/linden/indra/llvfs/lldir_linux.h index 20b408f8d..8e94fb1c9 100644 --- a/linden/indra/llvfs/lldir_linux.h +++ b/linden/indra/llvfs/lldir_linux.h @@ -52,6 +52,9 @@ class LLDir_Linux : public LLDir virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname); /*virtual*/ BOOL fileExists(const std::string &filename) const; + /*virtual*/ std::string getLLPluginLauncher(); + /*virtual*/ std::string getLLPluginFilename(std::string base_name); + private: DIR *mDirp; int mCurrentDirIndex; diff --git a/linden/indra/llvfs/lldir_mac.cpp b/linden/indra/llvfs/lldir_mac.cpp index 6d5dcf3f9..a45c1ed5f 100644 --- a/linden/indra/llvfs/lldir_mac.cpp +++ b/linden/indra/llvfs/lldir_mac.cpp @@ -190,6 +190,8 @@ LLDir_Mac::LLDir_Mac() } mWorkingDir = getCurPath(); + + mLLPluginDir = mAppRODataDir + mDirDelimiter + "llplugin"; CFRelease(executableURLRef); executableURLRef = NULL; @@ -388,4 +390,17 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const } +/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher() +{ + return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() + + "SLPlugin"; +} + +/*virtual*/ std::string LLDir_Mac::getLLPluginFilename(std::string base_name) +{ + return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() + + base_name + ".dylib"; +} + + #endif // LL_DARWIN diff --git a/linden/indra/llvfs/lldir_mac.h b/linden/indra/llvfs/lldir_mac.h index 28d48a0b6..8be5d03b2 100644 --- a/linden/indra/llvfs/lldir_mac.h +++ b/linden/indra/llvfs/lldir_mac.h @@ -52,6 +52,9 @@ class LLDir_Mac : public LLDir virtual void getRandomFileInDir(const std::string &dirname, const std::string &ask, std::string &fname); virtual BOOL fileExists(const std::string &filename) const; + /*virtual*/ std::string getLLPluginLauncher(); + /*virtual*/ std::string getLLPluginFilename(std::string base_name); + private: int mCurrentDirIndex; int mCurrentDirCount; diff --git a/linden/indra/llvfs/lldir_solaris.cpp b/linden/indra/llvfs/lldir_solaris.cpp index 9553d923a..c647e2bd1 100644 --- a/linden/indra/llvfs/lldir_solaris.cpp +++ b/linden/indra/llvfs/lldir_solaris.cpp @@ -161,6 +161,8 @@ LLDir_Solaris::LLDir_Solaris() } } + mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; + // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something. mTempDir = "/tmp"; } diff --git a/linden/indra/llvfs/lldir_win32.cpp b/linden/indra/llvfs/lldir_win32.cpp index 19b9bcc6e..9d4c5ecc8 100644 --- a/linden/indra/llvfs/lldir_win32.cpp +++ b/linden/indra/llvfs/lldir_win32.cpp @@ -143,6 +143,8 @@ LLDir_Win32::LLDir_Win32() llwarns << "Couldn't create LL_PATH_CACHE dir " << mDefaultCacheDir << llendl; } } + + mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; } LLDir_Win32::~LLDir_Win32() @@ -378,6 +380,19 @@ BOOL LLDir_Win32::fileExists(const std::string &filename) const } +/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher() +{ + return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() + + "SLPlugin.exe"; +} + +/*virtual*/ std::string LLDir_Win32::getLLPluginFilename(std::string base_name) +{ + return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() + + base_name + ".dll"; +} + + #if 0 // Utility function to get version number of a DLL diff --git a/linden/indra/llvfs/lldir_win32.h b/linden/indra/llvfs/lldir_win32.h index 8710ca50e..9ef4d300b 100644 --- a/linden/indra/llvfs/lldir_win32.h +++ b/linden/indra/llvfs/lldir_win32.h @@ -49,6 +49,9 @@ class LLDir_Win32 : public LLDir /*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname); /*virtual*/ BOOL fileExists(const std::string &filename) const; + /*virtual*/ std::string getLLPluginLauncher(); + /*virtual*/ std::string getLLPluginFilename(std::string base_name); + private: BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname, BOOL wrap); diff --git a/linden/indra/llwindow/CMakeLists.txt b/linden/indra/llwindow/CMakeLists.txt index afce0c06c..522416349 100644 --- a/linden/indra/llwindow/CMakeLists.txt +++ b/linden/indra/llwindow/CMakeLists.txt @@ -19,7 +19,6 @@ include(LLRender) include(LLVFS) include(LLWindow) include(LLXML) -include(Mozlib) include(UI) include_directories( @@ -55,6 +54,13 @@ set(viewer_HEADER_FILES llmousehandler.h ) +# Libraries on which this library depends, needed for Linux builds +# Sort by high-level to low-level +set(llwindow_LINK_LIBRARIES + ${UI_LIBRARIES} # for GTK + ${SDL_LIBRARY} + ) + if (DARWIN) list(APPEND llwindow_SOURCE_FILES llkeyboardmacosx.cpp @@ -98,6 +104,9 @@ if (WINDOWS) lldxhardware.h llkeyboardwin32.h ) + list(APPEND llwindow_LINK_LIBRARIES + comdlg32 # Common Dialogs for ChooseColor + ) endif (WINDOWS) if (SOLARIS) @@ -134,6 +143,7 @@ if (SERVER AND NOT WINDOWS AND NOT DARWIN) ${server_SOURCE_FILES} ) endif (SERVER AND NOT WINDOWS AND NOT DARWIN) + # *TODO: This should probably have target_link_libraries if (llwindow_HEADER_FILES) list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES}) @@ -145,4 +155,6 @@ if (VIEWER) ${llwindow_SOURCE_FILES} ${viewer_SOURCE_FILES} ) + target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) endif (VIEWER) + diff --git a/linden/indra/media_plugins/CMakeLists.txt b/linden/indra/media_plugins/CMakeLists.txt new file mode 100644 index 000000000..d35afd8cb --- /dev/null +++ b/linden/indra/media_plugins/CMakeLists.txt @@ -0,0 +1,11 @@ +# -*- cmake -*- + +add_subdirectory(base) + +add_subdirectory(webkit) + +add_subdirectory(gstreamer010) + +if (WINDOWS OR DARWIN) + add_subdirectory(quicktime) +endif (WINDOWS OR DARWIN) diff --git a/linden/indra/media_plugins/base/CMakeLists.txt b/linden/indra/media_plugins/base/CMakeLists.txt new file mode 100644 index 000000000..f8d2dabc6 --- /dev/null +++ b/linden/indra/media_plugins/base/CMakeLists.txt @@ -0,0 +1,41 @@ +# -*- cmake -*- + +project(media_plugin_base) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(FindOpenGL) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} +) + + +### media_plugin_base + +set(media_plugin_base_SOURCE_FILES + media_plugin_base.cpp +) + +set(media_plugin_base_HEADER_FILES + CMakeLists.txt + + media_plugin_base.h +) + +add_library(media_plugin_base + ${media_plugin_base_SOURCE_FILES} +) + diff --git a/linden/indra/media_plugins/base/media_plugin_base.cpp b/linden/indra/media_plugins/base/media_plugin_base.cpp new file mode 100644 index 000000000..19194196d --- /dev/null +++ b/linden/indra/media_plugins/base/media_plugin_base.cpp @@ -0,0 +1,155 @@ +/** + * @file media_plugin_base.cpp + * @brief Media plugin base class for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "media_plugin_base.h" + + +// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint +//////////////////////////////////////////////////////////////////////////////// +// + +MediaPluginBase::MediaPluginBase( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) +{ + mHostSendFunction = host_send_func; + mHostUserData = host_user_data; + mDeleteMe = false; + mPixels = 0; + mWidth = 0; + mHeight = 0; + mTextureWidth = 0; + mTextureHeight = 0; + mDepth = 0; + mStatus = STATUS_NONE; +} + +std::string MediaPluginBase::statusString() +{ + std::string result; + + switch(mStatus) + { + case STATUS_LOADING: result = "loading"; break; + case STATUS_LOADED: result = "loaded"; break; + case STATUS_ERROR: result = "error"; break; + case STATUS_PLAYING: result = "playing"; break; + case STATUS_PAUSED: result = "paused"; break; + default: + // keep the empty string + break; + } + + return result; +} + +void MediaPluginBase::setStatus(EStatus status) +{ + if(mStatus != status) + { + mStatus = status; + sendStatus(); + } +} + + +void MediaPluginBase::staticReceiveMessage(const char *message_string, void **user_data) +{ + MediaPluginBase *self = (MediaPluginBase*)*user_data; + + if(self != NULL) + { + self->receiveMessage(message_string); + + // If the plugin has processed the delete message, delete it. + if(self->mDeleteMe) + { + delete self; + *user_data = NULL; + } + } +} + +void MediaPluginBase::sendMessage(const LLPluginMessage &message) +{ + std::string output = message.generate(); + mHostSendFunction(output.c_str(), &mHostUserData); +} + +void MediaPluginBase::setDirty(int left, int top, int right, int bottom) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueS32("left", left); + message.setValueS32("top", top); + message.setValueS32("right", right); + message.setValueS32("bottom", bottom); + + sendMessage(message); +} + +void MediaPluginBase::sendStatus() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "media_status"); + + message.setValue("status", statusString()); + + sendMessage(message); +} + + +#if LL_WINDOWS +# define LLSYMEXPORT __declspec(dllexport) +#elif LL_LINUX +# define LLSYMEXPORT __attribute__ ((visibility("default"))) +#else +# define LLSYMEXPORT /**/ +#endif + +extern "C" +{ + LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); +} + +LLSYMEXPORT int +LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return init_media_plugin(host_send_func, host_user_data, plugin_send_func, plugin_user_data); +} + +#ifdef WIN32 +int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* params ) +{ + return 1; +} +#endif diff --git a/linden/indra/media_plugins/base/media_plugin_base.exp b/linden/indra/media_plugins/base/media_plugin_base.exp new file mode 100644 index 000000000..1e27d1f12 --- /dev/null +++ b/linden/indra/media_plugins/base/media_plugin_base.exp @@ -0,0 +1 @@ +_LLPluginInitEntryPoint diff --git a/linden/indra/media_plugins/base/media_plugin_base.h b/linden/indra/media_plugins/base/media_plugin_base.h new file mode 100644 index 000000000..487270601 --- /dev/null +++ b/linden/indra/media_plugins/base/media_plugin_base.h @@ -0,0 +1,112 @@ +/** + * @file media_plugin_base.h + * @brief Media plugin base class for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" + + +class MediaPluginBase +{ +public: + MediaPluginBase(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + virtual ~MediaPluginBase() {} + + virtual void receiveMessage(const char *message_string) = 0; + + static void staticReceiveMessage(const char *message_string, void **user_data); + +protected: + + typedef enum + { + STATUS_NONE, + STATUS_LOADING, + STATUS_LOADED, + STATUS_ERROR, + STATUS_PLAYING, + STATUS_PAUSED, + } EStatus; + + class SharedSegmentInfo + { + public: + void *mAddress; + size_t mSize; + }; + + void sendMessage(const LLPluginMessage &message); + void sendStatus(); + std::string statusString(); + void setStatus(EStatus status); + + // The quicktime plugin overrides this to add current time and duration to the message... + virtual void setDirty(int left, int top, int right, int bottom); + + typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap; + + + LLPluginInstance::sendMessageFunction mHostSendFunction; + void *mHostUserData; + bool mDeleteMe; + unsigned char* mPixels; + std::string mTextureSegmentName; + int mWidth; + int mHeight; + int mTextureWidth; + int mTextureHeight; + int mDepth; + EStatus mStatus; + SharedSegmentMap mSharedSegments; + +}; + +// The plugin must define this function to create its instance. +int init_media_plugin( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data); + +// It should look something like this: +/* +{ + MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data); + *plugin_send_func = MediaPluginFoo::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} +*/ + diff --git a/linden/indra/media_plugins/example/CMakeLists.txt b/linden/indra/media_plugins/example/CMakeLists.txt new file mode 100644 index 000000000..4d82f2747 --- /dev/null +++ b/linden/indra/media_plugins/example/CMakeLists.txt @@ -0,0 +1,74 @@ +# -*- cmake -*- + +project(media_plugin_example) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(FindOpenGL) + +include(ExamplePlugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} +) + + +### media_plugin_example + +set(media_plugin_example_SOURCE_FILES + media_plugin_example.cpp + ) + +add_library(media_plugin_example + SHARED + ${media_plugin_example_SOURCE_FILES} +) + +target_link_libraries(media_plugin_example + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${EXAMPLE_PLUGIN_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +add_dependencies(media_plugin_example + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +if (WINDOWS) + set_target_properties( + media_plugin_example + PROPERTIES + LINK_FLAGS "/MANIFEST:NO" + ) +endif (WINDOWS) + +if (DARWIN) + # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name + set_target_properties( + media_plugin_example + PROPERTIES + PREFIX "" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path" + LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" + ) + +endif (DARWIN) \ No newline at end of file diff --git a/linden/indra/media_plugins/example/media_plugin_example.cpp b/linden/indra/media_plugins/example/media_plugin_example.cpp new file mode 100644 index 000000000..99e0199a2 --- /dev/null +++ b/linden/indra/media_plugins/example/media_plugin_example.cpp @@ -0,0 +1,488 @@ +/** + * @file media_plugin_example.cpp + * @brief Example plugin for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgl.h" +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#include <time.h> + +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginExample : + public MediaPluginBase +{ + public: + MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ); + ~MediaPluginExample(); + + /*virtual*/ void receiveMessage( const char* message_string ); + + private: + bool init(); + void update( F64 milliseconds ); + void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ); + bool mFirstTime; + + time_t mLastUpdateTime; + enum Constants { ENumObjects = 10 }; + unsigned char* mBackgroundPixels; + int mColorR[ ENumObjects ]; + int mColorG[ ENumObjects ]; + int mColorB[ ENumObjects ]; + int mXpos[ ENumObjects ]; + int mYpos[ ENumObjects ]; + int mXInc[ ENumObjects ]; + int mYInc[ ENumObjects ]; + int mBlockSize[ ENumObjects ]; + bool mMouseButtonDown; + bool mStopAction; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginExample::MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : + MediaPluginBase( host_send_func, host_user_data ) +{ + mFirstTime = true; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + mMouseButtonDown = false; + mStopAction = false; + mLastUpdateTime = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginExample::~MediaPluginExample() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginExample::receiveMessage( const char* message_string ) +{ + LLPluginMessage message_in; + + if ( message_in.parse( message_string ) >= 0 ) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + + if ( message_class == LLPLUGIN_MESSAGE_CLASS_BASE ) + { + if ( message_name == "init" ) + { + LLPluginMessage message( "base", "init_response" ); + LLSD versions = LLSD::emptyMap(); + versions[ LLPLUGIN_MESSAGE_CLASS_BASE ] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[ LLPLUGIN_MESSAGE_CLASS_MEDIA ] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[ LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER ] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD( "versions", versions ); + + std::string plugin_version = "Example media plugin, Example Version 1.0.0.0"; + message.setValue( "plugin_version", plugin_version ); + sendMessage( message ); + + // Plugin gets to decide the texture parameters to use. + message.setMessage( LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params" ); + message.setValueS32( "default_width", mWidth ); + message.setValueS32( "default_height", mHeight ); + message.setValueS32( "depth", mDepth ); + message.setValueU32( "internalformat", GL_RGBA ); + message.setValueU32( "format", GL_RGBA ); + message.setValueU32( "type", GL_UNSIGNED_BYTE ); + message.setValueBoolean( "coords_opengl", false ); + sendMessage( message ); + } + else + if ( message_name == "idle" ) + { + // no response is necessary here. + F64 time = message_in.getValueReal( "time" ); + + // Convert time to milliseconds for update() + update( time ); + } + else + if ( message_name == "cleanup" ) + { + // clean up here + } + else + if ( message_name == "shm_added" ) + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer( "address" ); + info.mSize = ( size_t )message_in.getValueS32( "size" ); + std::string name = message_in.getValue( "name" ); + + mSharedSegments.insert( SharedSegmentMap::value_type( name, info ) ); + + } + else + if ( message_name == "shm_remove" ) + { + std::string name = message_in.getValue( "name" ); + + SharedSegmentMap::iterator iter = mSharedSegments.find( name ); + if( iter != mSharedSegments.end() ) + { + if ( mPixels == iter->second.mAddress ) + { + // This is the currently active pixel buffer. + // Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + }; + mSharedSegments.erase( iter ); + } + else + { + //std::cerr << "MediaPluginExample::receiveMessage: unknown shared memory region!" << std::endl; + }; + + // Send the response so it can be cleaned up. + LLPluginMessage message( "base", "shm_remove_response" ); + message.setValue( "name", name ); + sendMessage( message ); + } + else + { + //std::cerr << "MediaPluginExample::receiveMessage: unknown base message: " << message_name << std::endl; + }; + } + else + if ( message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA ) + { + if ( message_name == "size_change" ) + { + std::string name = message_in.getValue( "name" ); + S32 width = message_in.getValueS32( "width" ); + S32 height = message_in.getValueS32( "height" ); + S32 texture_width = message_in.getValueS32( "texture_width" ); + S32 texture_height = message_in.getValueS32( "texture_height" ); + + if ( ! name.empty() ) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find( name ); + if ( iter != mSharedSegments.end() ) + { + mPixels = ( unsigned char* )iter->second.mAddress; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + init(); + }; + }; + + LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response" ); + message.setValue( "name", name ); + message.setValueS32( "width", width ); + message.setValueS32( "height", height ); + message.setValueS32( "texture_width", texture_width ); + message.setValueS32( "texture_height", texture_height ); + sendMessage( message ); + } + else + if ( message_name == "load_uri" ) + { + std::string uri = message_in.getValue( "uri" ); + if ( ! uri.empty() ) + { + }; + } + else + if ( message_name == "mouse_event" ) + { + std::string event = message_in.getValue( "event" ); + S32 button = message_in.getValueS32( "button" ); + + // left mouse button + if ( button == 0 ) + { + int mouse_x = message_in.getValueS32( "x" ); + int mouse_y = message_in.getValueS32( "y" ); + std::string modifiers = message_in.getValue( "modifiers" ); + + if ( event == "move" ) + { + if ( mMouseButtonDown ) + write_pixel( mouse_x, mouse_y, rand() % 0x80 + 0x80, rand() % 0x80 + 0x80, rand() % 0x80 + 0x80 ); + } + else + if ( event == "down" ) + { + mMouseButtonDown = true; + } + else + if ( event == "up" ) + { + mMouseButtonDown = false; + } + else + if ( event == "double_click" ) + { + }; + }; + } + else + if ( message_name == "key_event" ) + { + std::string event = message_in.getValue( "event" ); + S32 key = message_in.getValueS32( "key" ); + std::string modifiers = message_in.getValue( "modifiers" ); + + if ( event == "down" ) + { + if ( key == ' ') + { + mLastUpdateTime = 0; + update( 0.0f ); + }; + }; + } + else + { + //std::cerr << "MediaPluginExample::receiveMessage: unknown media message: " << message_string << std::endl; + }; + } + else + if ( message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER ) + { + if ( message_name == "browse_reload" ) + { + mLastUpdateTime = 0; + mFirstTime = true; + mStopAction = false; + update( 0.0f ); + } + else + if ( message_name == "browse_stop" ) + { + for( int n = 0; n < ENumObjects; ++n ) + mXInc[ n ] = mYInc[ n ] = 0; + + mStopAction = true; + update( 0.0f ); + } + else + { + //std::cerr << "MediaPluginExample::receiveMessage: unknown media_browser message: " << message_string << std::endl; + }; + } + else + { + //std::cerr << "MediaPluginExample::receiveMessage: unknown message class: " << message_class << std::endl; + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginExample::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ) +{ + // make sure we don't write outside the buffer + if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) ) + return; + + if ( mBackgroundPixels != NULL ) + { + unsigned char *pixel = mBackgroundPixels; + pixel += y * mWidth * mDepth; + pixel += ( x * mDepth ); + pixel[ 0 ] = b; + pixel[ 1 ] = g; + pixel[ 2 ] = r; + + setDirty( x, y, x + 1, y + 1 ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginExample::update( F64 milliseconds ) +{ + if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 ) + return; + + if ( mPixels == 0 ) + return; + + if ( mFirstTime ) + { + for( int n = 0; n < ENumObjects; ++n ) + { + mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 ); + mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 ); + + mColorR[ n ] = rand() % 0x60 + 0x60; + mColorG[ n ] = rand() % 0x60 + 0x60; + mColorB[ n ] = rand() % 0x60 + 0x60; + + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + + mBlockSize[ n ] = rand() % 0x30 + 0x10; + }; + + delete [] mBackgroundPixels; + + mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ]; + + mFirstTime = false; + }; + + if ( mStopAction ) + return; + + if ( time( NULL ) > mLastUpdateTime + 3 ) + { + const int num_squares = rand() % 20 + 4; + int sqr1_r = rand() % 0x80 + 0x20; + int sqr1_g = rand() % 0x80 + 0x20; + int sqr1_b = rand() % 0x80 + 0x20; + int sqr2_r = rand() % 0x80 + 0x20; + int sqr2_g = rand() % 0x80 + 0x20; + int sqr2_b = rand() % 0x80 + 0x20; + + for ( int y1 = 0; y1 < num_squares; ++y1 ) + { + for ( int x1 = 0; x1 < num_squares; ++x1 ) + { + int px_start = mWidth * x1 / num_squares; + int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares; + int py_start = mHeight * y1 / num_squares; + int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares; + + for( int y2 = py_start; y2 < py_end; ++y2 ) + { + for( int x2 = px_start; x2 < px_end; ++x2 ) + { + int rowspan = mWidth * mDepth; + + if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b; + } + else + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b; + }; + }; + }; + }; + }; + + time( &mLastUpdateTime ); + }; + + memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth ); + + for( int n = 0; n < ENumObjects; ++n ) + { + if ( rand() % 50 == 0 ) + { + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + }; + + if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] ) + mXInc[ n ] =- mXInc[ n ]; + + if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] ) + mYInc[ n ] =- mYInc[ n ]; + + mXpos[ n ] += mXInc[ n ]; + mYpos[ n ] += mYInc[ n ]; + + for( int y = 0; y < mBlockSize[ n ]; ++y ) + { + for( int x = 0; x < mBlockSize[ n ]; ++x ) + { + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ]; + }; + }; + }; + + setDirty( 0, 0, mWidth, mHeight ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginExample::init() +{ + LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" ); + message.setValue( "name", "Example Plugin" ); + sendMessage( message ); + + return true; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data ) +{ + MediaPluginExample* self = new MediaPluginExample( host_send_func, host_user_data ); + *plugin_send_func = MediaPluginExample::staticReceiveMessage; + *plugin_user_data = ( void* )self; + + return 0; +} diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt new file mode 100644 index 000000000..a3a32d804 --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -0,0 +1,71 @@ +# -*- cmake -*- + +project(media_plugin_gstreamer010) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(FindOpenGL) + +include(GStreamer010Plugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} + ${GSTREAMER010_INCLUDE_DIRS} + ${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS} +) + +### media_plugin_gstreamer010 + +set(media_plugin_gstreamer010_SOURCE_FILES + media_plugin_gstreamer010.cpp + llmediaimplgstreamer_syms.cpp + llmediaimplgstreamervidplug.cpp + ) + +set(media_plugin_gstreamer010_HEADER_FILES + llmediaimplgstreamervidplug.h + llmediaimplgstreamer_syms.h + llmediaimplgstreamertriviallogging.h + ) + +#awfixme if (${CXX_VERSION_NUMBER} MATCHES "4[23].") + # Work around a bad interaction between broken gstreamer headers and + # g++ 4.3's increased strictness. + set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES + COMPILE_FLAGS -Wno-write-strings) +#awfixme endif (${CXX_VERSION_NUMBER} MATCHES "4[23].") + +add_library(media_plugin_gstreamer010 + SHARED + ${media_plugin_gstreamer010_SOURCE_FILES} +) + +target_link_libraries(media_plugin_gstreamer010 + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} + ${GSTREAMER010_LIBRARIES} +) + +add_dependencies(media_plugin_gstreamer010 + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + + diff --git a/linden/indra/llmedia/llmediaimplregister.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h similarity index 66% rename from linden/indra/llmedia/llmediaimplregister.h rename to linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h index 51912742f..ef41736c1 100644 --- a/linden/indra/llmedia/llmediaimplregister.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h @@ -1,6 +1,7 @@ -/** - * @file llmediaimplregister.h - * @brief Allow impls to register themselves with the impl factory +/** + * @file llmediaimplgstreamer.h + * @author Tofu Linden + * @brief implementation that supports media playback via GStreamer. * * $LicenseInfo:firstyear=2007&license=viewergpl$ * @@ -30,31 +31,27 @@ * $/LicenseInfo$ */ -#ifndef LLIMEDIAIMPLREGISTER_H -#define LLIMEDIAIMPLREGISTER_H +// header guard +#ifndef llmediaimplgstreamer_h +#define llmediaimplgstreamer_h -#include <string> +#if LL_GSTREAMER010_ENABLED -#include "llmediaimplfactory.h" +extern "C" { +#include <stdio.h> +#include <gst/gst.h> -/////////////////////////////////////////////////////////////////////////////// -// -class LLMediaImplRegister -{ - public: - LLMediaImplRegister( std::string impl_name, LLMediaImplMaker* impl_maker ) : - mImplName( impl_name ) - { - LLMediaImplFactory::getInstance()->registerImpl( impl_name, impl_maker ); - }; +#include "apr_pools.h" +#include "apr_dso.h" +} - std::string getImplName() - { - return mImplName; - }; - private: - std::string mImplName; -}; +extern "C" { +gboolean llmediaimplgstreamer_bus_callback (GstBus *bus, + GstMessage *message, + gpointer data); +} -#endif // LLIMEDIAIMPLREGISTER_H +#endif // LL_GSTREAMER010_ENABLED + +#endif // llmediaimplgstreamer_h diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp new file mode 100644 index 000000000..cc5223249 --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp @@ -0,0 +1,171 @@ +/** + * @file llmediaimplgstreamer_syms.cpp + * @brief dynamic GStreamer symbol-grabbing code + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#if LL_GSTREAMER010_ENABLED + +#include <string> + +extern "C" { +#include <gst/gst.h> + +#include "apr_pools.h" +#include "apr_dso.h" +} + +#include "llmediaimplgstreamertriviallogging.h" + +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL +#include "llmediaimplgstreamer_syms_raw.inc" +#include "llmediaimplgstreamer_syms_rawv.inc" +#undef LL_GST_SYM + +// a couple of stubs for disgusting reasons +GstDebugCategory* +ll_gst_debug_category_new(gchar *name, guint color, gchar *description) +{ + static GstDebugCategory dummy; + return &dummy; +} +void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname) +{ +} + +static bool sSymsGrabbed = false; +static apr_pool_t *sSymGSTDSOMemoryPool = NULL; +static apr_dso_handle_t *sSymGSTDSOHandleG = NULL; +static apr_dso_handle_t *sSymGSTDSOHandleV = NULL; + + +bool grab_gst_syms(std::string gst_dso_name, + std::string gst_dso_name_vid) +{ + if (sSymsGrabbed) + { + // already have grabbed good syms + return TRUE; + } + + bool sym_error = false; + bool rtn = false; + apr_status_t rv; + apr_dso_handle_t *sSymGSTDSOHandle = NULL; + +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0) + + //attempt to load the shared libraries + apr_pool_create(&sSymGSTDSOMemoryPool, NULL); + + if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, + gst_dso_name.c_str(), + sSymGSTDSOMemoryPool) )) + { + INFOMSG("Found DSO: %s", gst_dso_name.c_str()); +#include "llmediaimplgstreamer_syms_raw.inc" + + if ( sSymGSTDSOHandle ) + { + sSymGSTDSOHandleG = sSymGSTDSOHandle; + sSymGSTDSOHandle = NULL; + } + + if ( APR_SUCCESS == + (rv = apr_dso_load(&sSymGSTDSOHandle, + gst_dso_name_vid.c_str(), + sSymGSTDSOMemoryPool) )) + { + INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); +#include "llmediaimplgstreamer_syms_rawv.inc" + rtn = !sym_error; + } + else + { + INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); + rtn = false; // failure + } + } + else + { + INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); + rtn = false; // failure + } + + if (sym_error) + { + WARNMSG("Failed to find necessary symbols in GStreamer libraries."); + } + + if ( sSymGSTDSOHandle ) + { + sSymGSTDSOHandleV = sSymGSTDSOHandle; + sSymGSTDSOHandle = NULL; + } +#undef LL_GST_SYM + + sSymsGrabbed = !!rtn; + return rtn; +} + + +void ungrab_gst_syms() +{ + // should be safe to call regardless of whether we've + // actually grabbed syms. + + if ( sSymGSTDSOHandleG ) + { + apr_dso_unload(sSymGSTDSOHandleG); + sSymGSTDSOHandleG = NULL; + } + + if ( sSymGSTDSOHandleV ) + { + apr_dso_unload(sSymGSTDSOHandleV); + sSymGSTDSOHandleV = NULL; + } + + if ( sSymGSTDSOMemoryPool ) + { + apr_pool_destroy(sSymGSTDSOMemoryPool); + sSymGSTDSOMemoryPool = NULL; + } + + // NULL-out all of the symbols we'd grabbed +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0) +#include "llmediaimplgstreamer_syms_raw.inc" +#include "llmediaimplgstreamer_syms_rawv.inc" +#undef LL_GST_SYM + + sSymsGrabbed = false; +} + + +#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h new file mode 100644 index 000000000..ee7473d6d --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h @@ -0,0 +1,78 @@ +/** + * @file llmediaimplgstreamer_syms.h + * @brief dynamic GStreamer symbol-grabbing code + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#if LL_GSTREAMER010_ENABLED + +extern "C" { +#include <gst/gst.h> +} + +bool grab_gst_syms(std::string gst_dso_name, + std::string gst_dso_name_vid); +void ungrab_gst_syms(); + +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__) +#include "llmediaimplgstreamer_syms_raw.inc" +#include "llmediaimplgstreamer_syms_rawv.inc" +#undef LL_GST_SYM + +// regrettable hacks to give us better runtime compatibility with older systems +#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) +#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0) + +// regrettable hacks because GStreamer was not designed for runtime loading +#undef GST_TYPE_MESSAGE +#define GST_TYPE_MESSAGE (llgst_message_get_type()) +#undef GST_TYPE_OBJECT +#define GST_TYPE_OBJECT (llgst_object_get_type()) +#undef GST_TYPE_PIPELINE +#define GST_TYPE_PIPELINE (llgst_pipeline_get_type()) +#undef GST_TYPE_ELEMENT +#define GST_TYPE_ELEMENT (llgst_element_get_type()) +#undef GST_TYPE_VIDEO_SINK +#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type()) +// more regrettable hacks to stub-out these .h-exposed GStreamer internals +void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname); +#undef _gst_debug_register_funcptr +#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr +GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description); +#undef _gst_debug_category_new +#define _gst_debug_category_new ll_gst_debug_category_new +#undef __gst_debug_enabled +#define __gst_debug_enabled (0) + +// more hacks +#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M))) + +#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc new file mode 100644 index 000000000..b33e59363 --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc @@ -0,0 +1,51 @@ + +// required symbols to grab +LL_GST_SYM(true, gst_pad_peer_accept_caps, gboolean, GstPad *pad, GstCaps *caps); +LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void); +LL_GST_SYM(true, gst_buffer_set_caps, void, GstBuffer*, GstCaps *); +LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*); +LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err); +LL_GST_SYM(true, gst_message_get_type, GType, void); +LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type); +LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug); +LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug); +LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending); +LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state); +LL_GST_SYM(true, gst_object_unref, void, gpointer object); +LL_GST_SYM(true, gst_object_get_type, GType, void); +LL_GST_SYM(true, gst_pipeline_get_type, GType, void); +LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline); +LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data); +LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name); +LL_GST_SYM(true, gst_element_get_type, GType, void); +LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template); +LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp); +LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details); +LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps); +LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps); +//LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps); +LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string); +LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps); +LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index); +LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps); +//LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2); +LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type); +LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc); +LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value); +LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname); +LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value); +LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value); +LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure); +LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64); + +// optional symbols to grab +LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled); +LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled); +LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent); +LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug); +LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur); +LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano); + +// GStreamer 'internal' symbols which may not be visible in some runtimes but are still used in expanded GStreamer header macros - yuck! We'll substitute our own stubs for these. +//LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname); +//LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description); diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc new file mode 100644 index 000000000..14fbcb48b --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc @@ -0,0 +1,5 @@ + +// required symbols to grab +LL_GST_SYM(true, gst_video_sink_get_type, GType, void); + +// optional symbols to grab diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h new file mode 100644 index 000000000..e31d4a328 --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h @@ -0,0 +1,53 @@ +/** + * @file llmediaimplgstreamertriviallogging.h + * @brief minimal logging utilities. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ +#define __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ + +#include <cstdio> + +///////////////////////////////////////////////////////////////////////// +// Debug/Info/Warning macros. +#define MSGMODULEFOO "(media plugin)" +#define STDERRMSG(...) do{\ + fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\ + fprintf(stderr, __VA_ARGS__);\ + fputc('\n',stderr);\ + }while(0) +#define NULLMSG(...) do{}while(0) + +#define DEBUGMSG NULLMSG +#define INFOMSG STDERRMSG +#define WARNMSG STDERRMSG +///////////////////////////////////////////////////////////////////////// + +#endif /* __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ */ diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp similarity index 61% rename from linden/indra/llmedia/llmediaimplgstreamervidplug.cpp rename to linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index f2c0e8818..25e96d412 100644 --- a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -1,5 +1,5 @@ /** - * @file llmediaimplgstreamervidplug.h + * @file llmediaimplgstreamervidplug.cpp * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl * * $LicenseInfo:firstyear=2007&license=viewergpl$ @@ -30,7 +30,7 @@ * $/LicenseInfo$ */ -///#if LL_GSTREAMER_ENABLED +#if LL_GSTREAMER010_ENABLED #include "linden_common.h" @@ -38,30 +38,21 @@ #include <gst/video/video.h> #include <gst/video/gstvideosink.h> -#include "llthread.h" +#include "llmediaimplgstreamer_syms.h" +#include "llmediaimplgstreamertriviallogging.h" #include "llmediaimplgstreamervidplug.h" + GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); #define GST_CAT_DEFAULT gst_slvideo_debug -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0 -}; -#define SLV_SIZECAPS ", width=(int){1,2,4,8,16,32,64,128,256,512,1024}, height=(int){1,2,4,8,16,32,64,128,256,512,1024} " -#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS ";" GST_VIDEO_CAPS_BGRx SLV_SIZECAPS +#define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] " +#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ( - "sink", + (gchar*)"sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (SLV_ALLCAPS) @@ -87,9 +78,9 @@ gst_slvideo_base_init (gpointer gclass) }; GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details (element_class, &element_details); + llgst_element_class_add_pad_template (element_class, + llgst_static_pad_template_get (&sink_factory)); + llgst_element_class_set_details (element_class, &element_details); } @@ -100,7 +91,7 @@ gst_slvideo_finalize (GObject * object) slvideo = GST_SLVIDEO (object); if (slvideo->caps) { - gst_caps_unref(slvideo->caps); + llgst_caps_unref(slvideo->caps); } G_OBJECT_CLASS(parent_class)->finalize (object); @@ -111,7 +102,7 @@ static GstFlowReturn gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) { GstSLVideo *slvideo; - g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); + llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); slvideo = GST_SLVIDEO(bsink); @@ -204,7 +195,7 @@ gst_slvideo_get_caps (GstBaseSink * bsink) GstSLVideo *slvideo; slvideo = GST_SLVIDEO(bsink); - return gst_caps_ref (slvideo->caps); + return llgst_caps_ref (slvideo->caps); } @@ -214,42 +205,37 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) { GstSLVideo *filter; GstStructure *structure; - GstCaps *intersection; GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); filter = GST_SLVIDEO(bsink); - - intersection = gst_caps_intersect (filter->caps, caps); - if (gst_caps_is_empty (intersection)) - { - // no overlap between our caps and requested caps - return FALSE; - } - gst_caps_unref(intersection); - - int width = 0; - int height = 0; + + int width, height; gboolean ret; const GValue *fps; const GValue *par; - structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", &width); - ret = ret && gst_structure_get_int (structure, "height", &height); - fps = gst_structure_get_value (structure, "framerate"); + structure = llgst_caps_get_structure (caps, 0); + ret = llgst_structure_get_int (structure, "width", &width); + ret = ret && llgst_structure_get_int (structure, "height", &height); + fps = llgst_structure_get_value (structure, "framerate"); ret = ret && (fps != NULL); - par = gst_structure_get_value (structure, "pixel-aspect-ratio"); + par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); if (!ret) return FALSE; + INFOMSG("** filter caps set with width=%d, height=%d", width, height); + + GST_OBJECT_LOCK(filter); + filter->width = width; filter->height = height; - filter->fps_n = gst_value_get_fraction_numerator(fps); - filter->fps_d = gst_value_get_fraction_denominator(fps); + + filter->fps_n = llgst_value_get_fraction_numerator(fps); + filter->fps_d = llgst_value_get_fraction_denominator(fps); if (par) { - filter->par_n = gst_value_get_fraction_numerator(par); - filter->par_d = gst_value_get_fraction_denominator(par); + filter->par_n = llgst_value_get_fraction_numerator(par); + filter->par_d = llgst_value_get_fraction_denominator(par); } else { @@ -259,16 +245,18 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) GST_VIDEO_SINK_WIDTH(filter) = width; GST_VIDEO_SINK_HEIGHT(filter) = height; + // crufty lump - we *always* accept *only* RGBX now. + /* filter->format = SLV_PF_UNKNOWN; - if (0 == strcmp(gst_structure_get_name(structure), + if (0 == strcmp(llgst_structure_get_name(structure), "video/x-raw-rgb")) { int red_mask; int green_mask; int blue_mask; - gst_structure_get_int(structure, "red_mask", &red_mask); - gst_structure_get_int(structure, "green_mask", &green_mask); - gst_structure_get_int(structure, "blue_mask", &blue_mask); + llgst_structure_get_int(structure, "red_mask", &red_mask); + llgst_structure_get_int(structure, "green_mask", &green_mask); + llgst_structure_get_int(structure, "blue_mask", &blue_mask); if ((unsigned int)red_mask == 0xFF000000 && (unsigned int)green_mask == 0x00FF0000 && (unsigned int)blue_mask == 0x0000FF00) @@ -282,8 +270,12 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) filter->format = SLV_PF_BGRX; //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n"); } - } + }*/ + filter->format = SLV_PF_RGBX; + + GST_OBJECT_UNLOCK(filter); + return TRUE; } @@ -317,6 +309,97 @@ gst_slvideo_stop (GstBaseSink * bsink) } +static GstFlowReturn +gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, + GstCaps * caps, GstBuffer ** buf) +{ + gint width, height; + GstStructure *structure = NULL; + GstSLVideo *slvideo; + slvideo = GST_SLVIDEO(bsink); + + // caps == requested caps + // we can ignore these and reverse-negotiate our preferred dimensions with + // the peer if we like - we need to do this to obey dynamic resize requests + // flowing in from the app. + structure = llgst_caps_get_structure (caps, 0); + if (!llgst_structure_get_int(structure, "width", &width) || + !llgst_structure_get_int(structure, "height", &height)) + { + GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps); + return GST_FLOW_NOT_NEGOTIATED; + } + + GstBuffer *newbuf = llgst_buffer_new(); + bool made_bufferdata_ptr = false; +#define MAXDEPTHHACK 4 + + GST_OBJECT_LOCK(slvideo); + if (slvideo->resize_forced) + { + gint slwantwidth, slwantheight; + slwantwidth = slvideo->resize_try_width; + slwantheight = slvideo->resize_try_height; + + if (slwantwidth != width || + slwantheight != height) + { + // don't like requested caps, we will issue our own suggestion - copy + // the requested caps but substitute our own width and height and see + // if our peer is happy with that. + + GstCaps *desired_caps; + GstStructure *desired_struct; + desired_caps = llgst_caps_copy (caps); + desired_struct = llgst_caps_get_structure (desired_caps, 0); + + GValue value = {0}; + g_value_init(&value, G_TYPE_INT); + g_value_set_int(&value, slwantwidth); + llgst_structure_set_value (desired_struct, "width", &value); + g_value_unset(&value); + g_value_init(&value, G_TYPE_INT); + g_value_set_int(&value, slwantheight); + llgst_structure_set_value (desired_struct, "height", &value); + + if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), + desired_caps)) + { + // todo: re-use buffers from a pool? + // todo: set MALLOCDATA to null, set DATA to point straight to shm? + + // peer likes our cap suggestion + DEBUGMSG("peer loves us :)"); + GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK; + GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); + GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); + llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); + + made_bufferdata_ptr = true; + } else { + // peer hates our cap suggestion + INFOMSG("peer hates us :("); + llgst_caps_unref(desired_caps); + } + } + } + + if (!made_bufferdata_ptr) // need to fallback to malloc at original size + { + GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; + GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); + GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); + llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); + } + + GST_OBJECT_UNLOCK(slvideo); + + *buf = GST_BUFFER_CAST(newbuf); + + return GST_FLOW_OK; +} + + /* initialize the plugin's class */ static void gst_slvideo_class_init (GstSLVideoClass * klass) @@ -338,7 +421,7 @@ gst_slvideo_class_init (GstSLVideoClass * klass) #define LLGST_DEBUG_FUNCPTR(p) (p) gstbasesink_class->get_caps = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_caps); gstbasesink_class->set_caps = LLGST_DEBUG_FUNCPTR( gst_slvideo_set_caps); - //gstbasesink_class->buffer_alloc=LLGST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc); + gstbasesink_class->buffer_alloc=LLGST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc); //gstbasesink_class->get_times = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_times); gstbasesink_class->preroll = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); gstbasesink_class->render = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); @@ -351,20 +434,6 @@ gst_slvideo_class_init (GstSLVideoClass * klass) } -static void -gst_slvideo_update_caps (GstSLVideo * slvideo) -{ - GstCaps *caps; - - // GStreamer will automatically convert colourspace if necessary. - // GStreamer will automatically resize media to one of these enumerated - // powers-of-two that we ask for (yay GStreamer!) - caps = gst_caps_from_string (SLV_ALLCAPS); - - gst_caps_replace (&slvideo->caps, caps); -} - - /* initialize the new element * instantiate pads and add them to element * set functions @@ -374,6 +443,7 @@ static void gst_slvideo_init (GstSLVideo * filter, GstSLVideoClass * gclass) { + filter->caps = NULL; filter->width = -1; filter->height = -1; @@ -385,19 +455,24 @@ gst_slvideo_init (GstSLVideo * filter, filter->retained_frame_width = filter->width; filter->retained_frame_height = filter->height; filter->retained_frame_format = SLV_PF_UNKNOWN; + GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); + llgst_caps_replace (&filter->caps, caps); + filter->resize_forced = false; + filter->resize_try_width = -1; + filter->resize_try_height = -1; GST_OBJECT_UNLOCK(filter); - - gst_slvideo_update_caps(filter); } static void gst_slvideo_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - g_return_if_fail (GST_IS_SLVIDEO (object)); + llg_return_if_fail (GST_IS_SLVIDEO (object)); - if (prop_id) { + switch (prop_id) { + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } @@ -405,10 +480,12 @@ static void gst_slvideo_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - g_return_if_fail (GST_IS_SLVIDEO (object)); + llg_return_if_fail (GST_IS_SLVIDEO (object)); - if (prop_id) { + switch (prop_id) { + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } @@ -421,28 +498,35 @@ gst_slvideo_get_property (GObject * object, guint prop_id, static gboolean plugin_init (GstPlugin * plugin) { - //fprintf(stderr, "\n\n\nPLUGIN INIT\n\n\n"); + DEBUGMSG("\n\n\nPLUGIN INIT\n\n\n"); GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", 0, (gchar*)"Second Life Video Sink"); - return gst_element_register (plugin, "private-slvideo", + return llgst_element_register (plugin, (gchar*)"private-slvideo", GST_RANK_NONE, GST_TYPE_SLVIDEO); } - +/* this is the structure that gstreamer looks for to register plugins + */ +/* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since + some g++ versions buggily avoid __attribute__((constructor)) functions - + so we provide an explicit plugin init function. + */ void gst_slvideo_init_class (void) { - gst_plugin_register_static( GST_VERSION_MAJOR, - GST_VERSION_MINOR, - (const gchar *)"private-slvideoplugin", - (gchar *)"SL Video sink plugin", - plugin_init, - (const gchar *)"0.1", - GST_LICENSE_UNKNOWN, - (const gchar *)"Second Life", - (const gchar *)"Second Life", - (const gchar *)"http://www.secondlife.com/" ); +#define PACKAGE "packagehack" + // this macro quietly refers to PACKAGE internally + static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + (gchar*)"private-slvideoplugin", + (gchar*)"SL Video sink plugin", + plugin_init, (gchar*)"0.1", (gchar*)GST_LICENSE_UNKNOWN, + (gchar*)"Second Life", + (gchar*)"http://www.secondlife.com/"); +#undef PACKAGE + ll_gst_plugin_register_static (&gst_plugin_desc); + DEBUGMSG(stderr, "\n\n\nCLASS INIT\n\n\n"); } -///#endif // LL_GSTREAMER_ENABLED +#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h similarity index 93% rename from linden/indra/llmedia/llmediaimplgstreamervidplug.h rename to linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index 3a984a9b7..f6d55b875 100644 --- a/linden/indra/llmedia/llmediaimplgstreamervidplug.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -33,13 +33,12 @@ #ifndef __GST_SLVIDEO_H__ #define __GST_SLVIDEO_H__ -///#if LL_GSTREAMER_ENABLED +#if LL_GSTREAMER010_ENABLED extern "C" { #include <gst/gst.h> #include <gst/video/video.h> #include <gst/video/gstvideosink.h> -#include <glib/gthread.h> } G_BEGIN_DECLS @@ -85,9 +84,13 @@ struct _GstSLVideo // when the retained frame is updated.) bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.) unsigned char* retained_frame_data; - int retained_frame_allocbytes; - int retained_frame_width, retained_frame_height; + int retained_frame_allocbytes; + int retained_frame_width, retained_frame_height; SLVPixelFormat retained_frame_format; + // sticky resize info + bool resize_forced; + int resize_try_width; + int resize_try_height; }; struct _GstSLVideoClass @@ -101,6 +104,6 @@ void gst_slvideo_init_class (void); G_END_DECLS -///#endif // LL_GSTREAMER_ENABLED +#endif // LL_GSTREAMER010_ENABLED #endif /* __GST_SLVIDEO_H__ */ diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp new file mode 100644 index 000000000..77b7c1319 --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -0,0 +1,1202 @@ +/** + * @file media_plugin_gstreamer010.cpp + * @brief GStreamer-0.10 plugin for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#if LL_GSTREAMER010_ENABLED + +extern "C" { +#include <gst/gst.h> +} + +#include "llmediaimplgstreamer.h" +#include "llmediaimplgstreamertriviallogging.h" + +#include "llmediaimplgstreamervidplug.h" + +#include "llmediaimplgstreamer_syms.h" + +////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginGStreamer010 : public MediaPluginBase +{ +public: + MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginGStreamer010(); + + /* virtual */ void receiveMessage(const char *message_string); + + static bool startup(); + static bool closedown(); + + gboolean processGSTEvents(GstBus *bus, + GstMessage *message); + +private: + std::string getVersion(); + bool navigateTo( const std::string urlIn ); + bool seek( double time_sec ); + bool setVolume( float volume ); + + // misc + bool pause(); + bool stop(); + bool play(double rate); + bool getTimePos(double &sec_out); + + static const double MIN_LOOP_SEC = 1.0F; + + bool mIsLooping; + + enum ECommand { + COMMAND_NONE, + COMMAND_STOP, + COMMAND_PLAY, + COMMAND_FAST_FORWARD, + COMMAND_FAST_REWIND, + COMMAND_PAUSE, + COMMAND_SEEK, + }; + ECommand mCommand; + +private: + bool unload(); + bool load(); + + bool update(int milliseconds); + void mouseDown( int x, int y ); + void mouseUp( int x, int y ); + void mouseMove( int x, int y ); + + bool sizeChanged(); + + static bool mDoneInit; + + guint mBusWatchID; + + float mVolume; + + int mDepth; + + // media natural size + int mNaturalWidth; + int mNaturalHeight; + int mNaturalRowbytes; + // previous media natural size so we can detect changes + int mPreviousNaturalWidth; + int mPreviousNaturalHeight; + // desired render size from host + int mWidth; + int mHeight; + // padded texture size we need to write into + int mTextureWidth; + int mTextureHeight; + + int mTextureFormatPrimary; + int mTextureFormatType; + + bool mSeekWanted; + double mSeekDestination; + + // Very GStreamer-specific + GMainLoop *mPump; // event pump for this media + GstElement *mPlaybin; + GstSLVideo *mVideoSink; +}; + +//static +bool MediaPluginGStreamer010::mDoneInit = false; + +MediaPluginGStreamer010::MediaPluginGStreamer010( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data), + mBusWatchID ( 0 ), + mNaturalRowbytes ( 4 ), + mTextureFormatPrimary ( GL_RGBA ), + mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ), + mSeekWanted(false), + mSeekDestination(0.0), + mPump ( NULL ), + mPlaybin ( NULL ), + mVideoSink ( NULL ), + mCommand ( COMMAND_NONE ) +{ + std::ostringstream str; + INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid())); +} + +/////////////////////////////////////////////////////////////////////////////// +// +//#define LL_GST_REPORT_STATE_CHANGES +#ifdef LL_GST_REPORT_STATE_CHANGES +static char* get_gst_state_name(GstState state) +{ + switch (state) { + case GST_STATE_VOID_PENDING: return "VOID_PENDING"; + case GST_STATE_NULL: return "NULL"; + case GST_STATE_READY: return "READY"; + case GST_STATE_PAUSED: return "PAUSED"; + case GST_STATE_PLAYING: return "PLAYING"; + } + return "(unknown)"; +} +#endif // LL_GST_REPORT_STATE_CHANGES + +gboolean +MediaPluginGStreamer010::processGSTEvents(GstBus *bus, + GstMessage *message) +{ + if (!message) + return TRUE; // shield against GStreamer bug + + if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && + GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) + { + DEBUGMSG("Got GST message type: %s", + LLGST_MESSAGE_TYPE_NAME (message)); + } + else + { + DEBUGMSG("Got GST message type: %s", + LLGST_MESSAGE_TYPE_NAME (message)); + } + + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_BUFFERING: { + // NEEDS GST 0.10.11+ + if (llgst_message_parse_buffering) + { + gint percent = 0; + llgst_message_parse_buffering(message, &percent); + DEBUGMSG("GST buffering: %d%%", percent); + } + break; + } + case GST_MESSAGE_STATE_CHANGED: { + GstState old_state; + GstState new_state; + GstState pending_state; + llgst_message_parse_state_changed(message, + &old_state, + &new_state, + &pending_state); +#ifdef LL_GST_REPORT_STATE_CHANGES + // not generally very useful, and rather spammy. + DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", + get_gst_state_name(old_state), + get_gst_state_name(new_state), + get_gst_state_name(pending_state)); +#endif // LL_GST_REPORT_STATE_CHANGES + + switch (new_state) { + case GST_STATE_VOID_PENDING: + break; + case GST_STATE_NULL: + break; + case GST_STATE_READY: + setStatus(STATUS_LOADED); + break; + case GST_STATE_PAUSED: + setStatus(STATUS_PAUSED); + break; + case GST_STATE_PLAYING: + setStatus(STATUS_PLAYING); + break; + } + break; + } + case GST_MESSAGE_ERROR: { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_error (message, &err, &debug); + WARNMSG("GST error: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + + mCommand = COMMAND_STOP; + + setStatus(STATUS_ERROR); + + break; + } + case GST_MESSAGE_INFO: { + if (llgst_message_parse_info) + { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_info (message, &err, &debug); + INFOMSG("GST info: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + } + break; + } + case GST_MESSAGE_WARNING: { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_warning (message, &err, &debug); + WARNMSG("GST warning: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + + break; + } + case GST_MESSAGE_EOS: + /* end-of-stream */ + DEBUGMSG("GST end-of-stream."); + if (mIsLooping) + { + DEBUGMSG("looping media..."); + double eos_pos_sec = 0.0F; + bool got_eos_position = getTimePos(eos_pos_sec); + + if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) + { + // if we know that the movie is really short, don't + // loop it else it can easily become a time-hog + // because of GStreamer spin-up overhead + DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); + // inject a COMMAND_PAUSE + mCommand = COMMAND_PAUSE; + } + else + { +#undef LLGST_LOOP_BY_SEEKING +// loop with a stop-start instead of a seek, because it actually seems rather +// faster than seeking on remote streams. +#ifdef LLGST_LOOP_BY_SEEKING + // first, try looping by an explicit rewind + bool seeksuccess = seek(0.0); + if (seeksuccess) + { + play(1.0); + } + else +#endif // LLGST_LOOP_BY_SEEKING + { // use clumsy stop-start to loop + DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); + stop(); + play(1.0); + } + } + } + else // not a looping media + { + // inject a COMMAND_STOP + mCommand = COMMAND_STOP; + } + break; + default: + /* unhandled message */ + break; + } + + /* we want to be notified again the next time there is a message + * on the bus, so return true (false means we want to stop watching + * for messages on the bus and our callback should not be called again) + */ + return TRUE; +} + +extern "C" { +gboolean +llmediaimplgstreamer_bus_callback (GstBus *bus, + GstMessage *message, + gpointer data) +{ + MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data; + return impl->processGSTEvents(bus, message); +} +} // extern "C" + + + +bool +MediaPluginGStreamer010::navigateTo ( const std::string urlIn ) +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + DEBUGMSG("Setting media URI: %s", urlIn.c_str()); + + mSeekWanted = false; + + if (NULL == mPump || + NULL == mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // set URI + g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); + //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); + + // navigateTo implicitly plays, too. + play(1.0); + + return true; +} + + +bool +MediaPluginGStreamer010::update(int milliseconds) +{ + if (!mDoneInit) + return false; // error + + DEBUGMSG("updating media..."); + + // sanity check + if (NULL == mPump || + NULL == mPlaybin) + { + DEBUGMSG("dead media..."); + return false; + } + + // see if there's an outstanding seek wanted + if (mSeekWanted && + // bleh, GST has to be happy that the movie is really truly playing + // or it may quietly ignore the seek (with rtsp:// at least). + (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) + { + seek(mSeekDestination); + mSeekWanted = false; + } + + // *TODO: time-limit - but there isn't a lot we can do here, most + // time is spent in gstreamer's own opaque worker-threads. maybe + // we can do something sneaky like only unlock the video object + // for 'milliseconds' and otherwise hold the lock. + while (g_main_context_pending(g_main_loop_get_context(mPump))) + { + g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); + } + + // check for availability of a new frame + + if (mVideoSink) + { + GST_OBJECT_LOCK(mVideoSink); + if (mVideoSink->retained_frame_ready) + { + DEBUGMSG("NEW FRAME READY"); + + if (mVideoSink->retained_frame_width != mNaturalWidth || + mVideoSink->retained_frame_height != mNaturalHeight) + // *TODO: also check for change in format + { + // just resize container, don't consume frame + int neww = mVideoSink->retained_frame_width; + int newh = mVideoSink->retained_frame_height; + + int newd = 4; + mTextureFormatPrimary = GL_RGBA; + mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + + /* + int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; + if (SLV_PF_BGRX == mVideoSink->retained_frame_format) + { + mTextureFormatPrimary = GL_BGRA; + mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + } + else + { + mTextureFormatPrimary = GL_RGBA; + mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + } + */ + + GST_OBJECT_UNLOCK(mVideoSink); + + mNaturalRowbytes = neww * newd; + DEBUGMSG("video container resized to %dx%d", + neww, newh); + + mDepth = newd; + mNaturalWidth = neww; + mNaturalHeight = newh; + sizeChanged(); + return true; + } + + if (mPixels && + mNaturalHeight <= mHeight && + mNaturalWidth <= mWidth && + !mTextureSegmentName.empty()) + { + + // we're gonna totally consume this frame - reset 'ready' flag + mVideoSink->retained_frame_ready = FALSE; + int destination_rowbytes = mWidth * mDepth; + for (int row=0; row<mNaturalHeight; ++row) + { + memcpy(&mPixels + [destination_rowbytes * row], + &mVideoSink->retained_frame_data + [mNaturalRowbytes * row], + mNaturalRowbytes); + } + + GST_OBJECT_UNLOCK(mVideoSink); + DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); + + setDirty(0,0,mNaturalWidth,mNaturalHeight); + } + else + { + // new frame ready, but we're not ready to + // consume it. + + GST_OBJECT_UNLOCK(mVideoSink); + + DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize"); + } + + return true; + } + else + { + // nothing to do yet. + GST_OBJECT_UNLOCK(mVideoSink); + return true; + } + } + + return true; +} + + +void +MediaPluginGStreamer010::mouseDown( int x, int y ) +{ + // do nothing +} + +void +MediaPluginGStreamer010::mouseUp( int x, int y ) +{ + // do nothing +} + +void +MediaPluginGStreamer010::mouseMove( int x, int y ) +{ + // do nothing +} + + +bool +MediaPluginGStreamer010::pause() +{ + DEBUGMSG("pausing media..."); + // todo: error-check this? + llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); + return true; +} + +bool +MediaPluginGStreamer010::stop() +{ + DEBUGMSG("stopping media..."); + // todo: error-check this? + llgst_element_set_state(mPlaybin, GST_STATE_READY); + return true; +} + +bool +MediaPluginGStreamer010::play(double rate) +{ + // NOTE: we don't actually support non-natural rate. + + DEBUGMSG("playing media... rate=%f", rate); + // todo: error-check this? + llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); + return true; +} + +bool +MediaPluginGStreamer010::setVolume( float volume ) +{ + // we try to only update volume as conservatively as + // possible, as many gst-plugins-base versions up to at least + // November 2008 have critical race-conditions in setting volume - sigh + if (mVolume == volume) + return true; // nothing to do, everything's fine + + mVolume = volume; + if (mDoneInit && mPlaybin) + { + g_object_set(mPlaybin, "volume", mVolume, NULL); + return true; + } + + return false; +} + +bool +MediaPluginGStreamer010::seek(double time_sec) +{ + bool success = false; + if (mDoneInit && mPlaybin) + { + success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, + GstSeekFlags(GST_SEEK_FLAG_FLUSH | + GST_SEEK_FLAG_KEY_UNIT), + GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); + } + DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", + float(time_sec), int(success)); + return success; +} + +bool +MediaPluginGStreamer010::getTimePos(double &sec_out) +{ + bool got_position = false; + if (mPlaybin) + { + gint64 pos; + GstFormat timefmt = GST_FORMAT_TIME; + got_position = + llgst_element_query_position && + llgst_element_query_position(mPlaybin, + &timefmt, + &pos); + got_position = got_position + && (timefmt == GST_FORMAT_TIME); + // GStreamer may have other ideas, but we consider the current position + // undefined if not PLAYING or PAUSED + got_position = got_position && + (GST_STATE(mPlaybin) == GST_STATE_PLAYING || + GST_STATE(mPlaybin) == GST_STATE_PAUSED); + if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) + { + if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) + { + // if we're playing then we treat an invalid clock time + // as 0, for complicated reasons (insert reason here) + pos = 0; + } + else + { + got_position = false; + } + + } + // If all the preconditions succeeded... we can trust the result. + if (got_position) + { + sec_out = double(pos) / double(GST_SECOND); // gst to sec + } + } + return got_position; +} + +bool +MediaPluginGStreamer010::load() +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + DEBUGMSG("setting up media..."); + + mIsLooping = false; + mVolume = 0.1234567; // minor hack to force an initial volume update + + // Create a pumpable main-loop for this media + mPump = g_main_loop_new (NULL, FALSE); + if (!mPump) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // instantiate a playbin element to do the hard work + mPlaybin = llgst_element_factory_make ("playbin", "play"); + if (!mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // get playbin's bus + GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); + if (!bus) + { + setStatus(STATUS_ERROR); + return false; // error + } + mBusWatchID = llgst_bus_add_watch (bus, + llmediaimplgstreamer_bus_callback, + this); + llgst_object_unref (bus); + + if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { + // instantiate a custom video sink + mVideoSink = + GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); + if (!mVideoSink) + { + WARNMSG("Could not instantiate private-slvideo element."); + // todo: cleanup. + setStatus(STATUS_ERROR); + return false; // error + } + + // connect the pieces + g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); + } + + return true; +} + +bool +MediaPluginGStreamer010::unload () +{ + if (!mDoneInit) + return false; // error + + DEBUGMSG("unloading media..."); + + // stop getting callbacks for this bus + g_source_remove(mBusWatchID); + mBusWatchID = 0; + + if (mPlaybin) + { + llgst_element_set_state (mPlaybin, GST_STATE_NULL); + llgst_object_unref (GST_OBJECT (mPlaybin)); + mPlaybin = NULL; + } + + if (mPump) + { + g_main_loop_quit(mPump); + mPump = NULL; + } + + mVideoSink = NULL; + + setStatus(STATUS_NONE); + + return true; +} + + +//static +bool +MediaPluginGStreamer010::startup() +{ + // first - check if GStreamer is explicitly disabled + if (NULL != getenv("LL_DISABLE_GSTREAMER")) + return false; + + // only do global GStreamer initialization once. + if (!mDoneInit) + { + g_thread_init(NULL); + + // Init the glib type system - we need it. + g_type_init(); + + // Get symbols! +#if LL_DARWIN + if (! grab_gst_syms("libgstreamer-0.10.dylib", + "libgstvideo-0.10.dylib") ) +#elseif LL_WINDOWS + if (! grab_gst_syms("libgstreamer-0.10.dll", + "libgstvideo-0.10.dll") ) +#else // linux or other ELFy unixoid + if (! grab_gst_syms("libgstreamer-0.10.so.0", + "libgstvideo-0.10.so.0") ) +#endif + { + WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); + return false; + } + + if (llgst_segtrap_set_enabled) + { + llgst_segtrap_set_enabled(FALSE); + } + else + { + WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); + } + +#if LL_LINUX + // Gstreamer tries a fork during init, waitpid-ing on it, + // which conflicts with any installed SIGCHLD handler... + struct sigaction tmpact, oldact; + if (llgst_registry_fork_set_enabled) { + // if we can disable SIGCHLD-using forking behaviour, + // do it. + llgst_registry_fork_set_enabled(false); + } + else { + // else temporarily install default SIGCHLD handler + // while GStreamer initialises + tmpact.sa_handler = SIG_DFL; + sigemptyset( &tmpact.sa_mask ); + tmpact.sa_flags = SA_SIGINFO; + sigaction(SIGCHLD, &tmpact, &oldact); + } +#endif // LL_LINUX + + // Protect against GStreamer resetting the locale, yuck. + static std::string saved_locale; + saved_locale = setlocale(LC_ALL, NULL); + + // finally, try to initialize GStreamer! + GError *err = NULL; + gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); + + // restore old locale + setlocale(LC_ALL, saved_locale.c_str() ); + +#if LL_LINUX + // restore old SIGCHLD handler + if (!llgst_registry_fork_set_enabled) + sigaction(SIGCHLD, &oldact, NULL); +#endif // LL_LINUX + + if (!init_gst_success) // fail + { + if (err) + { + WARNMSG("GST init failed: %s", err->message); + g_error_free(err); + } + else + { + WARNMSG("GST init failed for unspecified reason."); + } + return false; + } + + // Init our custom plugins - only really need do this once. + gst_slvideo_init_class(); + + mDoneInit = true; + } + + return true; +} + + +bool +MediaPluginGStreamer010::sizeChanged() +{ + // the shared writing space has possibly changed size/location/whatever + + // Check to see whether the movie's natural size has updated + if (mNaturalWidth != mPreviousNaturalWidth || + mNaturalHeight != mPreviousNaturalHeight) + { + mPreviousNaturalWidth = mNaturalWidth; + mPreviousNaturalHeight = mNaturalHeight; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); + message.setValue("name", mTextureSegmentName); + message.setValueS32("width", mNaturalWidth); + message.setValueS32("height", mNaturalHeight); + DEBUGMSG("<--- Sending size change request to application with name: '%s' - size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); + sendMessage(message); + } + + return true; +} + + + +//static +bool +MediaPluginGStreamer010::closedown() +{ + if (!mDoneInit) + return false; // error + + ungrab_gst_syms(); + + mDoneInit = false; + + return true; +} + +MediaPluginGStreamer010::~MediaPluginGStreamer010() +{ + DEBUGMSG("MediaPluginGStreamer010 destructor"); + + closedown(); + + DEBUGMSG("GStreamer010 closing down"); +} + + +std::string +MediaPluginGStreamer010::getVersion() +{ + std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; + if (mDoneInit && + llgst_version) + { + guint major, minor, micro, nano; + llgst_version(&major, &minor, µ, &nano); + plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); + } + else + { + plugin_version += "(unknown)"; + } + return plugin_version; +} + +void MediaPluginGStreamer010::receiveMessage(const char *message_string) +{ + //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + if ( load() ) + { + DEBUGMSG("GStreamer010 media instance set up"); + } + else + { + WARNMSG("GStreamer010 media instance failed to set up"); + } + + message.setValue("plugin_version", getVersion()); + sendMessage(message); + + // Plugin gets to decide the texture parameters to use. + message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + // lame to have to decide this now, it depends on the movie. Oh well. + mDepth = 4; + + mNaturalWidth = 1; + mNaturalHeight = 1; + mPreviousNaturalWidth = 1; + mPreviousNaturalHeight = 1; + mWidth = 1; + mHeight = 1; + mTextureWidth = 1; + mTextureHeight = 1; + + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); + + message.setValueS32("depth", mDepth); + message.setValueS32("default_width", mWidth); + message.setValueS32("default_height", mHeight); + message.setValueU32("internalformat", GL_RGBA8); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + double time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + unload(); + closedown(); + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + std::ostringstream str; + INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str()); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + + // Make sure the movie decoder is no longer pointed at the shared segment. + sizeChanged(); + } + mSharedSegments.erase(iter); + } + else + { + WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!"); + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + std::ostringstream str; + INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str()); + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + std::ostringstream str; + INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height); + INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height); + + mPixels = (unsigned char*)iter->second.mAddress; + mTextureSegmentName = name; + mWidth = width; + mHeight = height; + + if (texture_width > 1 || + texture_height > 1) // not a dummy size from the app, a real explicit forced size + { + INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); + + GST_OBJECT_LOCK(mVideoSink); + mVideoSink->resize_forced = true; + mVideoSink->resize_try_width = texture_width; + mVideoSink->resize_try_height = texture_height; + GST_OBJECT_UNLOCK(mVideoSink); + } + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + } + } + } + else if(message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + navigateTo( uri ); + sendStatus(); + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + }; + }; + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "stop") + { + stop(); + } + else if(message_name == "start") + { + double rate = 0.0; + if(message_in.hasValue("rate")) + { + rate = message_in.getValueReal("rate"); + } + // NOTE: we don't actually support rate. + play(rate); + } + else if(message_name == "pause") + { + pause(); + } + else if(message_name == "seek") + { + double time = message_in.getValueReal("time"); + // defer the actual seek in case we haven't + // really truly started yet in which case there + // is nothing to seek upon + mSeekWanted = true; + mSeekDestination = time; + } + else if(message_name == "set_loop") + { + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; + } + else if(message_name == "set_volume") + { + double volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + else + { + INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str()); + } + } +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + if (MediaPluginGStreamer010::startup()) + { + MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data); + *plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; // okay + } + else + { + return -1; // failed to init + } +} + +#else // LL_GSTREAMER010_ENABLED + +// Stubbed-out class with constructor/destructor (necessary or windows linker +// will just think its dead code and optimize it all out) +class MediaPluginGStreamer010 : public MediaPluginBase +{ +public: + MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginGStreamer010(); + /* virtual */ void receiveMessage(const char *message_string); +}; + +MediaPluginGStreamer010::MediaPluginGStreamer010( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data) +{ + // no-op +} + +MediaPluginGStreamer010::~MediaPluginGStreamer010() +{ + // no-op +} + +void MediaPluginGStreamer010::receiveMessage(const char *message_string) +{ + // no-op +} + +// We're building without GStreamer enabled. Just refuse to initialize. +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return -1; +} + +#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ new file mode 100755 index 000000000..7d34a1ec0 --- /dev/null +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ @@ -0,0 +1,1219 @@ +/** + * @file media_plugin_gstreamer010.cpp + * @brief GStreamer-0.10 plugin for LLMedia API plugin system + * + * @cond + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#if LL_GSTREAMER010_ENABLED + +extern "C" { +#include <gst/gst.h> +} + +#include "llmediaimplgstreamer.h" +#include "llmediaimplgstreamertriviallogging.h" + +#include "llmediaimplgstreamervidplug.h" + +#include "llmediaimplgstreamer_syms.h" + +////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginGStreamer010 : public MediaPluginBase +{ +public: + MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginGStreamer010(); + + /* virtual */ void receiveMessage(const char *message_string); + + static bool startup(); + static bool closedown(); + + gboolean processGSTEvents(GstBus *bus, + GstMessage *message); + +private: + std::string getVersion(); + bool navigateTo( const std::string urlIn ); + bool seek( double time_sec ); + bool setVolume( float volume ); + + // misc + bool pause(); + bool stop(); + bool play(double rate); + bool getTimePos(double &sec_out); + + static const double MIN_LOOP_SEC = 1.0F; + + bool mIsLooping; + + enum ECommand { + COMMAND_NONE, + COMMAND_STOP, + COMMAND_PLAY, + COMMAND_FAST_FORWARD, + COMMAND_FAST_REWIND, + COMMAND_PAUSE, + COMMAND_SEEK, + }; + ECommand mCommand; + +private: + bool unload(); + bool load(); + + bool update(int milliseconds); + void mouseDown( int x, int y ); + void mouseUp( int x, int y ); + void mouseMove( int x, int y ); + + void sizeChanged(); + + static bool mDoneInit; + + guint mBusWatchID; + + float mVolume; + + int mDepth; + + // media NATURAL size + int mNaturalWidth; + int mNaturalHeight; + // media current size + int mCurrentWidth; + int mCurrentHeight; + int mCurrentRowbytes; + // previous media size so we can detect changes + int mPreviousWidth; + int mPreviousHeight; + // desired render size from host + int mWidth; + int mHeight; + // padded texture size we need to write into + int mTextureWidth; + int mTextureHeight; + + int mTextureFormatPrimary; + int mTextureFormatType; + + bool mSeekWanted; + double mSeekDestination; + + // Very GStreamer-specific + GMainLoop *mPump; // event pump for this media + GstElement *mPlaybin; + GstSLVideo *mVideoSink; +}; + +//static +bool MediaPluginGStreamer010::mDoneInit = false; + +MediaPluginGStreamer010::MediaPluginGStreamer010( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data), + mBusWatchID ( 0 ), + mCurrentRowbytes ( 4 ), + mTextureFormatPrimary ( GL_RGBA ), + mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ), + mSeekWanted(false), + mSeekDestination(0.0), + mPump ( NULL ), + mPlaybin ( NULL ), + mVideoSink ( NULL ), + mCommand ( COMMAND_NONE ) +{ + std::ostringstream str; + INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid())); +} + +/////////////////////////////////////////////////////////////////////////////// +// +//#define LL_GST_REPORT_STATE_CHANGES +#ifdef LL_GST_REPORT_STATE_CHANGES +static char* get_gst_state_name(GstState state) +{ + switch (state) { + case GST_STATE_VOID_PENDING: return "VOID_PENDING"; + case GST_STATE_NULL: return "NULL"; + case GST_STATE_READY: return "READY"; + case GST_STATE_PAUSED: return "PAUSED"; + case GST_STATE_PLAYING: return "PLAYING"; + } + return "(unknown)"; +} +#endif // LL_GST_REPORT_STATE_CHANGES + +gboolean +MediaPluginGStreamer010::processGSTEvents(GstBus *bus, + GstMessage *message) +{ + if (!message) + return TRUE; // shield against GStreamer bug + + if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && + GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) + { + DEBUGMSG("Got GST message type: %s", + LLGST_MESSAGE_TYPE_NAME (message)); + } + else + { + // TODO: grok 'duration' message type + DEBUGMSG("Got GST message type: %s", + LLGST_MESSAGE_TYPE_NAME (message)); + } + + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_BUFFERING: { + // NEEDS GST 0.10.11+ + if (llgst_message_parse_buffering) + { + gint percent = 0; + llgst_message_parse_buffering(message, &percent); + DEBUGMSG("GST buffering: %d%%", percent); + } + break; + } + case GST_MESSAGE_STATE_CHANGED: { + GstState old_state; + GstState new_state; + GstState pending_state; + llgst_message_parse_state_changed(message, + &old_state, + &new_state, + &pending_state); +#ifdef LL_GST_REPORT_STATE_CHANGES + // not generally very useful, and rather spammy. + DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", + get_gst_state_name(old_state), + get_gst_state_name(new_state), + get_gst_state_name(pending_state)); +#endif // LL_GST_REPORT_STATE_CHANGES + + switch (new_state) { + case GST_STATE_VOID_PENDING: + break; + case GST_STATE_NULL: + break; + case GST_STATE_READY: + setStatus(STATUS_LOADED); + break; + case GST_STATE_PAUSED: + setStatus(STATUS_PAUSED); + break; + case GST_STATE_PLAYING: + setStatus(STATUS_PLAYING); + break; + } + break; + } + case GST_MESSAGE_ERROR: { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_error (message, &err, &debug); + WARNMSG("GST error: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + + mCommand = COMMAND_STOP; + + setStatus(STATUS_ERROR); + + break; + } + case GST_MESSAGE_INFO: { + if (llgst_message_parse_info) + { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_info (message, &err, &debug); + INFOMSG("GST info: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + } + break; + } + case GST_MESSAGE_WARNING: { + GError *err = NULL; + gchar *debug = NULL; + + llgst_message_parse_warning (message, &err, &debug); + WARNMSG("GST warning: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + + break; + } + case GST_MESSAGE_EOS: + /* end-of-stream */ + DEBUGMSG("GST end-of-stream."); + if (mIsLooping) + { + DEBUGMSG("looping media..."); + double eos_pos_sec = 0.0F; + bool got_eos_position = getTimePos(eos_pos_sec); + + if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) + { + // if we know that the movie is really short, don't + // loop it else it can easily become a time-hog + // because of GStreamer spin-up overhead + DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); + // inject a COMMAND_PAUSE + mCommand = COMMAND_PAUSE; + } + else + { +#undef LLGST_LOOP_BY_SEEKING +// loop with a stop-start instead of a seek, because it actually seems rather +// faster than seeking on remote streams. +#ifdef LLGST_LOOP_BY_SEEKING + // first, try looping by an explicit rewind + bool seeksuccess = seek(0.0); + if (seeksuccess) + { + play(1.0); + } + else +#endif // LLGST_LOOP_BY_SEEKING + { // use clumsy stop-start to loop + DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); + stop(); + play(1.0); + } + } + } + else // not a looping media + { + // inject a COMMAND_STOP + mCommand = COMMAND_STOP; + } + break; + default: + /* unhandled message */ + break; + } + + /* we want to be notified again the next time there is a message + * on the bus, so return true (false means we want to stop watching + * for messages on the bus and our callback should not be called again) + */ + return TRUE; +} + +extern "C" { +gboolean +llmediaimplgstreamer_bus_callback (GstBus *bus, + GstMessage *message, + gpointer data) +{ + MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data; + return impl->processGSTEvents(bus, message); +} +} // extern "C" + + + +bool +MediaPluginGStreamer010::navigateTo ( const std::string urlIn ) +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + DEBUGMSG("Setting media URI: %s", urlIn.c_str()); + + mSeekWanted = false; + + if (NULL == mPump || + NULL == mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // set URI + g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); + //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); + + // navigateTo implicitly plays, too. + play(1.0); + + return true; +} + + +bool +MediaPluginGStreamer010::update(int milliseconds) +{ + if (!mDoneInit) + return false; // error + + DEBUGMSG("updating media..."); + + // sanity check + if (NULL == mPump || + NULL == mPlaybin) + { + DEBUGMSG("dead media..."); + return false; + } + + // see if there's an outstanding seek wanted + if (mSeekWanted && + // bleh, GST has to be happy that the movie is really truly playing + // or it may quietly ignore the seek (with rtsp:// at least). + (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) + { + seek(mSeekDestination); + mSeekWanted = false; + } + + // *TODO: time-limit - but there isn't a lot we can do here, most + // time is spent in gstreamer's own opaque worker-threads. maybe + // we can do something sneaky like only unlock the video object + // for 'milliseconds' and otherwise hold the lock. + while (g_main_context_pending(g_main_loop_get_context(mPump))) + { + g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); + } + + // check for availability of a new frame + + if (mVideoSink) + { + GST_OBJECT_LOCK(mVideoSink); + if (mVideoSink->retained_frame_ready) + { + DEBUGMSG("NEW FRAME READY"); + + if (mVideoSink->retained_frame_width != mCurrentWidth || + mVideoSink->retained_frame_height != mCurrentHeight) + // *TODO: also check for change in format + { + // just resize container, don't consume frame + int neww = mVideoSink->retained_frame_width; + int newh = mVideoSink->retained_frame_height; + + int newd = 4; + mTextureFormatPrimary = GL_RGBA; + mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + + /* + int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; + if (SLV_PF_BGRX == mVideoSink->retained_frame_format) + { + mTextureFormatPrimary = GL_BGRA; + mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + } + else + { + mTextureFormatPrimary = GL_RGBA; + mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + } + */ + + GST_OBJECT_UNLOCK(mVideoSink); + + mCurrentRowbytes = neww * newd; + DEBUGMSG("video container resized to %dx%d", + neww, newh); + + mDepth = newd; + mCurrentWidth = neww; + mCurrentHeight = newh; + sizeChanged(); + return true; + } + + if (mPixels && + mCurrentHeight <= mHeight && + mCurrentWidth <= mWidth && + !mTextureSegmentName.empty()) + { + // we're gonna totally consume this frame - reset 'ready' flag + mVideoSink->retained_frame_ready = FALSE; + int destination_rowbytes = mWidth * mDepth; + for (int row=0; row<mCurrentHeight; ++row) + { + memcpy(&mPixels + [destination_rowbytes * row], + &mVideoSink->retained_frame_data + [mCurrentRowbytes * row], + mCurrentRowbytes); + } + + GST_OBJECT_UNLOCK(mVideoSink); + DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); + + setDirty(0,0,mCurrentWidth,mCurrentHeight); + } + else + { + // new frame ready, but we're not ready to + // consume it. + + GST_OBJECT_UNLOCK(mVideoSink); + + DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize"); + } + + return true; + } + else + { + // nothing to do yet. + GST_OBJECT_UNLOCK(mVideoSink); + return true; + } + } + + return true; +} + + +void +MediaPluginGStreamer010::mouseDown( int x, int y ) +{ + // do nothing +} + +void +MediaPluginGStreamer010::mouseUp( int x, int y ) +{ + // do nothing +} + +void +MediaPluginGStreamer010::mouseMove( int x, int y ) +{ + // do nothing +} + + +bool +MediaPluginGStreamer010::pause() +{ + DEBUGMSG("pausing media..."); + // todo: error-check this? + llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); + return true; +} + +bool +MediaPluginGStreamer010::stop() +{ + DEBUGMSG("stopping media..."); + // todo: error-check this? + llgst_element_set_state(mPlaybin, GST_STATE_READY); + return true; +} + +bool +MediaPluginGStreamer010::play(double rate) +{ + // NOTE: we don't actually support non-natural rate. + + DEBUGMSG("playing media... rate=%f", rate); + // todo: error-check this? + llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); + return true; +} + +bool +MediaPluginGStreamer010::setVolume( float volume ) +{ + // we try to only update volume as conservatively as + // possible, as many gst-plugins-base versions up to at least + // November 2008 have critical race-conditions in setting volume - sigh + if (mVolume == volume) + return true; // nothing to do, everything's fine + + mVolume = volume; + if (mDoneInit && mPlaybin) + { + g_object_set(mPlaybin, "volume", mVolume, NULL); + return true; + } + + return false; +} + +bool +MediaPluginGStreamer010::seek(double time_sec) +{ + bool success = false; + if (mDoneInit && mPlaybin) + { + success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, + GstSeekFlags(GST_SEEK_FLAG_FLUSH | + GST_SEEK_FLAG_KEY_UNIT), + GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); + } + DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", + float(time_sec), int(success)); + return success; +} + +bool +MediaPluginGStreamer010::getTimePos(double &sec_out) +{ + bool got_position = false; + if (mPlaybin) + { + gint64 pos; + GstFormat timefmt = GST_FORMAT_TIME; + got_position = + llgst_element_query_position && + llgst_element_query_position(mPlaybin, + &timefmt, + &pos); + got_position = got_position + && (timefmt == GST_FORMAT_TIME); + // GStreamer may have other ideas, but we consider the current position + // undefined if not PLAYING or PAUSED + got_position = got_position && + (GST_STATE(mPlaybin) == GST_STATE_PLAYING || + GST_STATE(mPlaybin) == GST_STATE_PAUSED); + if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) + { + if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) + { + // if we're playing then we treat an invalid clock time + // as 0, for complicated reasons (insert reason here) + pos = 0; + } + else + { + got_position = false; + } + + } + // If all the preconditions succeeded... we can trust the result. + if (got_position) + { + sec_out = double(pos) / double(GST_SECOND); // gst to sec + } + } + return got_position; +} + +bool +MediaPluginGStreamer010::load() +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + DEBUGMSG("setting up media..."); + + mIsLooping = false; + mVolume = 0.1234567; // minor hack to force an initial volume update + + // Create a pumpable main-loop for this media + mPump = g_main_loop_new (NULL, FALSE); + if (!mPump) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // instantiate a playbin element to do the hard work + mPlaybin = llgst_element_factory_make ("playbin", "play"); + if (!mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // get playbin's bus + GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); + if (!bus) + { + setStatus(STATUS_ERROR); + return false; // error + } + mBusWatchID = llgst_bus_add_watch (bus, + llmediaimplgstreamer_bus_callback, + this); + llgst_object_unref (bus); + + if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { + // instantiate a custom video sink + mVideoSink = + GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); + if (!mVideoSink) + { + WARNMSG("Could not instantiate private-slvideo element."); + // todo: cleanup. + setStatus(STATUS_ERROR); + return false; // error + } + + // connect the pieces + g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); + } + + return true; +} + +bool +MediaPluginGStreamer010::unload () +{ + if (!mDoneInit) + return false; // error + + DEBUGMSG("unloading media..."); + + // stop getting callbacks for this bus + g_source_remove(mBusWatchID); + mBusWatchID = 0; + + if (mPlaybin) + { + llgst_element_set_state (mPlaybin, GST_STATE_NULL); + llgst_object_unref (GST_OBJECT (mPlaybin)); + mPlaybin = NULL; + } + + if (mPump) + { + g_main_loop_quit(mPump); + mPump = NULL; + } + + mVideoSink = NULL; + + setStatus(STATUS_NONE); + + return true; +} + + +//static +bool +MediaPluginGStreamer010::startup() +{ + // first - check if GStreamer is explicitly disabled + if (NULL != getenv("LL_DISABLE_GSTREAMER")) + return false; + + // only do global GStreamer initialization once. + if (!mDoneInit) + { + g_thread_init(NULL); + + // Init the glib type system - we need it. + g_type_init(); + + // Get symbols! +#if LL_DARWIN + if (! grab_gst_syms("libgstreamer-0.10.dylib", + "libgstvideo-0.10.dylib") ) +#elseif LL_WINDOWS + if (! grab_gst_syms("libgstreamer-0.10.dll", + "libgstvideo-0.10.dll") ) +#else // linux or other ELFy unixoid + if (! grab_gst_syms("libgstreamer-0.10.so.0", + "libgstvideo-0.10.so.0") ) +#endif + { + WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); + return false; + } + + if (llgst_segtrap_set_enabled) + { + llgst_segtrap_set_enabled(FALSE); + } + else + { + WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); + } + +#if LL_LINUX + // Gstreamer tries a fork during init, waitpid-ing on it, + // which conflicts with any installed SIGCHLD handler... + struct sigaction tmpact, oldact; + if (llgst_registry_fork_set_enabled) { + // if we can disable SIGCHLD-using forking behaviour, + // do it. + llgst_registry_fork_set_enabled(false); + } + else { + // else temporarily install default SIGCHLD handler + // while GStreamer initialises + tmpact.sa_handler = SIG_DFL; + sigemptyset( &tmpact.sa_mask ); + tmpact.sa_flags = SA_SIGINFO; + sigaction(SIGCHLD, &tmpact, &oldact); + } +#endif // LL_LINUX + + // Protect against GStreamer resetting the locale, yuck. + static std::string saved_locale; + saved_locale = setlocale(LC_ALL, NULL); + + // finally, try to initialize GStreamer! + GError *err = NULL; + gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); + + // restore old locale + setlocale(LC_ALL, saved_locale.c_str() ); + +#if LL_LINUX + // restore old SIGCHLD handler + if (!llgst_registry_fork_set_enabled) + sigaction(SIGCHLD, &oldact, NULL); +#endif // LL_LINUX + + if (!init_gst_success) // fail + { + if (err) + { + WARNMSG("GST init failed: %s", err->message); + g_error_free(err); + } + else + { + WARNMSG("GST init failed for unspecified reason."); + } + return false; + } + + // Init our custom plugins - only really need do this once. + gst_slvideo_init_class(); + + mDoneInit = true; + } + + return true; +} + + +void +MediaPluginGStreamer010::sizeChanged() +{ + // the shared writing space has possibly changed size/location/whatever + + // Check to see whether the movie's NATURAL size has been set yet + if (1 == mNaturalWidth && + 1 == mNaturalHeight) + { + mNaturalWidth = mCurrentWidth; + mNaturalHeight = mCurrentHeight; + DEBUGMSG("Media NATURAL size better detected as %dx%d", + mNaturalWidth, mNaturalHeight); + } + + // if the size has changed then the shm has changed and the app needs telling + if (mCurrentWidth != mPreviousWidth || + mCurrentHeight != mPreviousHeight) + { + mPreviousWidth = mCurrentWidth; + mPreviousHeight = mCurrentHeight; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); + message.setValue("name", mTextureSegmentName); + message.setValueS32("width", mNaturalWidth); + message.setValueS32("height", mNaturalHeight); + DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); + sendMessage(message); + } +} + + + +//static +bool +MediaPluginGStreamer010::closedown() +{ + if (!mDoneInit) + return false; // error + + ungrab_gst_syms(); + + mDoneInit = false; + + return true; +} + +MediaPluginGStreamer010::~MediaPluginGStreamer010() +{ + DEBUGMSG("MediaPluginGStreamer010 destructor"); + + closedown(); + + DEBUGMSG("GStreamer010 closing down"); +} + + +std::string +MediaPluginGStreamer010::getVersion() +{ + std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; + if (mDoneInit && + llgst_version) + { + guint major, minor, micro, nano; + llgst_version(&major, &minor, µ, &nano); + plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); + } + else + { + plugin_version += "(unknown)"; + } + return plugin_version; +} + +void MediaPluginGStreamer010::receiveMessage(const char *message_string) +{ + //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + if ( load() ) + { + DEBUGMSG("GStreamer010 media instance set up"); + } + else + { + WARNMSG("GStreamer010 media instance failed to set up"); + } + + message.setValue("plugin_version", getVersion()); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + double time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + unload(); + closedown(); + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + std::ostringstream str; + INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str()); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + + // Make sure the movie decoder is no longer pointed at the shared segment. + sizeChanged(); + } + mSharedSegments.erase(iter); + } + else + { + WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!"); + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + std::ostringstream str; + INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str()); + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "init") + { + // Plugin gets to decide the texture parameters to use. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + // lame to have to decide this now, it depends on the movie. Oh well. + mDepth = 4; + + mCurrentWidth = 1; + mCurrentHeight = 1; + mPreviousWidth = 1; + mPreviousHeight = 1; + mNaturalWidth = 1; + mNaturalHeight = 1; + mWidth = 1; + mHeight = 1; + mTextureWidth = 1; + mTextureHeight = 1; + + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); + + message.setValueS32("depth", mDepth); + message.setValueS32("default_width", mWidth); + message.setValueS32("default_height", mHeight); + message.setValueU32("internalformat", GL_RGBA8); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale + sendMessage(message); + } + else if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + std::ostringstream str; + INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height); + INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height); + + mPixels = (unsigned char*)iter->second.mAddress; + mTextureSegmentName = name; + mWidth = width; + mHeight = height; + + if (texture_width > 1 || + texture_height > 1) // not a dummy size from the app, a real explicit forced size + { + INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); + + GST_OBJECT_LOCK(mVideoSink); + mVideoSink->resize_forced_always = true; + mVideoSink->resize_try_width = texture_width; + mVideoSink->resize_try_height = texture_height; + GST_OBJECT_UNLOCK(mVideoSink); + } + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + } + } + } + else if(message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + navigateTo( uri ); + sendStatus(); + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + }; + }; + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "stop") + { + stop(); + } + else if(message_name == "start") + { + double rate = 0.0; + if(message_in.hasValue("rate")) + { + rate = message_in.getValueReal("rate"); + } + // NOTE: we don't actually support rate. + play(rate); + } + else if(message_name == "pause") + { + pause(); + } + else if(message_name == "seek") + { + double time = message_in.getValueReal("time"); + // defer the actual seek in case we haven't + // really truly started yet in which case there + // is nothing to seek upon + mSeekWanted = true; + mSeekDestination = time; + } + else if(message_name == "set_loop") + { + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; + } + else if(message_name == "set_volume") + { + double volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + else + { + INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str()); + } + } +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + if (MediaPluginGStreamer010::startup()) + { + MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data); + *plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; // okay + } + else + { + return -1; // failed to init + } +} + +#else // LL_GSTREAMER010_ENABLED + +// Stubbed-out class with constructor/destructor (necessary or windows linker +// will just think its dead code and optimize it all out) +class MediaPluginGStreamer010 : public MediaPluginBase +{ +public: + MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginGStreamer010(); + /* virtual */ void receiveMessage(const char *message_string); +}; + +MediaPluginGStreamer010::MediaPluginGStreamer010( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data) +{ + // no-op +} + +MediaPluginGStreamer010::~MediaPluginGStreamer010() +{ + // no-op +} + +void MediaPluginGStreamer010::receiveMessage(const char *message_string) +{ + // no-op +} + +// We're building without GStreamer enabled. Just refuse to initialize. +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return -1; +} + +#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/quicktime/CMakeLists.txt b/linden/indra/media_plugins/quicktime/CMakeLists.txt new file mode 100644 index 000000000..db11c9ae2 --- /dev/null +++ b/linden/indra/media_plugins/quicktime/CMakeLists.txt @@ -0,0 +1,83 @@ +# -*- cmake -*- + +project(media_plugin_quicktime) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(FindOpenGL) +include(QuickTimePlugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} +) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(CARBON_LIBRARY Carbon) +endif (DARWIN) + + +### media_plugin_quicktime + +set(media_plugin_quicktime_SOURCE_FILES + media_plugin_quicktime.cpp + ) + +add_library(media_plugin_quicktime + SHARED + ${media_plugin_quicktime_SOURCE_FILES} +) + +target_link_libraries(media_plugin_quicktime + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${QUICKTIME_LIBRARY} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +add_dependencies(media_plugin_quicktime + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +if (QUICKTIME) + + add_definitions(-DLL_QUICKTIME_ENABLED=1) + + if (DARWIN) + # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name + set_target_properties( + media_plugin_quicktime + PROPERTIES + PREFIX "" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path" + LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" + ) + +# We use a bunch of deprecated system APIs. + set_source_files_properties( + media_plugin_quicktime.cpp PROPERTIES + COMPILE_FLAGS -Wno-deprecated-declarations + ) + find_library(CARBON_LIBRARY Carbon) + target_link_libraries(media_plugin_quicktime ${CARBON_LIBRARY}) + endif (DARWIN) +endif (QUICKTIME) + diff --git a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp new file mode 100644 index 000000000..51cc8dd4f --- /dev/null +++ b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -0,0 +1,985 @@ +/** + * @file media_plugin_quicktime.cpp + * @brief QuickTime plugin for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#if LL_QUICKTIME_ENABLED + +#if defined(LL_DARWIN) + #include <QuickTime/QuickTime.h> +#elif defined(LL_WINDOWS) + #include "MacTypes.h" + #include "QTML.h" + #include "Movies.h" + #include "QDoffscreen.h" + #include "FixMath.h" +#endif + +// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginQuickTime : public MediaPluginBase +{ +public: + MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginQuickTime(); + + /* virtual */ void receiveMessage(const char *message_string); + +private: + + int mNaturalWidth; + int mNaturalHeight; + Movie mMovieHandle; + GWorldPtr mGWorldHandle; + ComponentInstance mMovieController; + int mCurVolume; + bool mMediaSizeChanging; + bool mIsLooping; + const int mMinWidth; + const int mMaxWidth; + const int mMinHeight; + const int mMaxHeight; + F64 mPlayRate; + + enum ECommand { + COMMAND_NONE, + COMMAND_STOP, + COMMAND_PLAY, + COMMAND_FAST_FORWARD, + COMMAND_FAST_REWIND, + COMMAND_PAUSE, + COMMAND_SEEK, + }; + ECommand mCommand; + + // Override this to add current time and duration to the message + /*virtual*/ void setDirty(int left, int top, int right, int bottom) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueS32("left", left); + message.setValueS32("top", top); + message.setValueS32("right", right); + message.setValueS32("bottom", bottom); + + if(mMovieHandle) + { + message.setValueReal("current_time", getCurrentTime()); + message.setValueReal("duration", getDuration()); + message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle))); + } + + sendMessage(message); + } + + + static Rect rectFromSize(int width, int height) + { + Rect result; + + + result.left = 0; + result.top = 0; + result.right = width; + result.bottom = height; + + return result; + } + + Fixed getPlayRate(void) + { + Fixed result; + if(mPlayRate == 0.0f) + { + // Default to the movie's preferred rate + result = GetMoviePreferredRate(mMovieHandle); + if(result == 0) + { + // Don't return a 0 play rate, ever. + std::cerr << "Movie's preferred rate is 0, forcing to 1.0." << std::endl; + result = X2Fix(1.0f); + } + } + else + { + result = X2Fix(mPlayRate); + } + + return result; + } + + void load( const std::string url ) + { + if ( url.empty() ) + return; + + // Stop and unload any existing movie before starting another one. + unload(); + + setStatus(STATUS_LOADING); + + //In case std::string::c_str() makes a copy of the url data, + //make sure there is memory to hold it before allocating memory for handle. + //if fails, NewHandleClear(...) should return NULL. + const char* url_string = url.c_str() ; + Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); + if ( NULL == handle || noErr != MemError() || NULL == *handle ) + { + setStatus(STATUS_ERROR); + return; + } + + BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) ); + + OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType ); + DisposeHandle( handle ); + if ( noErr != err ) + { + setStatus(STATUS_ERROR); + return; + }; + + // do pre-roll actions (typically fired for streaming movies but not always) + PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this ); + + Rect movie_rect = rectFromSize(mWidth, mHeight); + + // make a new movie controller + mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie ); + + // movie controller + MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this ); + + SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize ); + + // function that gets called when a frame is drawn + SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); + + setStatus(STATUS_LOADED); + + sizeChanged(); + }; + + bool unload() + { + if ( mMovieHandle ) + { + StopMovie( mMovieHandle ); + if ( mMovieController ) + { + MCMovieChanged( mMovieController, mMovieHandle ); + }; + }; + + if ( mMovieController ) + { + MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this ); + DisposeMovieController( mMovieController ); + mMovieController = NULL; + }; + + if ( mMovieHandle ) + { + SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this ); + DisposeMovie( mMovieHandle ); + mMovieHandle = NULL; + }; + + if ( mGWorldHandle ) + { + DisposeGWorld( mGWorldHandle ); + mGWorldHandle = NULL; + }; + + setStatus(STATUS_NONE); + + return true; + } + + bool navigateTo( const std::string url ) + { + unload(); + load( url ); + + return true; + }; + + bool sizeChanged() + { + if ( ! mMovieHandle ) + return false; + + // Check to see whether the movie's natural size has updated + { + int width, height; + getMovieNaturalSize(&width, &height); + if((width != 0) && (height != 0) && ((width != mNaturalWidth) || (height != mNaturalHeight))) + { + mNaturalWidth = width; + mNaturalHeight = height; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); + message.setValue("name", mTextureSegmentName); + message.setValueS32("width", width); + message.setValueS32("height", height); + sendMessage(message); + //std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl; + } + } + + // sanitize destination size + Rect dest_rect = rectFromSize(mWidth, mHeight); + + // media depth won't change + int depth_bits = mDepth * 8; + long rowbytes = mDepth * mTextureWidth; + + GWorldPtr old_gworld_handle = mGWorldHandle; + + if(mPixels != NULL) + { + // We have pixels. Set up a GWorld pointing at the texture. + OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes); + if ( noErr != result ) + { + // TODO: unrecoverable?? throw exception? return something? + return false; + } + } + else + { + // We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally. + Rect tempRect = rectFromSize(1, 1); + OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0); + if ( noErr != result ) + { + // TODO: unrecoverable?? throw exception? return something? + return false; + } + } + + SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) ); + + // If the GWorld was already set up, delete it. + if(old_gworld_handle != NULL) + { + DisposeGWorld( old_gworld_handle ); + } + + // Set up the movie display matrix + { + // scale movie to fit rect and invert vertically to match opengl image format + MatrixRecord transform; + SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix + double scaleX = (double) mWidth / mNaturalWidth; + double scaleY = -1.0 * (double) mHeight / mNaturalHeight; + double centerX = mWidth / 2.0; + double centerY = mHeight / 2.0; + ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) ); + SetMovieMatrix( mMovieHandle, &transform ); + } + + // update movie controller + if ( mMovieController ) + { + MCSetControllerPort( mMovieController, mGWorldHandle ); + MCPositionController( mMovieController, &dest_rect, &dest_rect, + mcTopLeftMovie | mcPositionDontInvalidate ); + MCMovieChanged( mMovieController, mMovieHandle ); + } + + + // Emit event with size change so the calling app knows about it too + // TODO: + //LLMediaEvent event( this ); + //mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + return true; + } + + static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) + { + Boolean result = false; + + MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + + switch( action ) + { + // handle window resizing + case mcActionControllerSizeChanged: + // Ensure that the movie draws correctly at the new size + self->sizeChanged(); + break; + + // Block any movie controller actions that open URLs. + case mcActionLinkToURL: + case mcActionGetNextURL: + case mcActionLinkToURLExtended: + // Prevent the movie controller from handling the message + result = true; + break; + + default: + break; + }; + + return result; + }; + + static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref ) + { + MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + + // IMPORTANT: typically, a consumer who is observing this event will set a flag + // when this event is fired then render later. Be aware that the media stream + // can change during this period - dimensions, depth, format etc. + //LLMediaEvent event( self ); +// self->updateQuickTime(); + // TODO ^^^ + + if ( self->mWidth > 0 && self->mHeight > 0 ) + self->setDirty( 0, 0, self->mWidth, self->mHeight ); + + return noErr; + }; + + static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) + { + //MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + + // TODO: + //LLMediaEvent event( self ); + //self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); + }; + + + void rewind() + { + GoToBeginningOfMovie( mMovieHandle ); + MCMovieChanged( mMovieController, mMovieHandle ); + }; + + bool processState() + { + if ( mCommand == COMMAND_PLAY ) + { + if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING ) + { + long state = GetMovieLoadState( mMovieHandle ); + + if ( state >= kMovieLoadStatePlaythroughOK ) + { + // if the movie is at the end (generally because it reached it naturally) + // and we play is requested, jump back to the start of the movie. + // note: this is different from having loop flag set. + if ( IsMovieDone( mMovieHandle ) ) + { + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); + rewind(); + }; + + MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); + setStatus(STATUS_PLAYING); + mCommand = COMMAND_NONE; + }; + }; + } + else + if ( mCommand == COMMAND_STOP ) + { + if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED ) + { + if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) + { + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); + rewind(); + + setStatus(STATUS_LOADED); + mCommand = COMMAND_NONE; + }; + }; + } + else + if ( mCommand == COMMAND_PAUSE ) + { + if ( mStatus == STATUS_PLAYING ) + { + if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) + { + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); + setStatus(STATUS_PAUSED); + mCommand = COMMAND_NONE; + }; + }; + }; + + return true; + }; + + void play(F64 rate) + { + mPlayRate = rate; + mCommand = COMMAND_PLAY; + }; + + void stop() + { + mCommand = COMMAND_STOP; + }; + + void pause() + { + mCommand = COMMAND_PAUSE; + }; + + void getMovieNaturalSize(int *movie_width, int *movie_height) + { + Rect rect; + + GetMovieNaturalBoundsRect( mMovieHandle, &rect ); + + int width = ( rect.right - rect.left ); + int height = ( rect.bottom - rect.top ); + + // make sure width and height fall in valid range + if ( width < mMinWidth ) + width = mMinWidth; + + if ( width > mMaxWidth ) + width = mMaxWidth; + + if ( height < mMinHeight ) + height = mMinHeight; + + if ( height > mMaxHeight ) + height = mMaxHeight; + + // return the new rect + *movie_width = width; + *movie_height = height; + } + + void updateQuickTime(int milliseconds) + { + if ( ! mMovieHandle ) + return; + + if ( ! mMovieController ) + return; + + // service QuickTime + // Calling it this way doesn't have good behavior on Windows... +// MoviesTask( mMovieHandle, milliseconds ); + // This was the original, but I think using both MoviesTask and MCIdle is redundant. Trying with only MCIdle. +// MoviesTask( mMovieHandle, 0 ); + + MCIdle( mMovieController ); + + if ( ! mGWorldHandle ) + return; + + if ( mMediaSizeChanging ) + return; + + // update state machine + processState(); + + // special code for looping - need to rewind at the end of the movie + if ( mIsLooping ) + { + // QT call to see if we are at the end - can't do with controller + if ( IsMovieDone( mMovieHandle ) ) + { + // go back to start + rewind(); + + if ( mMovieController ) + { + // kick off new play + MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); + + // set the volume + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); + }; + }; + }; + }; + + int getDataWidth() const + { + if ( mGWorldHandle ) + { + int depth = mDepth; + + if (depth < 1) + depth = 1; + + // ALWAYS use the row bytes from the PixMap if we have a GWorld because + // sometimes it's not the same as mMediaDepth * mMediaWidth ! + PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); + return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth; + } + else + { + // TODO : return LLMediaImplCommon::getaDataWidth(); + return 0; + } + }; + + void seek( F64 time ) + { + if ( mMovieController ) + { + TimeRecord when; + when.scale = GetMovieTimeScale( mMovieHandle ); + when.base = 0; + + // 'time' is in (floating point) seconds. The timebase time will be in 'units', where + // there are 'scale' units per second. + SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) ); + + when.value.hi = ( SInt32 )( raw_time >> 32 ); + when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) ); + + MCDoAction( mMovieController, mcActionGoToTime, &when ); + }; + }; + + F64 getDuration() + { + TimeValue duration = GetMovieDuration( mMovieHandle ); + TimeValue scale = GetMovieTimeScale( mMovieHandle ); + + return (F64)duration / (F64)scale; + }; + + F64 getCurrentTime() + { + TimeValue curr_time = GetMovieTime( mMovieHandle, 0 ); + TimeValue scale = GetMovieTimeScale( mMovieHandle ); + + return (F64)curr_time / (F64)scale; + }; + + void setVolume( F64 volume ) + { + mCurVolume = (short)(volume * ( double ) 0x100 ); + + if ( mMovieController ) + { + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void update(int milliseconds = 0) + { + updateQuickTime(milliseconds); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseDown( int x, int y ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseUp( int x, int y ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int x, int y ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyPress( unsigned char key ) + { + }; + +}; + +MediaPluginQuickTime::MediaPluginQuickTime( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data), + mMinWidth( 0 ), + mMaxWidth( 2048 ), + mMinHeight( 0 ), + mMaxHeight( 2048 ) +{ +// std::cerr << "MediaPluginQuickTime constructor" << std::endl; + + mNaturalWidth = -1; + mNaturalHeight = -1; + mMovieHandle = 0; + mGWorldHandle = 0; + mMovieController = 0; + mCurVolume = 0x99; + mMediaSizeChanging = false; + mIsLooping = false; + mCommand = COMMAND_NONE; + mPlayRate = 0.0f; + mStatus = STATUS_NONE; +} + +MediaPluginQuickTime::~MediaPluginQuickTime() +{ +// std::cerr << "MediaPluginQuickTime destructor" << std::endl; + + ExitMovies(); + +#ifdef LL_WINDOWS + TerminateQTML(); +// std::cerr << "QuickTime closing down" << std::endl; +#endif +} + + +void MediaPluginQuickTime::receiveMessage(const char *message_string) +{ +// std::cerr << "MediaPluginQuickTime::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + // Normally a plugin would only specify one of these two subclasses, but this is a demo... +// versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + #ifdef LL_WINDOWS + if ( InitializeQTML( 0L ) != noErr ) + { + //TODO: If no QT on Windows, this fails - respond accordingly. + //return false; + } + else + { +// std::cerr << "QuickTime initialized" << std::endl; + }; + #endif + + EnterMovies(); + + std::string plugin_version = "QuickTime media plugin, QuickTime version "; + + long version = 0; + Gestalt( gestaltQuickTimeVersion, &version ); + std::ostringstream codec( "" ); + codec << std::hex << version << std::dec; + plugin_version += codec.str(); + message.setValue("plugin_version", plugin_version); + sendMessage(message); + + // Plugin gets to decide the texture parameters to use. + message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + #if defined(LL_WINDOWS) + // Values for Windows + mDepth = 3; + message.setValueU32("format", GL_RGB); + message.setValueU32("type", GL_UNSIGNED_BYTE); + + // We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even. + // Padding to a multiple of 3*32 guarantees it'll divide out properly. + message.setValueU32("padding", 32 * 3); + #else + // Values for Mac + mDepth = 4; + message.setValueU32("format", GL_BGRA_EXT); + #ifdef __BIG_ENDIAN__ + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV ); + #else + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8); + #endif + + // Pad texture width to a multiple of 32 bytes, to line up with cache lines. + message.setValueU32("padding", 32); + #endif + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + F64 time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + // TODO: clean up here + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + U64 address_lo = message_in.getValueU32("address"); + U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0; + info.mAddress = (void*)((address_lo) | + (address_hi * (U64(1)<<31))); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + +// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name +// << ", size: " << info.mSize +// << ", address: " << info.mAddress +// << std::endl; + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + +// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory remove, name = " << name << std::endl; + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + + // Make sure the movie GWorld is no longer pointed at the shared segment. + sizeChanged(); + } + mSharedSegments.erase(iter); + } + else + { +// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { +// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + //std::cerr << "---->Got size change instruction from application with name: " << name << " - size is " << width << " x " << height << std::endl; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { +// std::cerr << "%%% Got size change, new size is " << width << " by " << height << std::endl; +// std::cerr << "%%%% texture size is " << texture_width << " by " << texture_height << std::endl; + + mPixels = (unsigned char*)iter->second.mAddress; + mTextureSegmentName = name; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + mMediaSizeChanging = false; + + sizeChanged(); + + update(); + }; + }; + } + else if(message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + load( uri ); + sendStatus(); + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + }; + }; + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "stop") + { + stop(); + } + else if(message_name == "start") + { + F64 rate = 0.0; + if(message_in.hasValue("rate")) + { + rate = message_in.getValueReal("rate"); + } + play(rate); + } + else if(message_name == "pause") + { + pause(); + } + else if(message_name == "seek") + { + F64 time = message_in.getValueReal("time"); + seek(time); + } + else if(message_name == "set_loop") + { + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; + } + else if(message_name == "set_volume") + { + F64 volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + else + { +// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown message class: " << message_class << std::endl; + }; + }; +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + MediaPluginQuickTime *self = new MediaPluginQuickTime(host_send_func, host_user_data); + *plugin_send_func = MediaPluginQuickTime::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + +#else // LL_QUICKTIME_ENABLED + +// Stubbed-out class with constructor/destructor (necessary or windows linker +// will just think its dead code and optimize it all out) +class MediaPluginQuickTime : public MediaPluginBase +{ +public: + MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginQuickTime(); + /* virtual */ void receiveMessage(const char *message_string); +}; + +MediaPluginQuickTime::MediaPluginQuickTime( + LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) : + MediaPluginBase(host_send_func, host_user_data) +{ + // no-op +} + +MediaPluginQuickTime::~MediaPluginQuickTime() +{ + // no-op +} + +void MediaPluginQuickTime::receiveMessage(const char *message_string) +{ + // no-op +} + +// We're building without quicktime enabled. Just refuse to initialize. +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return -1; +} + +#endif // LL_QUICKTIME_ENABLED diff --git a/linden/indra/media_plugins/webkit/CMakeLists.txt b/linden/indra/media_plugins/webkit/CMakeLists.txt new file mode 100644 index 000000000..5bccd589d --- /dev/null +++ b/linden/indra/media_plugins/webkit/CMakeLists.txt @@ -0,0 +1,82 @@ +# -*- cmake -*- + +project(media_plugin_webkit) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(FindOpenGL) + +include(WebKitLibPlugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} +) + + +### media_plugin_webkit + +set(media_plugin_webkit_SOURCE_FILES + media_plugin_webkit.cpp + ) + +add_library(media_plugin_webkit + SHARED + ${media_plugin_webkit_SOURCE_FILES} +) + +target_link_libraries(media_plugin_webkit + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${WEBKIT_PLUGIN_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +add_dependencies(media_plugin_webkit + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +if (WINDOWS) + set_target_properties( + media_plugin_webkit + PROPERTIES + LINK_FLAGS "/MANIFEST:NO" + ) +endif (WINDOWS) + +if (DARWIN) + # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name + set_target_properties( + media_plugin_webkit + PROPERTIES + PREFIX "" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path" + LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" + ) + + # copy the webkit dylib to the build directory + add_custom_command( + TARGET media_plugin_webkit POST_BUILD +# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ + DEPENDS media_plugin_webkit ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib + ) + +endif (DARWIN) \ No newline at end of file diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp new file mode 100644 index 000000000..f115c2885 --- /dev/null +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -0,0 +1,932 @@ +/** + * @file media_plugin_webkit.cpp + * @brief Webkit plugin for LLMedia API plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llqtwebkit.h" + +#include "linden_common.h" +#include "indra_constants.h" // for indra keyboard codes + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#if LL_WINDOWS +#include <direct.h> +#else +#include <unistd.h> +#include <stdlib.h> +#endif + +#if LL_WINDOWS + // NOTE - This captures the module handle of the dll. This is used below + // to get the path to this dll for webkit initialization. + // I don't know how/if this can be done with apr... + namespace { HMODULE gModuleHandle;}; + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) + { + gModuleHandle = (HMODULE) hinstDLL; + return TRUE; + } +#endif + +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginWebKit : + public MediaPluginBase, + public LLEmbeddedBrowserWindowObserver +{ +public: + MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginWebKit(); + + /*virtual*/ void receiveMessage(const char *message_string); + +private: + + enum + { + INIT_STATE_UNINITIALIZED, // Browser instance hasn't been set up yet + INIT_STATE_NAVIGATING, // Browser instance has been set up and initial navigate to about:blank has been issued + INIT_STATE_NAVIGATE_COMPLETE, // initial navigate to about:blank has completed + INIT_STATE_WAIT_REDRAW, // First real navigate begin has been received, waiting for page changed event to start handling redraws + INIT_STATE_RUNNING // All initialization gymnastics are complete. + }; + int mBrowserWindowId; + int mInitState; + std::string mInitialNavigateURL; + bool mNeedsUpdate; + + bool mCanCut; + bool mCanCopy; + bool mCanPaste; + int mLastMouseX; + int mLastMouseY; + bool mFirstFocus; + + //////////////////////////////////////////////////////////////////////////////// + // + void update(int milliseconds) + { + LLQtWebKit::getInstance()->pump( milliseconds ); + + checkEditState(); + + if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) + { + if(!mInitialNavigateURL.empty()) + { + // We already have the initial navigate URL -- kick off the navigate. + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, mInitialNavigateURL ); + mInitialNavigateURL.clear(); + } + } + + if ( (mInitState == INIT_STATE_RUNNING) && mNeedsUpdate ) + { + const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId ); + + unsigned int buffer_size = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId ) * LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId ); + +// std::cerr << "webkit plugin: updating" << std::endl; + + // TODO: should get rid of this memcpy if possible + if ( mPixels && browser_pixels ) + { +// std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl; + memcpy( mPixels, browser_pixels, buffer_size ); + } + + if ( mWidth > 0 && mHeight > 0 ) + { +// std::cerr << "Setting dirty, " << mWidth << " x " << mHeight << std::endl; + setDirty( 0, 0, mWidth, mHeight ); + } + + mNeedsUpdate = false; + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + bool initBrowser() + { + // already initialized + if ( mInitState > INIT_STATE_UNINITIALIZED ) + return true; + + // not enough information to initialize the browser yet. + if ( mWidth < 0 || mHeight < 0 || mDepth < 0 || + mTextureWidth < 0 || mTextureHeight < 0 ) + { + return false; + }; + + // set up directories + char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use + if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) + { + llwarns << "Couldn't get cwd - probably too long - failing to init." << llendl; + return false; + } + std::string application_dir = std::string( cwd ); + +#if LL_WINDOWS + // NOTE - On windows, at least, the component path is the + // location of this dll's image file. + std::string component_dir; + char dll_path[_MAX_PATH]; + DWORD len = GetModuleFileNameA(gModuleHandle, (LPCH)&dll_path, _MAX_PATH); + while(len && dll_path[ len ] != ('\\') ) + { + len--; + } + if(len >= 0) + { + dll_path[len] = 0; + component_dir = dll_path; + } + else + { + // NOTE - This case should be a rare exception. + // GetModuleFileNameA should always give you a full path. + component_dir = application_dir; + } +#else + std::string component_dir = application_dir; +#endif + std::string profileDir = application_dir + "/" + "browser_profile"; // cross platform? + + // window handle - needed on Windows and must be app window. +#if LL_WINDOWS + char window_title[ MAX_PATH ]; + GetConsoleTitleA( window_title, MAX_PATH ); + void* native_window_handle = (void*)FindWindowA( NULL, window_title ); +#else + void* native_window_handle = 0; +#endif + + // main browser initialization + bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, profileDir, native_window_handle ); + if ( result ) + { + // create single browser window + mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight ); + +#if LL_WINDOWS + // Enable plugins + LLQtWebKit::getInstance()->enablePlugins(true); +#elif LL_DARWIN + // Disable plugins + LLQtWebKit::getInstance()->enablePlugins(false); +#elif LL_LINUX + // Disable plugins + LLQtWebKit::getInstance()->enablePlugins(false); +#endif + + // tell LLQtWebKit about the size of the browser window + LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); + + // observer events that LLQtWebKit emits + LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this ); + + // append details to agent string + LLQtWebKit::getInstance()->setBrowserAgentId( "LLPluginMedia Web Browser" ); + + // don't flip bitmap + LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); + + // Set the background color to black - mostly for initial login page + LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, 0x00, 0x00, 0x00 ); + + // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns. + mInitState = INIT_STATE_NAVIGATING; + + // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance. + // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially + // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date. + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" ); + + return true; + }; + + return false; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onCursorChanged(const EventType& event) + { + LLQtWebKit::ECursor llqt_cursor = (LLQtWebKit::ECursor)event.getIntValue(); + std::string name; + + switch(llqt_cursor) + { + case LLQtWebKit::C_ARROW: + name = "arrow"; + break; + case LLQtWebKit::C_IBEAM: + name = "ibeam"; + break; + case LLQtWebKit::C_SPLITV: + name = "splitv"; + break; + case LLQtWebKit::C_SPLITH: + name = "splith"; + break; + case LLQtWebKit::C_POINTINGHAND: + name = "hand"; + break; + + default: + llwarns << "Unknown cursor ID: " << (int)llqt_cursor << llendl; + break; + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed"); + message.setValue("name", name); + sendMessage(message); + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onPageChanged( const EventType& event ) + { + if(mInitState == INIT_STATE_WAIT_REDRAW) + { + mInitState = INIT_STATE_RUNNING; + } + + // flag that an update is required + mNeedsUpdate = true; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateBegin(const EventType& event) + { + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + message.setValue("uri", event.getEventUri()); + sendMessage(message); + + setStatus(STATUS_LOADING); + } + + if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) + { + mInitState = INIT_STATE_WAIT_REDRAW; + } + + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateComplete(const EventType& event) + { + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + message.setValue("uri", event.getEventUri()); + message.setValueS32("result_code", event.getIntValue()); + message.setValue("result_string", event.getStringValue()); + message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK)); + message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD)); + sendMessage(message); + + setStatus(STATUS_LOADED); + } + else if(mInitState == INIT_STATE_NAVIGATING) + { + mInitState = INIT_STATE_NAVIGATE_COMPLETE; + } + + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onUpdateProgress(const EventType& event) + { + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "progress"); + message.setValueS32("percent", event.getIntValue()); + sendMessage(message); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onStatusTextChange(const EventType& event) + { + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); + message.setValue("status", event.getStringValue()); + sendMessage(message); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onTitleChange(const EventType& event) + { + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", event.getStringValue()); + sendMessage(message); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onLocationChange(const EventType& event) + { + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); + message.setValue("uri", event.getEventUri()); + sendMessage(message); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onClickLinkHref(const EventType& event) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); + message.setValue("uri", event.getStringValue()); + message.setValue("target", event.getStringValue2()); + sendMessage(message); + } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onClickLinkNoFollow(const EventType& event) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); + message.setValue("uri", event.getStringValue()); + sendMessage(message); + } + + LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers) + { + int result = 0; + + if(modifiers.find("shift") != std::string::npos) + result |= LLQtWebKit::KM_MODIFIER_SHIFT; + + if(modifiers.find("alt") != std::string::npos) + result |= LLQtWebKit::KM_MODIFIER_ALT; + + if(modifiers.find("control") != std::string::npos) + result |= LLQtWebKit::KM_MODIFIER_CONTROL; + + if(modifiers.find("meta") != std::string::npos) + result |= LLQtWebKit::KM_MODIFIER_META; + + return (LLQtWebKit::EKeyboardModifier)result; + } + + + //////////////////////////////////////////////////////////////////////////////// + // + void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers) + { + int llqt_key; + + // The incoming values for 'key' will be the ones from indra_constants.h + // the outgoing values are the ones from llqtwebkit.h + + switch((KEY)key) + { + // This is the list that the llqtwebkit implementation actually maps into Qt keys. +// case KEY_XXX: llqt_key = LL_DOM_VK_CANCEL; break; +// case KEY_XXX: llqt_key = LL_DOM_VK_HELP; break; + case KEY_BACKSPACE: llqt_key = LL_DOM_VK_BACK_SPACE; break; + case KEY_TAB: llqt_key = LL_DOM_VK_TAB; break; +// case KEY_XXX: llqt_key = LL_DOM_VK_CLEAR; break; + case KEY_RETURN: llqt_key = LL_DOM_VK_RETURN; break; + case KEY_PAD_RETURN: llqt_key = LL_DOM_VK_ENTER; break; + case KEY_SHIFT: llqt_key = LL_DOM_VK_SHIFT; break; + case KEY_CONTROL: llqt_key = LL_DOM_VK_CONTROL; break; + case KEY_ALT: llqt_key = LL_DOM_VK_ALT; break; +// case KEY_XXX: llqt_key = LL_DOM_VK_PAUSE; break; + case KEY_CAPSLOCK: llqt_key = LL_DOM_VK_CAPS_LOCK; break; + case KEY_ESCAPE: llqt_key = LL_DOM_VK_ESCAPE; break; + case KEY_PAGE_UP: llqt_key = LL_DOM_VK_PAGE_UP; break; + case KEY_PAGE_DOWN: llqt_key = LL_DOM_VK_PAGE_DOWN; break; + case KEY_END: llqt_key = LL_DOM_VK_END; break; + case KEY_HOME: llqt_key = LL_DOM_VK_HOME; break; + case KEY_LEFT: llqt_key = LL_DOM_VK_LEFT; break; + case KEY_UP: llqt_key = LL_DOM_VK_UP; break; + case KEY_RIGHT: llqt_key = LL_DOM_VK_RIGHT; break; + case KEY_DOWN: llqt_key = LL_DOM_VK_DOWN; break; +// case KEY_XXX: llqt_key = LL_DOM_VK_PRINTSCREEN; break; + case KEY_INSERT: llqt_key = LL_DOM_VK_INSERT; break; + case KEY_DELETE: llqt_key = LL_DOM_VK_DELETE; break; +// case KEY_XXX: llqt_key = LL_DOM_VK_CONTEXT_MENU; break; + + default: + if(key < KEY_SPECIAL) + { + // Pass the incoming key through -- it should be regular ASCII, which should be correct for webkit. + llqt_key = key; + } + else + { + // Don't pass through untranslated special keys -- they'll be all wrong. + llqt_key = 0; + } + break; + } + +// std::cerr << "keypress, original code = 0x" << std::hex << key << ", converted code = 0x" << std::hex << llqt_key << std::dec << std::endl; + + if(llqt_key != 0) + { + LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, key_event, llqt_key, modifiers); + } + + checkEditState(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers) + { + LLWString wstr = utf8str_to_wstring(utf8str); + + unsigned int i; + for(i=0; i < wstr.size(); i++) + { +// std::cerr << "unicode input, code = 0x" << std::hex << (unsigned long)(wstr[i]) << std::dec << std::endl; + + LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, wstr[i], modifiers); + } + + checkEditState(); + }; + + void checkEditState(void) + { + bool can_cut = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT); + bool can_copy = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY); + bool can_paste = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE); + + if((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste)) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state"); + + if(can_cut != mCanCut) + { + mCanCut = can_cut; + message.setValueBoolean("cut", can_cut); + } + + if(can_copy != mCanCopy) + { + mCanCopy = can_copy; + message.setValueBoolean("copy", can_copy); + } + + if(can_paste != mCanPaste) + { + mCanPaste = can_paste; + message.setValueBoolean("paste", can_paste); + } + + sendMessage(message); + + } + } + +}; + +MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : + MediaPluginBase(host_send_func, host_user_data) +{ +// std::cerr << "MediaPluginWebKit constructor" << std::endl; + + mBrowserWindowId = 0; + mInitState = INIT_STATE_UNINITIALIZED; + mNeedsUpdate = true; + mCanCut = false; + mCanCopy = false; + mCanPaste = false; + mLastMouseX = 0; + mLastMouseY = 0; + mFirstFocus = true; +} + +MediaPluginWebKit::~MediaPluginWebKit() +{ + // unhook observer + LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this ); + + // clean up + LLQtWebKit::getInstance()->reset(); + +// std::cerr << "MediaPluginWebKit destructor" << std::endl; +} + +void MediaPluginWebKit::receiveMessage(const char *message_string) +{ +// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD("versions", versions); + + std::string plugin_version = "Webkit media plugin, Webkit version "; + plugin_version += LLQtWebKit::getInstance()->getVersion(); + message.setValue("plugin_version", plugin_version); + sendMessage(message); + + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + + message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGBA); + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", true); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + F64 time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + // TODO: clean up here + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + +// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name +// << ", size: " << info.mSize +// << ", address: " << info.mAddress +// << std::endl; + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + +// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl; + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + + // initialize (only gets called once) + initBrowser(); + + // size changed so tell the browser + LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); + +// std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight +// << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl; + + S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId); + + // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response. + if(real_width <= texture_width) + { + texture_width = real_width; + } + else + { + // This won't work -- it'll be bigger than the allocated memory. This is a fatal error. +// std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl; + mDeleteMe = true; + return; + } + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + }; + }; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + } + else if(message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + +// std::cout << "loading URI: " << uri << std::endl; + + if(!uri.empty()) + { + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + { + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, uri ); + } + else + { + mInitialNavigateURL = uri; + } + } + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 button = message_in.getValueS32("button"); + mLastMouseX = message_in.getValueS32("x"); + mLastMouseY = message_in.getValueS32("y"); + std::string modifiers = message_in.getValue("modifiers"); + + // Treat unknown mouse events as mouse-moves. + LLQtWebKit::EMouseEvent mouse_event = LLQtWebKit::ME_MOUSE_MOVE; + if(event == "down") + { + mouse_event = LLQtWebKit::ME_MOUSE_DOWN; + } + else if(event == "up") + { + mouse_event = LLQtWebKit::ME_MOUSE_UP; + } + else if(event == "double_click") + { + mouse_event = LLQtWebKit::ME_MOUSE_DOUBLE_CLICK; + } + + LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, mouse_event, button, mLastMouseX, mLastMouseY, decodeModifiers(modifiers)); + checkEditState(); + } + else if(message_name == "scroll_event") + { + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + std::string modifiers = message_in.getValue("modifiers"); + + // Incoming scroll events are adjusted so that 1 detent is approximately 1 unit. + // Qt expects 1 detent to be 120 units. + // It also seems that our y scroll direction is inverted vs. what Qt expects. + + x *= 120; + y *= -120; + + LLQtWebKit::getInstance()->scrollWheelEvent(mBrowserWindowId, mLastMouseX, mLastMouseY, x, y, decodeModifiers(modifiers)); + } + else if(message_name == "key_event") + { + std::string event = message_in.getValue("event"); + S32 key = message_in.getValueS32("key"); + std::string modifiers = message_in.getValue("modifiers"); + + // Treat unknown events as key-up for safety. + LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP; + if(event == "down") + { + key_event = LLQtWebKit::KE_KEY_DOWN; + } + else if(event == "repeat") + { + key_event = LLQtWebKit::KE_KEY_REPEAT; + } + + keyEvent(key_event, key, decodeModifiers(modifiers)); + } + else if(message_name == "text_event") + { + std::string text = message_in.getValue("text"); + std::string modifiers = message_in.getValue("modifiers"); + + unicodeInput(text, decodeModifiers(modifiers)); + } + if(message_name == "edit_cut") + { + LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT ); + checkEditState(); + } + if(message_name == "edit_copy") + { + LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY ); + checkEditState(); + } + if(message_name == "edit_paste") + { + LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE ); + checkEditState(); + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl; + }; + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) + { + if(message_name == "focus") + { + bool val = message_in.getValueBoolean("focused"); + LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, val ); + + if(mFirstFocus && val) + { + // On the first focus, post a tab key event. This fixes a problem with initial focus. + std::string empty; + keyEvent(LLQtWebKit::KE_KEY_DOWN, KEY_TAB, decodeModifiers(empty)); + keyEvent(LLQtWebKit::KE_KEY_UP, KEY_TAB, decodeModifiers(empty)); + mFirstFocus = false; + } + } + else if(message_name == "clear_cache") + { + LLQtWebKit::getInstance()->clearCache(); + } + else if(message_name == "clear_cookies") + { + LLQtWebKit::getInstance()->clearAllCookies(); + } + else if(message_name == "enable_cookies") + { + bool val = message_in.getValueBoolean("enable"); + LLQtWebKit::getInstance()->enableCookies( val ); + } + else if(message_name == "proxy_setup") + { + bool val = message_in.getValueBoolean("enable"); + std::string host = message_in.getValue("host"); + int port = message_in.getValueS32("port"); + LLQtWebKit::getInstance()->enableProxy( val, host, port ); + } + else if(message_name == "browse_stop") + { + LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_STOP ); + } + else if(message_name == "browse_reload") + { + // foo = message_in.getValueBoolean("ignore_cache"); + LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD ); + } + else if(message_name == "browse_forward") + { + LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD ); + } + else if(message_name == "browse_back") + { + LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK ); + } + else if(message_name == "set_status_redirect") + { + int code = message_in.getValueS32("code"); + std::string url = message_in.getValue("url"); + if ( 404 == code ) // browser lib only supports 404 right now + { + LLQtWebKit::getInstance()->set404RedirectUrl( mBrowserWindowId, url ); + }; + } + else if(message_name == "set_user_agent") + { + std::string user_agent = message_in.getValue("user_agent"); + LLQtWebKit::getInstance()->setBrowserAgentId( user_agent ); + } + else if(message_name == "init_history") + { + // Initialize browser history + LLSD history = message_in.getValueLLSD("history"); + // First, clear the URL history + LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId); + // Then, add the history items in order + LLSD::array_iterator iter_history = history.beginArray(); + LLSD::array_iterator end_history = history.endArray(); + for(; iter_history != end_history; ++iter_history) + { + std::string url = (*iter_history).asString(); + if(! url.empty()) { + LLQtWebKit::getInstance()->prependHistoryUrl(mBrowserWindowId, url); + } + } + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl; + }; + } + else + { +// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; + }; + } +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data); + *plugin_send_func = MediaPluginWebKit::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 16910953b..15561d03b 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -21,8 +21,8 @@ include(LLImage) include(LLImageJ2COJ) include(LLInventory) include(LLMath) -include(LLMedia) include(LLMessage) +include(LLPlugin) include(LLPrimitive) include(LLRender) include(LLUI) @@ -31,7 +31,6 @@ include(LLWindow) include(LLXML) include(LScript) include(Linking) -include(Mozlib) include(NDOF) include(GooglePerfTools) include(TemplateCheck) @@ -55,8 +54,8 @@ include_directories( ${LLIMAGE_INCLUDE_DIRS} ${LLINVENTORY_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} - ${LLMEDIA_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} + ${LLPLUGIN_INCLUDE_DIRS} ${LLPRIMITIVE_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} ${LLUI_INCLUDE_DIRS} @@ -65,7 +64,6 @@ include_directories( ${LLXML_INCLUDE_DIRS} ${LSCRIPT_INCLUDE_DIRS} ${LSCRIPT_INCLUDE_DIRS}/lscript_compile - ${GSTREAMER_INCLUDE_DIRS} ) set(viewer_SOURCE_FILES @@ -185,9 +183,8 @@ set(viewer_SOURCE_FILES llfloatergroups.cpp llfloaterhandler.cpp llfloaterhardwaresettings.cpp - llfloaterhtml.cpp llfloaterhtmlcurrency.cpp - llfloaterhtmlhelp.cpp + llfloatermediabrowser.cpp llfloaterhtmlsimple.cpp llfloaterhud.cpp llfloaterimagepreview.cpp @@ -312,10 +309,12 @@ set(viewer_SOURCE_FILES llpanelinput.cpp llpanelinventory.cpp llpanelland.cpp + llpanellandaudio.cpp llpanellandmedia.cpp llpanellandobjects.cpp llpanellandoptions.cpp llpanellogin.cpp + llpanelmediahud.cpp llpanelmsgs.cpp llpanelnetwork.cpp llpanelobject.cpp @@ -421,6 +420,8 @@ set(viewer_SOURCE_FILES llviewerkeyboard.cpp llviewerlayer.cpp llviewermedia.cpp + llviewermediafocus.cpp + llviewermedia_streamingaudio.cpp llviewermenu.cpp llviewermenufile.cpp llviewermessage.cpp @@ -467,7 +468,7 @@ set(viewer_SOURCE_FILES llwearable.cpp llwearablelist.cpp llweb.cpp - llwebbrowserctrl.cpp + llmediactrl.cpp llwindlightremotectrl.cpp llwind.cpp llwlanimator.cpp @@ -630,9 +631,8 @@ set(viewer_HEADER_FILES llfloatergroups.h llfloaterhandler.h llfloaterhardwaresettings.h - llfloaterhtml.h llfloaterhtmlcurrency.h - llfloaterhtmlhelp.h + llfloatermediabrowser.h llfloaterhtmlsimple.h llfloaterhud.h llfloaterimagepreview.h @@ -756,11 +756,13 @@ set(viewer_HEADER_FILES llpanelinput.h llpanelinventory.h llpanelland.h + llpanellandaudio.h llpanellandmedia.h llpanellandobjects.h llpanellandoptions.h llpanelLCD.h llpanellogin.h + llpanelmediahud.h llpanelmsgs.h llpanelnetwork.h llpanelobject.h @@ -867,6 +869,8 @@ set(viewer_HEADER_FILES llviewerkeyboard.h llviewerlayer.h llviewermedia.h + llviewermediaobserver.h + llviewermediafocus.h llviewermenu.h llviewermenufile.h llviewermessage.h @@ -915,7 +919,7 @@ set(viewer_HEADER_FILES llwearable.h llwearablelist.h llweb.h - llwebbrowserctrl.h + llmediactrl.h llwind.h llwindebug.h llwindlightremotectrl.h @@ -1118,6 +1122,7 @@ if (WINDOWS) if (INTEL_MEMOPS_LIBRARY) list(APPEND viewer_LIBRARIES ${INTEL_MEMOPS_LIBRARY}) endif (INTEL_MEMOPS_LIBRARY) + use_prebuilt_binary(dbghelp) endif (WINDOWS) # Add the xui files. This is handy for searching for xui elements @@ -1134,6 +1139,8 @@ set(viewer_XUI_FILES ) +list(APPEND viewer_XUI_FILES ${viewer_XUI_FILE_GLOB_LIST}) +list(SORT viewer_XUI_FILES) list(APPEND viewer_XUI_FILES ${viewer_XUI_FILE_GLOB_LIST}) list(SORT viewer_XUI_FILES) @@ -1169,6 +1176,7 @@ set(viewer_APPSETTINGS_FILES ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg ) + source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) set_source_files_properties(${viewer_APPSETTINGS_FILES} @@ -1326,6 +1334,9 @@ if (WINDOWS) --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) + + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) + if (PACKAGE) add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat) add_dependencies(package windows-updater windows-crash-logger) @@ -1338,8 +1349,8 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLIMAGE_LIBRARIES} ${LLIMAGEJ2COJ_LIBRARIES} ${LLINVENTORY_LIBRARIES} - ${LLMEDIA_LIBRARIES} ${LLMESSAGE_LIBRARIES} + ${LLPLUGIN_LIBRARIES} ${LLPRIMITIVE_LIBRARIES} ${LLRENDER_LIBRARIES} ${FREETYPE_LIBRARIES} @@ -1361,7 +1372,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${OPENGL_LIBRARIES} ${FMODWRAPPER_LIBRARY} ${OPENGL_LIBRARIES} - ${MOZLIB_LIBRARIES} ${JSONCPP_LIBRARIES} ${SDL_LIBRARY} ${SMARTHEAP_LIBRARY} @@ -1443,6 +1453,8 @@ if (DARWIN) DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010 media_plugin_webkit) + if (PACKAGE) add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME}) add_dependencies(package mac-updater mac-crash-logger) @@ -1461,6 +1473,8 @@ if (DARWIN) --build=${CMAKE_CURRENT_BINARY_DIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched + + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) @@ -1492,3 +1506,65 @@ if (INSTALL) endif (INSTALL) ADD_VIEWER_BUILD_TEST(llagentaccess viewer) + +# Don't do these for DARWIN or LINUX here -- they're taken care of by viewer_manifest.py +if (WINDOWS) + get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${BUILT_SLPLUGIN} + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + COMMENT "Copying SLPlugin executable to the runtime folder." + ) + + get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${BUILT_WEBKIT_PLUGIN} + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin + COMMENT "Copying WebKit Plugin to the runtime folder." + ) + + get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${BUILT_QUICKTIME_PLUGIN} + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin + COMMENT "Copying Quicktime Plugin to the runtime folder." + ) + + # Copying the mime_types.xml file to app_settings + set(mime_types_source "${CMAKE_SOURCE_DIR}/newview/skins/default/xui/en-us") + set(mime_types_dest "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/app_settings") + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${mime_types_source}/mime_types_windows.xml + ${mime_types_dest}/mime_types.xml + COMMENT "Copying mime_types_windows.xml to mime_types.xml." + ) + +endif (WINDOWS) + +if (DARWIN) +# Don't do this here -- it's taken care of by viewer_manifest.py +# add_custom_command(TARGET ${VIEWER_BINARY_NAME} POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin/ +# DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib +# ) +endif (DARWIN) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 0a27aa2fd..4d8084598 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -7624,7 +7624,40 @@ <key>Value</key> <integer>0</integer> </map> - <key>MemoryLogFrequency</key> + <key>MediaControlFadeTime</key> + <map> + <key>Comment</key> + <string>Amount of time (in seconds) that the media control fades</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.5</real> + </map> + <key>MediaControlTimeout</key> + <map> + <key>Comment</key> + <string>Amount of time (in seconds) for media controls to fade with no mouse activity</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>3.0</real> + </map> + <key>MediaOnAPrimUI</key> + <map> + <key>Comment</key> + <string>Whether or not to show the "link sharing" UI</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>MemoryLogFrequency</key> <map> <key>Comment</key> <string>Seconds between display of Memory in log (0 for never)</string> diff --git a/linden/indra/newview/chatbar_as_cmdline.cpp b/linden/indra/newview/chatbar_as_cmdline.cpp index 59804c02b..d90bcd8b4 100644 --- a/linden/indra/newview/chatbar_as_cmdline.cpp +++ b/linden/indra/newview/chatbar_as_cmdline.cpp @@ -16,7 +16,7 @@ * may be used to endorse or promote products derived from this * software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS” + * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS �AS IS� * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS @@ -69,7 +69,7 @@ #include "llviewerparcelmgr.h" #include "llviewerparcelmedia.h" #include "llparcel.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "llviewerparcelmediaautoplay.h" #include "lloverlaybar.h" #include "lggautocorrectfloater.h" diff --git a/linden/indra/newview/floatervoicelicense.cpp b/linden/indra/newview/floatervoicelicense.cpp index 40042908a..74d16c35d 100644 --- a/linden/indra/newview/floatervoicelicense.cpp +++ b/linden/indra/newview/floatervoicelicense.cpp @@ -27,7 +27,7 @@ * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ - +/* #include "llviewerprecompiledheaders.h" #include "floatervoicelicense.h" @@ -234,4 +234,4 @@ void FloaterVoiceLicense::onNavigateComplete( const EventType& eventIn ) LLCheckBoxCtrl * license_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); license_agreement->setEnabled( true ); } -} +}*/ diff --git a/linden/indra/newview/floatervoicelicense.h b/linden/indra/newview/floatervoicelicense.h index 4130d2287..9d2012d46 100644 --- a/linden/indra/newview/floatervoicelicense.h +++ b/linden/indra/newview/floatervoicelicense.h @@ -35,8 +35,8 @@ #include "llmodaldialog.h" #include "llassetstorage.h" -#include "llwebbrowserctrl.h" - +//imprudence fixme: removed for media plugins #include "llwebbrowserctrl.h" +/* class LLButton; class LLRadioGroup; class LLVFS; @@ -45,7 +45,7 @@ class LLUUID; class FloaterVoiceLicense : public LLModalDialog, - public LLWebBrowserCtrlObserver, + public LLViewerMediaObserver public LLFloaterSingleton<FloaterVoiceLicense> { public: @@ -67,6 +67,6 @@ class FloaterVoiceLicense : private: int mWebBrowserWindowId; int mLoadCompleteCount; -}; +};*/ #endif // FLOATERVOICELICENSE_H diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 51b6c5368..5bcffdbc9 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -77,6 +77,7 @@ #include "llfloaterdirectory.h" #include "llfloatergroupinfo.h" #include "llfloatergroups.h" +#include "llfloaterland.h" #include "llfloatermap.h" #include "llfloatermute.h" #include "llfloatersnapshot.h" @@ -113,6 +114,7 @@ #include "llurldispatcher.h" #include "llviewercamera.h" #include "llviewerinventory.h" +#include "llviewermediafocus.h" #include "llviewermenu.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" @@ -6061,7 +6063,11 @@ bool LLAgent::teleportCore(bool is_local) LLFloaterWorldMap::hide(NULL); LLFloaterDirectory::hide(NULL); + // hide land floater too - it'll be out of date + LLFloaterLand::hideInstance(); + LLViewerParcelMgr::getInstance()->deselectLand(); + LLViewerMediaFocus::getInstance()->setFocusFace(false, NULL, 0, NULL); // Close all pie menus, deselect land, etc. // Don't change the camera until we know teleport succeeded. JC diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index b3f3e59cb..86c83b9e1 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -61,8 +61,8 @@ #include "llviewerwindow.h" #include "llviewerdisplay.h" #include "llviewermedia.h" - - +#include "llviewerparcelmedia.h" +#include "llviewermediafocus.h" #include "llviewermessage.h" #include "llviewerobjectlist.h" #include "llworldmap.h" @@ -103,7 +103,8 @@ #include "llassetstorage.h" #include "llpolymesh.h" #include "llcachename.h" -#include "audioengine.h" +#include "llaudioengine.h" +#include "llstreamingaudio.h" #include "llviewermenu.h" #include "llselectmgr.h" #include "lltrans.h" @@ -1257,6 +1258,14 @@ bool LLAppViewer::cleanup() if (gAudiop) { + // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem. + + LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl(); + delete sai; + gAudiop->setStreamingAudioImpl(NULL); + + // shut down the audio subsystem + bool want_longname = false; if (gAudiop->getDriverName(want_longname) == "FMOD") { @@ -1483,7 +1492,9 @@ bool LLAppViewer::cleanup() //Note: //LLViewerMedia::cleanupClass() has to be put before gImageList.shutdown() //because some new image might be generated during cleaning up media. --bao + LLViewerMediaFocus::cleanupClass(); LLViewerMedia::cleanupClass(); + LLViewerParcelMedia::cleanupClass(); gImageList.shutdown(); // shutdown again in case a callback added something LLUIImageList::getInstance()->cleanUp(); @@ -3671,6 +3682,9 @@ void LLAppViewer::idle() gAgent.updateCamera(); } + // update media focus + LLViewerMediaFocus::getInstance()->update(); + // objects and camera should be in sync, do LOD calculations now { LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE); diff --git a/linden/indra/newview/llappviewerlinux.cpp b/linden/indra/newview/llappviewerlinux.cpp index bfad899e4..307f925fc 100644 --- a/linden/indra/newview/llappviewerlinux.cpp +++ b/linden/indra/newview/llappviewerlinux.cpp @@ -437,7 +437,7 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ llinfos << "Was asked to go to slurl: " << slurl << llendl; std::string url = slurl; - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; const bool trusted_browser = false; if (LLURLDispatcher::dispatch(url, web, trusted_browser)) { diff --git a/linden/indra/newview/llappviewermacosx.cpp b/linden/indra/newview/llappviewermacosx.cpp index 3cd083631..3a993eb94 100644 --- a/linden/indra/newview/llappviewermacosx.cpp +++ b/linden/indra/newview/llappviewermacosx.cpp @@ -1,6 +1,6 @@ /** * @file llappviewermacosx.cpp - * @brief The LLAppViewerWin32 class definitions + * @brief The LLAppViewerMacOSX class definitions * * $LicenseInfo:firstyear=2007&license=viewergpl$ * @@ -476,7 +476,7 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) url.replace(0, prefix.length(), "secondlife:///app/"); } - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; const bool trusted_browser = false; LLURLDispatcher::dispatch(url, web, trusted_browser); } diff --git a/linden/indra/newview/llassetuploadresponders.cpp b/linden/indra/newview/llassetuploadresponders.cpp index aff1fb8cd..b9ec9a026 100644 --- a/linden/indra/newview/llassetuploadresponders.cpp +++ b/linden/indra/newview/llassetuploadresponders.cpp @@ -287,7 +287,8 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) LLInventoryView* view = LLInventoryView::getActiveInventory(); if(view) { - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); + LLFocusableElement* focus = gFocusMgr.getKeyboardFocus(); + view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type) && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD) @@ -296,7 +297,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) } //LLInventoryView::dumpSelectionInformation((void*)view); // restore keyboard focus - gFocusMgr.setKeyboardFocus(focus_ctrl); + gFocusMgr.setKeyboardFocus(focus); } } else diff --git a/linden/indra/newview/llaudiosourcevo.h b/linden/indra/newview/llaudiosourcevo.h index e7bb2837a..4b70f8bc2 100644 --- a/linden/indra/newview/llaudiosourcevo.h +++ b/linden/indra/newview/llaudiosourcevo.h @@ -34,7 +34,7 @@ #ifndef LL_LLAUDIOSOURCEVO_H #define LL_LLAUDIOSOURCEVO_H -#include "audioengine.h" +#include "llaudioengine.h" #include "llviewerobject.h" class LLViewerObject; diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp index 0a4ca34a8..99a2a224f 100644 --- a/linden/indra/newview/llchatbar.cpp +++ b/linden/indra/newview/llchatbar.cpp @@ -955,7 +955,7 @@ class LLChatHandler : public LLCommandHandler // Your code here bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { if (tokens.size() < 2) return false; S32 channel = tokens[0].asInteger(); diff --git a/linden/indra/newview/llcommandhandler.cpp b/linden/indra/newview/llcommandhandler.cpp index 422c94ade..a04182a91 100644 --- a/linden/indra/newview/llcommandhandler.cpp +++ b/linden/indra/newview/llcommandhandler.cpp @@ -55,7 +55,7 @@ class LLCommandHandlerRegistry bool dispatch(const std::string& cmd, const LLSD& params, const LLSD& query_map, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser); private: @@ -84,7 +84,7 @@ void LLCommandHandlerRegistry::add(const char* cmd, bool require_trusted_browser bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, const LLSD& params, const LLSD& query_map, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser) { std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd); @@ -126,7 +126,7 @@ LLCommandHandler::~LLCommandHandler() bool LLCommandDispatcher::dispatch(const std::string& cmd, const LLSD& params, const LLSD& query_map, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser) { return LLCommandHandlerRegistry::instance().dispatch( diff --git a/linden/indra/newview/llcommandhandler.h b/linden/indra/newview/llcommandhandler.h index ab4c2cc48..5cb3ee73d 100644 --- a/linden/indra/newview/llcommandhandler.h +++ b/linden/indra/newview/llcommandhandler.h @@ -47,7 +47,7 @@ class LLFooHandler : public LLCommandHandler // Your code here bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { if (tokens.size() < 1) return false; LLUUID id( tokens[0] ); @@ -60,7 +60,7 @@ LLFooHandler gFooHandler; */ -class LLWebBrowserCtrl; +class LLMediaCtrl; class LLCommandHandler { @@ -68,14 +68,14 @@ class LLCommandHandler LLCommandHandler(const char* command, bool allow_from_untrusted_browser); // Automatically registers object to get called when // command is executed. All commands can be processed - // in links from LLWebBrowserCtrl, but some (like teleport) + // in links from LLMediaCtrl, but some (like teleport) // should not be allowed from outside the app. virtual ~LLCommandHandler(); virtual bool handle(const LLSD& params, const LLSD& query_map, - LLWebBrowserCtrl* web) = 0; + LLMediaCtrl* web) = 0; // For URL secondlife:///app/foo/bar/baz?cat=1&dog=2 // @params - array of "bar", "baz", possibly empty // @query_map - map of "cat" -> 1, "dog" -> 2, possibly empty @@ -91,7 +91,7 @@ class LLCommandDispatcher static bool dispatch(const std::string& cmd, const LLSD& params, const LLSD& query_map, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser); // Execute a command registered via the above mechanism, // passing string parameters. diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp index e82aa96a0..ca8614c23 100644 --- a/linden/indra/newview/llfirstuse.cpp +++ b/linden/indra/newview/llfirstuse.cpp @@ -397,8 +397,8 @@ void LLFirstUse::voiceLicenseAgreement() { gSavedSettings.setWarning("FirstVoiceLicense", FALSE); - FloaterVoiceLicense::getInstance()->open(); - FloaterVoiceLicense::getInstance()->center(); +// imprudence fixme FloaterVoiceLicense::getInstance()->open(); +// FloaterVoiceLicense::getInstance()->center(); } else // currently in STATE_LOGIN_VOICE_LICENSE when arriving here { diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 1945df434..d2d12505c 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp @@ -42,7 +42,7 @@ #include "llcurl.h" #include "llimagej2c.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "hippoGridManager.h" #include "llviewertexteditor.h" @@ -57,7 +57,6 @@ #include "lltrans.h" #include "llappviewer.h" #include "llglheaders.h" -#include "llmediamanager.h" #include "llwindow.h" #include "viewerversion.h" @@ -244,26 +243,10 @@ LLFloaterAbout::LLFloaterAbout() support.append("\n"); - LLMediaManager *mgr = LLMediaManager::getInstance(); - if (mgr) - { - LLMediaBase *gstreamer = mgr->createSourceFromMimeType("http", "audio/mpeg"); - if (gstreamer) - { - support.append("GStreamer Version: "); - support.append( gstreamer->getVersion() ); - support.append("\n"); - } - - LLMediaBase *media_source = mgr->createSourceFromMimeType("http", "text/html"); - if (media_source) - { - support.append("LLMozLib Version: "); - support.append(media_source->getVersion()); - support.append("\n"); - mgr->destroySource(media_source); - } - } + // TODO: Implement media plugin version query + + support.append("Qt Webkit Version: 4.5.2 "); + support.append("\n"); if (gPacketsIn > 0) { diff --git a/linden/indra/newview/llfloateravatarinfo.cpp b/linden/indra/newview/llfloateravatarinfo.cpp index 21f160e04..06188750c 100644 --- a/linden/indra/newview/llfloateravatarinfo.cpp +++ b/linden/indra/newview/llfloateravatarinfo.cpp @@ -63,7 +63,7 @@ class LLAgentHandler : public LLCommandHandler LLAgentHandler() : LLCommandHandler("agent", true) { } bool handle(const LLSD& params, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { if (params.size() < 2) return false; LLUUID agent_id; diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index 59f4d703e..2daa5aa4b 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp @@ -190,6 +190,15 @@ void LLFloaterChat::setMinimized(BOOL minimized) updateConsoleVisibility(); } +// linden library includes +#include "llaudioengine.h" +#include "llchat.h" +#include "llfontgl.h" +#include "llrect.h" +#include "llerror.h" +#include "llstring.h" +#include "llwindow.h" +#include "message.h" void LLFloaterChat::updateConsoleVisibility() { @@ -583,13 +592,54 @@ void LLFloaterChat::addChat(const LLChat& chat, if(from_instant_message && gSavedSettings.getBOOL("IMInChatHistory")) addChatHistory(chat,false); - LLTextParser* highlight = LLTextParser::getInstance(); - highlight->triggerAlerts(gAgent.getID(), gAgent.getPositionGlobal(), chat.mText, gViewerWindow->getWindow()); + triggerAlerts(chat.mText); if(!from_instant_message) addChatHistory(chat); } +// Moved from lltextparser.cpp to break llui/llaudio library dependency. +//static +void LLFloaterChat::triggerAlerts(const std::string& text) +{ + LLTextParser* parser = LLTextParser::getInstance(); +// bool spoken=FALSE; + for (S32 i=0;i<parser->mHighlights.size();i++) + { + LLSD& highlight = parser->mHighlights[i]; + if (parser->findPattern(text,highlight) >= 0 ) + { + if(gAudiop) + { + if ((std::string)highlight["sound_lluuid"] != LLUUID::null.asString()) + { + gAudiop->triggerSound(highlight["sound_lluuid"].asUUID(), + gAgent.getID(), + 1.f, + LLAudioEngine::AUDIO_TYPE_UI, + gAgent.getPositionGlobal() ); + } +/* + if (!spoken) + { + LLTextToSpeech* text_to_speech = NULL; + text_to_speech = LLTextToSpeech::getInstance(); + spoken = text_to_speech->speak((LLString)highlight["voice"],text); + } + */ + } + if (highlight["flash"]) + { + LLWindow* viewer_window = gViewerWindow->getWindow(); + if (viewer_window && viewer_window->getMinimized()) + { + viewer_window->flashIcon(5.f); + } + } + } + } +} + LLColor4 get_text_color(const LLChat& chat) { LLColor4 text_color; diff --git a/linden/indra/newview/llfloaterchat.h b/linden/indra/newview/llfloaterchat.h index 5a265672c..f8683b934 100644 --- a/linden/indra/newview/llfloaterchat.h +++ b/linden/indra/newview/llfloaterchat.h @@ -78,6 +78,8 @@ class LLFloaterChat // Add chat to history alone. static void addChatHistory(const LLChat& chat, bool log_to_file = true); + static void triggerAlerts(const std::string& text); + static void onClickMute(void *data); static void onClickToggleShowMute(LLUICtrl* caller, void *data); static void onClickToggleTranslateChat(LLUICtrl* caller, void *data); diff --git a/linden/indra/newview/llfloaterclassified.cpp b/linden/indra/newview/llfloaterclassified.cpp index d426e0421..07603039b 100644 --- a/linden/indra/newview/llfloaterclassified.cpp +++ b/linden/indra/newview/llfloaterclassified.cpp @@ -57,7 +57,7 @@ class LLClassifiedHandler : public LLCommandHandler // requires trusted browser to trigger LLClassifiedHandler() : LLCommandHandler("classified", true) { } bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { if (tokens.size() < 2) { diff --git a/linden/indra/newview/llfloaterevent.cpp b/linden/indra/newview/llfloaterevent.cpp index 485c13c7b..0ec2a7637 100644 --- a/linden/indra/newview/llfloaterevent.cpp +++ b/linden/indra/newview/llfloaterevent.cpp @@ -58,7 +58,7 @@ class LLEventHandler : public LLCommandHandler // requires trusted browser to trigger LLEventHandler() : LLCommandHandler("event", true) { } bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { if (tokens.size() < 2) { diff --git a/linden/indra/newview/llfloatergroupinfo.cpp b/linden/indra/newview/llfloatergroupinfo.cpp index 6fbd5e176..3ae7d5a87 100644 --- a/linden/indra/newview/llfloatergroupinfo.cpp +++ b/linden/indra/newview/llfloatergroupinfo.cpp @@ -60,7 +60,7 @@ class LLGroupHandler : public LLCommandHandler // requires trusted browser to trigger LLGroupHandler() : LLCommandHandler("group", true) { } bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { if (tokens.size() < 1) { diff --git a/linden/indra/newview/llfloaterhandler.cpp b/linden/indra/newview/llfloaterhandler.cpp index f4c7e43a7..7cf715662 100644 --- a/linden/indra/newview/llfloaterhandler.cpp +++ b/linden/indra/newview/llfloaterhandler.cpp @@ -31,7 +31,7 @@ #include "llfloaterhandler.h" #include "llfloater.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" // register with dispatch via global object LLFloaterHandler gFloaterHandler; @@ -54,7 +54,7 @@ LLFloater* get_parent_floater(LLView* view) } -bool LLFloaterHandler::handle(const LLSD ¶ms, const LLSD &query_map, LLWebBrowserCtrl *web) +bool LLFloaterHandler::handle(const LLSD ¶ms, const LLSD &query_map, LLMediaCtrl *web) { if (params.size() < 2) return false; LLFloater* floater = NULL; diff --git a/linden/indra/newview/llfloaterhandler.h b/linden/indra/newview/llfloaterhandler.h index b08f1f35b..31ea80c12 100644 --- a/linden/indra/newview/llfloaterhandler.h +++ b/linden/indra/newview/llfloaterhandler.h @@ -39,7 +39,7 @@ class LLFloaterHandler { public: LLFloaterHandler() : LLCommandHandler("floater", true) { } - bool handle(const LLSD& params, const LLSD& query_map, LLWebBrowserCtrl* web); + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web); }; #endif diff --git a/linden/indra/newview/llfloaterhtmlsimple.cpp b/linden/indra/newview/llfloaterhtmlsimple.cpp index 7dfc4f638..8091c1e97 100644 --- a/linden/indra/newview/llfloaterhtmlsimple.cpp +++ b/linden/indra/newview/llfloaterhtmlsimple.cpp @@ -35,7 +35,7 @@ #include "llfloaterhtmlsimple.h" #include "lluictrlfactory.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" LLFloaterHtmlSimple::LLFloaterHtmlSimple(const LLSD &initial_url) @@ -56,12 +56,12 @@ LLFloaterHtmlSimple::~LLFloaterHtmlSimple() void LLFloaterHtmlSimple::navigateTo(const std::string &url) { - LLWebBrowserCtrl* web = getChild<LLWebBrowserCtrl>("browser"); + LLMediaCtrl* web = getChild<LLMediaCtrl>("browser"); web->navigateTo(url); } void LLFloaterHtmlSimple::setTrusted(bool trusted) { - LLWebBrowserCtrl* web = getChild<LLWebBrowserCtrl>("browser"); + LLMediaCtrl* web = getChild<LLMediaCtrl>("browser"); web->setTrusted(trusted); } diff --git a/linden/indra/newview/llfloaterhud.cpp b/linden/indra/newview/llfloaterhud.cpp index 9810bf100..6324b5656 100644 --- a/linden/indra/newview/llfloaterhud.cpp +++ b/linden/indra/newview/llfloaterhud.cpp @@ -36,7 +36,7 @@ // Viewer libs #include "llviewercontrol.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" #include "llalertdialog.h" // Linden libs @@ -74,7 +74,7 @@ LLFloaterHUD::LLFloaterHUD() reshape(saved_position_rect.getWidth(), saved_position_rect.getHeight(), FALSE); setRect(saved_position_rect); - mWebBrowser = getChild<LLWebBrowserCtrl>("floater_hud_browser" ); + mWebBrowser = getChild<LLMediaCtrl>("floater_hud_browser" ); if (mWebBrowser) { // Open links in internal browser diff --git a/linden/indra/newview/llfloaterhud.h b/linden/indra/newview/llfloaterhud.h index 2d58685b5..919ffefdb 100644 --- a/linden/indra/newview/llfloaterhud.h +++ b/linden/indra/newview/llfloaterhud.h @@ -35,7 +35,7 @@ #include "llfloater.h" -class LLWebBrowserCtrl; +class LLMediaCtrl; class LLFloaterHUD : public LLFloater { @@ -53,7 +53,7 @@ class LLFloaterHUD : public LLFloater /*virtual*/ ~LLFloaterHUD(); private: - LLWebBrowserCtrl* mWebBrowser; ///< the actual web browser control + LLMediaCtrl* mWebBrowser; ///< the actual web browser control static LLFloaterHUD* sInstance; }; diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp index 066b739b3..39de55f01 100644 --- a/linden/indra/newview/llfloaterland.cpp +++ b/linden/indra/newview/llfloaterland.cpp @@ -56,6 +56,7 @@ #include "lllineeditor.h" #include "llnamelistctrl.h" #include "llnotify.h" +#include "llpanellandaudio.h" #include "llpanellandmedia.h" #include "llradiogroup.h" #include "llscrolllistctrl.h" @@ -204,6 +205,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this); factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this); +// factory_map["land_audio_panel"] = LLCallbackMap(createPanelLandAudio, this); factory_map["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); factory_map["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); @@ -239,6 +241,7 @@ void LLFloaterLand::refresh() mPanelGeneral->refresh(); mPanelObjects->refresh(); mPanelOptions->refresh(); +// mPanelAudio->refresh(); mPanelMedia->refresh(); mPanelAccess->refresh(); } @@ -277,6 +280,15 @@ void* LLFloaterLand::createPanelLandOptions(void* data) return self->mPanelOptions; } +/* +// static +void* LLFloaterLand::createPanelLandAudio(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelAudio = new LLPanelLandAudio(self->mParcel); + return self->mPanelAudio; +} +*/ // static void* LLFloaterLand::createPanelLandMedia(void* data) { diff --git a/linden/indra/newview/llfloaterland.h b/linden/indra/newview/llfloaterland.h index 113b679d7..4105f4426 100644 --- a/linden/indra/newview/llfloaterland.h +++ b/linden/indra/newview/llfloaterland.h @@ -64,6 +64,7 @@ class LLParcelSelection; class LLPanelLandGeneral; class LLPanelLandObjects; class LLPanelLandOptions; +class LLPanelLandAudio; class LLPanelLandMedia; class LLPanelLandAccess; class LLPanelLandBan; @@ -102,6 +103,7 @@ class LLFloaterLand static void* createPanelLandCovenant(void* data); static void* createPanelLandObjects(void* data); static void* createPanelLandOptions(void* data); + static void* createPanelLandAudio(void* data); static void* createPanelLandMedia(void* data); static void* createPanelLandAccess(void* data); static void* createPanelLandBan(void* data); @@ -115,6 +117,7 @@ class LLFloaterLand LLPanelLandGeneral* mPanelGeneral; LLPanelLandObjects* mPanelObjects; LLPanelLandOptions* mPanelOptions; +// LLPanelLandAudio* mPanelAudio; LLPanelLandMedia* mPanelMedia; LLPanelLandAccess* mPanelAccess; LLPanelLandCovenant* mPanelCovenant; diff --git a/linden/indra/newview/llfloatermediabrowser.cpp b/linden/indra/newview/llfloatermediabrowser.cpp new file mode 100644 index 000000000..def015943 --- /dev/null +++ b/linden/indra/newview/llfloatermediabrowser.cpp @@ -0,0 +1,398 @@ +/** + * @file llfloaterhtmlhelp.cpp + * @brief HTML Help floater - uses embedded web browser control + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatermediabrowser.h" +#include "llfloaterhtml.h" + +#include "llparcel.h" +#include "llpluginclassmedia.h" +#include "lluictrlfactory.h" +#include "llmediactrl.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" +#include "llviewerparcelmgr.h" +#include "llweb.h" +#include "llui.h" +#include "roles_constants.h" + +#include "llurlhistory.h" +#include "llmediactrl.h" +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" +#include "llcombobox.h" + + +// TEMP +#include "llsdutil.h" + +LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_browser.xml"); + +} + +void LLFloaterMediaBrowser::draw() +{ + childSetEnabled("go", !mAddressCombo->getValue().asString().empty()); + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if(parcel) + { + childSetVisible("parcel_owner_controls", LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA)); + childSetEnabled("assign", !mAddressCombo->getValue().asString().empty()); + } + bool show_time_controls = false; + bool media_playing = false; + if(mBrowser) + { + LLPluginClassMedia* media_plugin = mBrowser->getMediaPlugin(); + if(media_plugin) + { + show_time_controls = media_plugin->pluginSupportsMediaTime(); + media_playing = media_plugin->getStatus() == LLPluginClassMediaOwner::MEDIA_PLAYING; + } + } + childSetVisible("rewind", show_time_controls); + childSetVisible("play", show_time_controls && ! media_playing); + childSetVisible("pause", show_time_controls && media_playing); + childSetVisible("stop", show_time_controls); + childSetVisible("seek", show_time_controls); + + childSetEnabled("play", ! media_playing); + childSetEnabled("stop", media_playing); + + childSetEnabled("back", mBrowser->canNavigateBack()); + childSetEnabled("forward", mBrowser->canNavigateForward()); + + LLFloater::draw(); +} + +BOOL LLFloaterMediaBrowser::postBuild() +{ + mBrowser = getChild<LLMediaCtrl>("browser"); + mBrowser->addObserver(this); + + mAddressCombo = getChild<LLComboBox>("address"); + mAddressCombo->setCommitCallback(onEnterAddress); + mAddressCombo->setCallbackUserData(this); + + childSetAction("back", onClickBack, this); + childSetAction("forward", onClickForward, this); + childSetAction("reload", onClickRefresh, this); + childSetAction("rewind", onClickRewind, this); + childSetAction("play", onClickPlay, this); + childSetAction("stop", onClickStop, this); + childSetAction("pause", onClickPlay, this); + childSetAction("seek", onClickSeek, this); + childSetAction("go", onClickGo, this); + childSetAction("close", onClickClose, this); + childSetAction("open_browser", onClickOpenWebBrowser, this); + childSetAction("assign", onClickAssign, this); + + buildURLHistory(); + return TRUE; +} + +void LLFloaterMediaBrowser::buildURLHistory() +{ + LLCtrlListInterface* url_list = childGetListInterface("address"); + if (url_list) + { + url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + // Get all of the entries in the "browser" collection + LLSD browser_history = LLURLHistory::getURLHistory("browser"); + + LLSD::array_iterator iter_history = + browser_history.beginArray(); + LLSD::array_iterator end_history = + browser_history.endArray(); + for(; iter_history != end_history; ++iter_history) + { + std::string url = (*iter_history).asString(); + if(! url.empty()) + url_list->addSimpleElement(url); + } + + // initialize URL history in the plugin + mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history); +} + +std::string LLFloaterMediaBrowser::getSupportURL() +{ + return getString("support_page_url"); +} +void LLFloaterMediaBrowser::onClose(bool app_quitting) +{ + //setVisible(FALSE); + destroy(); +} + +void LLFloaterMediaBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + if(event == MEDIA_EVENT_LOCATION_CHANGED) + { + setCurrentURL(self->getLocation()); + } + else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) + { + // This is the event these flags are sent with. + childSetEnabled("back", self->getHistoryBackAvailable()); + childSetEnabled("forward", self->getHistoryForwardAvailable()); + } +} +void LLFloaterMediaBrowser::setCurrentURL(const std::string& url) +{ + mCurrentURL = url; + + // redirects will navigate momentarily to about:blank, don't add to history + if (mCurrentURL != "about:blank") + { + mAddressCombo->remove(mCurrentURL); + mAddressCombo->add(mCurrentURL, ADD_SORTED); + mAddressCombo->selectByValue(mCurrentURL); + + // Serialize url history + LLURLHistory::removeURL("browser", mCurrentURL); + LLURLHistory::addURL("browser", mCurrentURL); + } + childSetEnabled("back", mBrowser->canNavigateBack()); + childSetEnabled("forward", mBrowser->canNavigateForward()); + childSetEnabled("reload", TRUE); +} + +LLFloaterMediaBrowser* LLFloaterMediaBrowser::showInstance(const LLSD& media_url) +{ + LLFloaterMediaBrowser* floaterp = LLUISingleton<LLFloaterMediaBrowser, VisibilityPolicy<LLFloater> >::showInstance(media_url); + + floaterp->openMedia(media_url.asString()); + return floaterp; +} + +//static +void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); +} + +//static +void LLFloaterMediaBrowser::onClickRefresh(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mAddressCombo->remove(0); + self->mBrowser->navigateTo(self->mCurrentURL); +} + +//static +void LLFloaterMediaBrowser::onClickForward(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mBrowser->navigateForward(); +} + +//static +void LLFloaterMediaBrowser::onClickBack(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mBrowser->navigateBack(); +} + +//static +void LLFloaterMediaBrowser::onClickGo(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); +} + +//static +void LLFloaterMediaBrowser::onClickClose(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->close(); +} + +//static +void LLFloaterMediaBrowser::onClickOpenWebBrowser(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + std::string url = self->mCurrentURL.empty() ? + self->mBrowser->getHomePageUrl() : + self->mCurrentURL; + LLWeb::loadURLExternal(url); +} + +void LLFloaterMediaBrowser::onClickAssign(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!parcel) + { + return; + } + std::string media_url = self->mAddressCombo->getValue().asString(); + LLStringUtil::trim(media_url); + + if(parcel->getMediaType() != "text/html") + { + parcel->setMediaURL(media_url); + parcel->setMediaCurrentURL(media_url); + parcel->setMediaType(std::string("text/html")); + LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel, true ); + LLViewerParcelMedia::sendMediaNavigateMessage(media_url); + LLViewerParcelMedia::stop(); + // LLViewerParcelMedia::update( parcel ); + } + LLViewerParcelMedia::sendMediaNavigateMessage(media_url); +} +//static +void LLFloaterMediaBrowser::onClickRewind(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + if(self->mBrowser->getMediaPlugin()) + self->mBrowser->getMediaPlugin()->start(-2.0f); +} +//static +void LLFloaterMediaBrowser::onClickPlay(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + LLPluginClassMedia* plugin = self->mBrowser->getMediaPlugin(); + if(plugin) + { + if(plugin->getStatus() == LLPluginClassMediaOwner::MEDIA_PLAYING) + { + plugin->pause(); + } + else + { + plugin->start(); + } + } +} +//static +void LLFloaterMediaBrowser::onClickStop(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + if(self->mBrowser->getMediaPlugin()) + self->mBrowser->getMediaPlugin()->stop(); +} +//static +void LLFloaterMediaBrowser::onClickSeek(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + if(self->mBrowser->getMediaPlugin()) + self->mBrowser->getMediaPlugin()->start(2.0f); +} +void LLFloaterMediaBrowser::openMedia(const std::string& media_url) +{ + mBrowser->setHomePageUrl(media_url); + mBrowser->navigateTo(media_url); + setCurrentURL(media_url); +} +//////////////////////////////////////////////////////////////////////////////// +// + +LLViewerHtmlHelp gViewerHtmlHelp; + + +//////////////////////////////////////////////////////////////////////////////// +// +LLViewerHtmlHelp::LLViewerHtmlHelp() +{ + + LLUI::setHtmlHelp(this); +} + +LLViewerHtmlHelp::~LLViewerHtmlHelp() +{ + + LLUI::setHtmlHelp(NULL); +} + +void LLViewerHtmlHelp::show() +{ + show(""); +} + +void LLViewerHtmlHelp::show(std::string url) +{ + LLFloaterMediaBrowser* floater_html = LLFloaterMediaBrowser::getInstance(); + floater_html->setVisible(FALSE); + + if (url.empty()) + { + url = floater_html->getSupportURL(); + } + + if (gSavedSettings.getBOOL("UseExternalBrowser")) + { + LLSD notificationData; + notificationData["url"] = url; + + LLNotifications::instance().add("ClickOpenF1Help", notificationData, LLSD(), onClickF1HelpLoadURL); + floater_html->close(); + } + else + { + // don't wait, just do it + floater_html->setVisible(TRUE); + floater_html->openMedia(url); + } +} +// static +bool LLViewerHtmlHelp::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response) +{ + LLFloaterMediaBrowser* floater_html = LLFloaterMediaBrowser::getInstance(); + floater_html->setVisible(FALSE); + std::string url = floater_html->getSupportURL(); + S32 option = LLNotification::getSelectedOption(notification, response); + if (option == 0) + { + LLWeb::loadURL(url); + } + floater_html->close(); + return false; +} + diff --git a/linden/indra/newview/llfloaterhtmlhelp.h b/linden/indra/newview/llfloatermediabrowser.h similarity index 78% rename from linden/indra/newview/llfloaterhtmlhelp.h rename to linden/indra/newview/llfloatermediabrowser.h index 83f15cdaf..8a78df833 100644 --- a/linden/indra/newview/llfloaterhtmlhelp.h +++ b/linden/indra/newview/llfloatermediabrowser.h @@ -35,7 +35,7 @@ #include "llhtmlhelp.h" #include "llfloater.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" class LLViewerHtmlHelp : public LLHtmlHelp { @@ -45,28 +45,38 @@ class LLViewerHtmlHelp : public LLHtmlHelp /*virtual*/ void show(); /*virtual*/ void show(std::string start_url); + void show(std::string start_url, std::string title); + + static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response); + }; class LLComboBox; -class LLWebBrowserCtrl; +class LLMediaCtrl; -class LLFloaterMediaBrowser : public LLFloater, public LLFloaterSingleton<LLFloaterMediaBrowser>, public LLWebBrowserCtrlObserver +class LLFloaterMediaBrowser : + public LLFloater, + public LLUISingleton<LLFloaterMediaBrowser, + VisibilityPolicy<LLFloater> >, + public LLViewerMediaObserver { public: LLFloaterMediaBrowser(const LLSD& media_data); /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ void onLocationChange( const EventType& eventIn ); - /*virtual*/ void draw(); + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); + void openMedia(const std::string& media_url); void buildURLHistory(); + std::string getSupportURL(); + void setCurrentURL(const std::string& url); - static void helpF1(); -private: + static LLFloaterMediaBrowser* showInstance(const LLSD& id); static void onEnterAddress(LLUICtrl* ctrl, void* user_data); static void onClickRefresh(void* user_data); static void onClickBack(void* user_data); @@ -75,11 +85,13 @@ class LLFloaterMediaBrowser : public LLFloater, public LLFloaterSingleton<LLFloa static void onClickClose(void* user_data); static void onClickOpenWebBrowser(void* user_data); static void onClickAssign(void* user_data); - static void onClickHome(void* user_data); - static void onClickSetHome(void* user_data); - static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response); + static void onClickRewind(void* user_data); + static void onClickPlay(void* user_data); + static void onClickStop(void* user_data); + static void onClickSeek(void* user_data); - LLWebBrowserCtrl* mBrowser; +private: + LLMediaCtrl* mBrowser; LLComboBox* mAddressCombo; std::string mCurrentURL; }; diff --git a/linden/indra/newview/llfloaterobjectiminfo.cpp b/linden/indra/newview/llfloaterobjectiminfo.cpp index fa7964c22..f933a85d2 100644 --- a/linden/indra/newview/llfloaterobjectiminfo.cpp +++ b/linden/indra/newview/llfloaterobjectiminfo.cpp @@ -137,7 +137,7 @@ void LLFloaterObjectIMInfo::onClickMap(void* data) std::ostringstream link; link << "secondlife://" << self->mSlurl; - class LLWebBrowserCtrl* web = NULL; + class LLMediaCtrl* web = NULL; LLURLDispatcher::dispatch(link.str(), web, true); } @@ -213,14 +213,14 @@ class LLObjectIMInfoHandler : public LLCommandHandler LLObjectIMInfoHandler() : LLCommandHandler("objectim", true) { } bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web); + LLMediaCtrl* web); }; // Creating the object registers with the dispatcher. LLObjectIMInfoHandler gObjectIMHandler; // ex. secondlife:///app/objectim/9426adfc-9c17-8765-5f09-fdf19957d003?owner=a112d245-9095-4e9c-ace4-ffa31717f934&groupowned=true&slurl=ahern/123/123/123&name=Object -bool LLObjectIMInfoHandler::handle(const LLSD &tokens, const LLSD &query_map, LLWebBrowserCtrl* web) +bool LLObjectIMInfoHandler::handle(const LLSD &tokens, const LLSD &query_map, LLMediaCtrl* web) { LLUUID task_id = tokens[0].asUUID(); std::string name = query_map["name"].asString(); diff --git a/linden/indra/newview/llfloaterparcel.cpp b/linden/indra/newview/llfloaterparcel.cpp index 421315055..a61f3b912 100644 --- a/linden/indra/newview/llfloaterparcel.cpp +++ b/linden/indra/newview/llfloaterparcel.cpp @@ -55,7 +55,7 @@ class LLParcelHandler : public LLCommandHandler // requires trusted browser to trigger LLParcelHandler() : LLCommandHandler("parcel", true) { } bool handle(const LLSD& params, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { if (params.size() < 2) { diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp index 09336cb8f..a94f7cf98 100644 --- a/linden/indra/newview/llfloaterpreference.cpp +++ b/linden/indra/newview/llfloaterpreference.cpp @@ -94,7 +94,7 @@ class LLPreferencesHandler : public LLCommandHandler // requires trusted browser LLPreferencesHandler() : LLCommandHandler("preferences", true) { } bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { LLFloaterPreference::show(NULL); return true; @@ -445,7 +445,7 @@ void LLFloaterPreference::onBtnOK( void* userdata ) // commit any outstanding text entry if (fp->hasFocus()) { - LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (cur_focus->acceptsTextInput()) { cur_focus->onCommit(); @@ -479,7 +479,7 @@ void LLFloaterPreference::onBtnApply( void* userdata ) LLFloaterPreference *fp =(LLFloaterPreference *)userdata; if (fp->hasFocus()) { - LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (cur_focus->acceptsTextInput()) { cur_focus->onCommit(); @@ -505,7 +505,7 @@ void LLFloaterPreference::onBtnCancel( void* userdata ) LLFloaterPreference *fp =(LLFloaterPreference *)userdata; if (fp->hasFocus()) { - LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (cur_focus->acceptsTextInput()) { cur_focus->onCommit(); diff --git a/linden/indra/newview/llfloatertos.cpp b/linden/indra/newview/llfloatertos.cpp index 6a392e03f..2dedc79af 100644 --- a/linden/indra/newview/llfloatertos.cpp +++ b/linden/indra/newview/llfloatertos.cpp @@ -161,12 +161,10 @@ BOOL LLFloaterTOS::postBuild() LLTextEditor *editor = getChild<LLTextEditor>("tos_text"); editor->setVisible( FALSE ); - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); + LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("tos_html"); if ( web_browser ) { - // start to observe it so we see navigate complete events - web_browser->addObserver( this ); - + web_browser->addObserver(this); gResponsePtr = LLIamHere::build( this ); LLHTTPClient::get( getString( "real_url" ), gResponsePtr ); } @@ -179,7 +177,7 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) // only do this for TOS pages if ( mType == TOS_TOS ) { - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); + LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("tos_html"); // if the contents of the site was retrieved if ( alive ) { @@ -201,12 +199,6 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) LLFloaterTOS::~LLFloaterTOS() { - // stop obsaerving events - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); - if ( web_browser ) - { - web_browser->remObserver( this ); - }; // tell the responder we're not here anymore if ( gResponsePtr ) @@ -269,14 +261,17 @@ void LLFloaterTOS::onCancel( void* userdata ) } //virtual -void LLFloaterTOS::onNavigateComplete( const EventType& eventIn ) +void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event) { - // skip past the loading screen navigate complete - if ( ++mLoadCompleteCount == 2 ) + if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) { - llinfos << "NAVIGATE COMPLETE" << llendl; - // enable Agree to TOS radio button now that page has loaded - LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); - tos_agreement->setEnabled( true ); - }; + // skip past the loading screen navigate complete + if ( ++mLoadCompleteCount == 2 ) + { + llinfos << "NAVIGATE COMPLETE" << llendl; + // enable Agree to TOS radio button now that page has loaded + LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); + tos_agreement->setEnabled( true ); + } + } } diff --git a/linden/indra/newview/llfloatertos.h b/linden/indra/newview/llfloatertos.h index dbec3ff8b..c5d587897 100644 --- a/linden/indra/newview/llfloatertos.h +++ b/linden/indra/newview/llfloatertos.h @@ -35,7 +35,7 @@ #include "llmodaldialog.h" #include "llassetstorage.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" class LLButton; class LLRadioGroup; @@ -45,7 +45,7 @@ class LLUUID; class LLFloaterTOS : public LLModalDialog, - public LLWebBrowserCtrlObserver + public LLViewerMediaObserver { public: virtual ~LLFloaterTOS(); @@ -70,7 +70,8 @@ class LLFloaterTOS : void setSiteIsAlive( bool alive ); - virtual void onNavigateComplete( const EventType& eventIn ); + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); private: // Asset_id is overwritten with LLUUID::null when agree is clicked. diff --git a/linden/indra/newview/llfloaterurlentry.cpp b/linden/indra/newview/llfloaterurlentry.cpp index 9d91aa986..8d483e59e 100644 --- a/linden/indra/newview/llfloaterurlentry.cpp +++ b/linden/indra/newview/llfloaterurlentry.cpp @@ -227,7 +227,7 @@ void LLFloaterURLEntry::onBtnOK( void* userdata ) } // Discover the MIME type only for "http" scheme. - if(scheme == "http") + if(scheme == "http" || scheme == "https") { LLHTTPClient::getHeaderOnly( media_url, new LLMediaTypeResponder(self->getHandle())); diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp index 636738018..109eeceb3 100644 --- a/linden/indra/newview/llhoverview.cpp +++ b/linden/indra/newview/llhoverview.cpp @@ -154,12 +154,13 @@ void LLHoverView::updateHover(LLTool* current_tool) void LLHoverView::pickCallback(const LLPickInfo& pick_info) { + gHoverView->mLastPickInfo = pick_info; LLViewerObject* hit_obj = pick_info.getObject(); if (hit_obj) { gHoverView->setHoverActive(TRUE); - LLSelectMgr::getInstance()->setHoverObject(hit_obj); + LLSelectMgr::getInstance()->setHoverObject(hit_obj, pick_info.mObjectFace); gHoverView->mLastHoverObject = hit_obj; gHoverView->mHoverOffset = pick_info.mObjectOffset; } diff --git a/linden/indra/newview/llhoverview.h b/linden/indra/newview/llhoverview.h index 0891118b7..d0bb28d83 100644 --- a/linden/indra/newview/llhoverview.h +++ b/linden/indra/newview/llhoverview.h @@ -42,6 +42,7 @@ #include "v3dmath.h" #include "lldarray.h" +#include "llviewerwindow.h" #include "llviewerobject.h" class LLTool; @@ -79,6 +80,7 @@ class LLHoverView : public LLView BOOL isHoveringLand() const; LLViewerObject* getLastHoverObject() const; + LLPickInfo getPickInfo() { return mLastPickInfo; } static void pickCallback(const LLPickInfo& info); @@ -103,6 +105,7 @@ class LLHoverView : public LLView // If not null and not dead, we're over an object. LLPointer<LLViewerObject> mLastHoverObject; + LLPickInfo mLastPickInfo; // If not LLVector3d::ZERO, we're over land. LLVector3d mHoverLandGlobal; diff --git a/linden/indra/newview/llhudview.cpp b/linden/indra/newview/llhudview.cpp index 198514ce0..afcdd73c9 100644 --- a/linden/indra/newview/llhudview.cpp +++ b/linden/indra/newview/llhudview.cpp @@ -48,14 +48,19 @@ #include "lltracker.h" #include "llviewercamera.h" #include "llui.h" +#include "lluictrlfactory.h" LLHUDView *gHUDView = NULL; const S32 HUD_ARROW_SIZE = 32; -LLHUDView::LLHUDView() -: LLPanel() -{ } + + +LLHUDView::LLHUDView(const LLRect& r) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_hud.xml"); + userSetShape(r); +} LLHUDView::~LLHUDView() { } @@ -64,6 +69,7 @@ LLHUDView::~LLHUDView() void LLHUDView::draw() { LLTracker::drawHUDArrow(); + LLView::draw(); } @@ -89,4 +95,3 @@ BOOL LLHUDView::handleMouseDown(S32 x, S32 y, MASK mask) } return LLView::handleMouseDown(x, y, mask); } - diff --git a/linden/indra/newview/llhudview.h b/linden/indra/newview/llhudview.h index 7859e7f8b..05ff9c859 100644 --- a/linden/indra/newview/llhudview.h +++ b/linden/indra/newview/llhudview.h @@ -42,7 +42,7 @@ class LLHUDView : public LLPanel { public: - LLHUDView(); + LLHUDView(const LLRect& rect); virtual ~LLHUDView(); virtual void draw(); diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp index 808a2c994..cc7a35d43 100644 --- a/linden/indra/newview/llimpanel.cpp +++ b/linden/indra/newview/llimpanel.cpp @@ -2198,8 +2198,8 @@ void LLFloaterIMPanel::sendMsg() LLViewerStats::getInstance()->incStat(LLViewerStats::ST_IM_COUNT); + mInputEditor->setText(LLStringUtil::null); } - mInputEditor->setText(LLStringUtil::null); // Don't need to actually send the typing stop message, the other // client will infer it from receiving the message. diff --git a/linden/indra/newview/llloginhandler.cpp b/linden/indra/newview/llloginhandler.cpp index 636639856..30b05ef98 100644 --- a/linden/indra/newview/llloginhandler.cpp +++ b/linden/indra/newview/llloginhandler.cpp @@ -111,7 +111,7 @@ void LLLoginHandler::parse(const LLSD& queryMap) bool LLLoginHandler::handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { parse(query_map); diff --git a/linden/indra/newview/llloginhandler.h b/linden/indra/newview/llloginhandler.h index c76d7e827..0844b80c7 100644 --- a/linden/indra/newview/llloginhandler.h +++ b/linden/indra/newview/llloginhandler.h @@ -40,7 +40,7 @@ class LLLoginHandler : public LLCommandHandler public: // allow from external browsers LLLoginHandler() : LLCommandHandler("login", false) { } - /*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web); + /*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web); // Fill in our internal fields from a SLURL like // secondlife:///app/login?first=Bob&last=Dobbs diff --git a/linden/indra/newview/llmediactrl.cpp b/linden/indra/newview/llmediactrl.cpp new file mode 100644 index 000000000..153059897 --- /dev/null +++ b/linden/indra/newview/llmediactrl.cpp @@ -0,0 +1,1201 @@ +/** + * @file LLMediaCtrl.cpp + * @brief Web browser UI control + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + + +#include "llmediactrl.h" + +// viewer includes +#include "llfloaterhtml.h" +#include "llfloaterworldmap.h" +#include "lluictrlfactory.h" +#include "llurldispatcher.h" +#include "llurlsimstring.h" +#include "llviewborder.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llviewerwindow.h" +#include "llnotifications.h" +#include "llweb.h" +#include "llrender.h" +#include "llpluginclassmedia.h" + +// linden library includes +#include "llfocusmgr.h" + +extern BOOL gRestoreGL; + +// Setting the mozilla buffer width to 2048 exactly doesn't work, since it pads its rowbytes a bit, pushing the texture width over 2048. +// 2000 should give enough headroom for any amount of padding it cares to add. +const S32 MAX_DIMENSION = 2000; +const S32 MAX_TEXTURE_DIMENSION = 2048; + +static LLRegisterWidget<LLMediaCtrl> r("web_browser"); + +LLMediaCtrl::LLMediaCtrl( const std::string& name, const LLRect& rect ) : + LLUICtrl( name, rect, FALSE, NULL, NULL ), + mTextureDepthBytes( 4 ), + mWebBrowserImage( 0 ), + mBorder(NULL), + mFrequentUpdates( true ), + mForceUpdate( false ), + mOpenLinksInExternalBrowser( false ), + mOpenLinksInInternalBrowser( false ), + mTrusted( false ), + mHomePageUrl( "" ), + mIgnoreUIScale( true ), + mAlwaysRefresh( false ), + mExternalUrl( "" ), + mMediaSource( 0 ), + mTakeFocusOnClick( true ), + mCurrentNavUrl( "about:blank" ), + mLastSetCursor( UI_CURSOR_ARROW ), + mStretchToFill( true ), + mMaintainAspectRatio ( true ), + mHideLoading (false) +{ + S32 screen_width = mIgnoreUIScale ? + llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth(); + S32 screen_height = mIgnoreUIScale ? + llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight(); + + mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, LLUUID::null, screen_width, screen_height, false, false, "text/html"); + if ( !mMediaSource ) + { + llwarns << "media source create failed " << llendl; + // return; + } + else + { + // create a new texture (based on LLDynamic texture) that will be used to display the output + mWebBrowserImage = new LLWebBrowserTexture( screen_width, screen_height, this, mMediaSource ); + } + + mMediaSource->setVisible( getVisible() ); + + mMediaSource->addObserver( this ); + + LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); + mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN ); + addChild( mBorder ); +} + +//////////////////////////////////////////////////////////////////////////////// +// note: this is now a singleton and destruction happens via initClass() now +LLMediaCtrl::~LLMediaCtrl() +{ + + if (mMediaSource) + { + mMediaSource->remObserver( this ); + mMediaSource = NULL; + } + + if ( mWebBrowserImage ) + { + delete mWebBrowserImage; + mWebBrowserImage = NULL; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::setBorderVisible( BOOL border_visible ) +{ + if ( mBorder ) + { + mBorder->setVisible( border_visible ); + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::setTakeFocusOnClick( bool take_focus ) +{ + mTakeFocusOnClick = take_focus; +} + +//////////////////////////////////////////////////////////////////////////////// +// set flag that forces the embedded browser to open links in the external system browser +void LLMediaCtrl::setOpenInExternalBrowser( bool valIn ) +{ + mOpenLinksInExternalBrowser = valIn; +}; + +//////////////////////////////////////////////////////////////////////////////// +// set flag that forces the embedded browser to open links in the internal browser floater +void LLMediaCtrl::setOpenInInternalBrowser( bool valIn ) +{ + mOpenLinksInInternalBrowser = valIn; +}; + +//////////////////////////////////////////////////////////////////////////////// +void LLMediaCtrl::setTrusted( bool valIn ) +{ + mTrusted = valIn; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask ) +{ + convertInputCoords(x, y); + + if (mMediaSource) + mMediaSource->mouseMove(x, y); + + gViewerWindow->setCursor(mLastSetCursor); + + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) +{ + if (mMediaSource && mMediaSource->hasMedia()) + mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, MASK_NONE); + + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) +{ + convertInputCoords(x, y); + + if (mMediaSource) + { + mMediaSource->mouseUp(x, y); + + // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, + // in addition to the onFocusReceived() call below. Undo this. JC + if (!mTakeFocusOnClick) + { + mMediaSource->focus(false); + gViewerWindow->focusClient(); + } + } + + gFocusMgr.setMouseCapture( NULL ); + + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) +{ + convertInputCoords(x, y); + + if (mMediaSource) + mMediaSource->mouseDown(x, y); + + gFocusMgr.setMouseCapture( this ); + + if (mTakeFocusOnClick) + { + setFocus( TRUE ); + } + + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) +{ + convertInputCoords(x, y); + + if (mMediaSource) + mMediaSource->mouseLeftDoubleClick( x, y ); + + gFocusMgr.setMouseCapture( this ); + + if (mTakeFocusOnClick) + { + setFocus( TRUE ); + } + + return TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::onFocusReceived() +{ + if (mMediaSource) + { + mMediaSource->focus(true); + + // Set focus for edit menu items + LLEditMenuHandler::gEditMenuHandler = mMediaSource; + } + + LLUICtrl::onFocusReceived(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::onFocusLost() +{ + if (mMediaSource) + { + mMediaSource->focus(false); + + if( LLEditMenuHandler::gEditMenuHandler == mMediaSource ) + { + // Clear focus for edit menu items + LLEditMenuHandler::gEditMenuHandler = NULL; + } + } + + gViewerWindow->focusClient(); + + LLUICtrl::onFocusLost(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask ) +{ + BOOL result = FALSE; + + // FIXME: THIS IS SO WRONG. + // Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it... + + if (mMediaSource) + { + if( MASK_CONTROL & mask ) + { + if( 'C' == key ) + { + mMediaSource->copy(); + result = TRUE; + } + else + if( 'V' == key ) + { + mMediaSource->paste(); + result = TRUE; + } + else + if( 'X' == key ) + { + mMediaSource->cut(); + result = TRUE; + } + } + + if(!result) + { + result = mMediaSource->handleKeyHere(key, mask); + } + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility ) +{ + llinfos << "visibility changed to " << (new_visibility?"true":"false") << llendl; + if(mMediaSource) + { + mMediaSource->setVisible( new_visibility ); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char) +{ + BOOL result = FALSE; + + // only accept 'printable' characters, sigh... + if (uni_char >= 32 // discard 'control' characters + && uni_char != 127) // SDL thinks this is 'delete' - yuck. + { + if (mMediaSource) + result = mMediaSource->handleUnicodeCharHere(uni_char); + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::onVisibilityChange ( BOOL new_visibility ) +{ + // set state of frequent updates automatically if visibility changes + if ( new_visibility ) + { + mFrequentUpdates = true; + } + else + { + mFrequentUpdates = false; + } + LLUICtrl::onVisibilityChange(new_visibility); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) +{ + S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width; + S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height; + +// llinfos << "reshape called with width = " << width << ", height = " << height << llendl; + + // when floater is minimized, these sizes are negative + if ( mWebBrowserImage && screen_height > 0 && screen_width > 0 ) + { + mWebBrowserImage->resize( screen_width, screen_height ); + mForceUpdate = true; + } + + LLUICtrl::reshape( width, height, called_from_parent ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::navigateBack() +{ + if (mMediaSource && mMediaSource->hasMedia()) + { + mMediaSource->getMediaPlugin()->browse_back(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::navigateForward() +{ + if (mMediaSource && mMediaSource->hasMedia()) + { + mMediaSource->getMediaPlugin()->browse_forward(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaCtrl::canNavigateBack() +{ + if (mMediaSource) + return mMediaSource->canNavigateBack(); + else + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaCtrl::canNavigateForward() +{ + if (mMediaSource) + return mMediaSource->canNavigateForward(); + else + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::set404RedirectUrl( std::string redirect_url ) +{ + if(mMediaSource && mMediaSource->hasMedia()) + mMediaSource->getMediaPlugin()->set_status_redirect( 404, redirect_url ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::clr404RedirectUrl() +{ + if(mMediaSource && mMediaSource->hasMedia()) + mMediaSource->getMediaPlugin()->set_status_redirect(404, ""); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type) +{ + // don't browse to anything that starts with secondlife:// or sl:// + const std::string protocol1 = "secondlife://"; + const std::string protocol2 = "sl://"; + if ((LLStringUtil::compareInsensitive(url_in.substr(0, protocol1.length()), protocol1) == 0) || + (LLStringUtil::compareInsensitive(url_in.substr(0, protocol2.length()), protocol2) == 0)) + { + // TODO: Print out/log this attempt? + // llinfos << "Rejecting attempt to load restricted website :" << urlIn << llendl; + return; + } + + if (mMediaSource) + { + mCurrentNavUrl = url_in; + mMediaSource->navigateTo(url_in, mime_type, mime_type.empty()); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in ) +{ + std::string language = LLUI::getLanguage(); + std::string delim = gDirUtilp->getDirDelimiter(); + std::string filename; + + filename += subdir; + filename += delim; + filename += filename_in; + + std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename); + + if (! gDirUtilp->fileExists(expanded_filename)) + { + if (language != "en-us") + { + expanded_filename = gDirUtilp->findSkinnedFilename("html", "en-us", filename); + if (! gDirUtilp->fileExists(expanded_filename)) + { + llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; + return; + } + } + else + { + llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; + return; + } + } + if (mMediaSource) + { + mCurrentNavUrl = expanded_filename; + mMediaSource->navigateTo(expanded_filename, "text/html", false); + } + +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::navigateHome() +{ + if( mHomePageUrl.length() ) + { + if (mMediaSource) + mMediaSource->navigateTo(mHomePageUrl); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::setHomePageUrl( const std::string urlIn ) +{ + mHomePageUrl = urlIn; +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue) +{ + //NOOP + return false; +} +//////////////////////////////////////////////////////////////////////////////// +// +std::string LLMediaCtrl::getHomePageUrl() +{ + return mHomePageUrl; +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLPluginClassMedia* LLMediaCtrl::getMediaPlugin() +{ + return mMediaSource.isNull() ? NULL : mMediaSource->getMediaPlugin(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::draw() +{ + if ( ! mWebBrowserImage ) + return; + + if ( gRestoreGL == 1 ) + { + LLRect r = getRect(); + reshape( r.getWidth(), r.getHeight(), FALSE ); + return; + }; + + // NOTE: optimization needed here - probably only need to do this once + // unless tearoffs change the parent which they probably do. + const LLUICtrl* ptr = findRootMostFocusRoot(); + if ( ptr && ptr->hasFocus() ) + { + setFrequentUpdates( true ); + } + else + { + setFrequentUpdates( false ); + }; + + // alpha off for this + LLGLSUIDefault gls_ui; + LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); + + gGL.pushMatrix(); + { + if (mIgnoreUIScale) + { + glLoadIdentity(); + // font system stores true screen origin, need to scale this by UI scale factor + // to get render origin for this view (with unit scale) + gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]), + floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]), + LLFontGL::sCurOrigin.mZ); + } + + // scale texture to fit the space using texture coords + gGL.getTexUnit(0)->bind(mWebBrowserImage->getTexture()); + gGL.color4fv( LLColor4::white.mV ); + F32 max_u = ( F32 )mWebBrowserImage->getMediaWidth() / ( F32 )mWebBrowserImage->getWidth(); + F32 max_v = ( F32 )mWebBrowserImage->getMediaHeight() / ( F32 )mWebBrowserImage->getHeight(); + + LLRect r = getRect(); + S32 width, height; + S32 x_offset = 0; + S32 y_offset = 0; + + if(mStretchToFill) + { + if(mMaintainAspectRatio) + { + F32 media_aspect = (F32)(mWebBrowserImage->getMediaWidth()) / (F32)(mWebBrowserImage->getMediaHeight()); + F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight()); + if(media_aspect > view_aspect) + { + // max width, adjusted height + width = r.getWidth(); + height = llmin(llmax(S32(width / media_aspect), 0), r.getHeight()); + } + else + { + // max height, adjusted width + height = r.getHeight(); + width = llmin(llmax(S32(height * media_aspect), 0), r.getWidth()); + } + } + else + { + width = r.getWidth(); + height = r.getHeight(); + } + } + else + { + width = llmin(mWebBrowserImage->getMediaWidth(), r.getWidth()); + height = llmin(mWebBrowserImage->getMediaHeight(), r.getHeight()); + } + + x_offset = (r.getWidth() - width) / 2; + y_offset = (r.getHeight() - height) / 2; + + if (mIgnoreUIScale) + { + width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]); + height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]); + x_offset = llround((F32)x_offset * LLUI::sGLScaleFactor.mV[VX]); + y_offset = llround((F32)y_offset * LLUI::sGLScaleFactor.mV[VY]); + } + + // draw the browser + gGL.setSceneBlendType(LLRender::BT_REPLACE); + gGL.begin( LLRender::QUADS ); + if (! mWebBrowserImage->getTextureCoordsOpenGL()) + { + // render using web browser reported width and height, instead of trying to invert GL scale + gGL.texCoord2f( max_u, 0.f ); + gGL.vertex2i( x_offset + width, y_offset + height ); + + gGL.texCoord2f( 0.f, 0.f ); + gGL.vertex2i( x_offset, y_offset + height ); + + gGL.texCoord2f( 0.f, max_v ); + gGL.vertex2i( x_offset, y_offset ); + + gGL.texCoord2f( max_u, max_v ); + gGL.vertex2i( x_offset + width, y_offset ); + } + else + { + // render using web browser reported width and height, instead of trying to invert GL scale + gGL.texCoord2f( max_u, max_v ); + gGL.vertex2i( x_offset + width, y_offset + height ); + + gGL.texCoord2f( 0.f, max_v ); + gGL.vertex2i( x_offset, y_offset + height ); + + gGL.texCoord2f( 0.f, 0.f ); + gGL.vertex2i( x_offset, y_offset ); + + gGL.texCoord2f( max_u, 0.f ); + gGL.vertex2i( x_offset + width, y_offset ); + } + gGL.end(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + gGL.popMatrix(); + + // highlight if keyboard focus here. (TODO: this needs some work) + if ( mBorder->getVisible() ) + mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); + + + LLUICtrl::draw(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::convertInputCoords(S32& x, S32& y) +{ + x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x; + if ( ! mWebBrowserImage->getTextureCoordsOpenGL() ) + { + y = mIgnoreUIScale ? llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]) : y; + } + else + { + y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight() - y; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// static +bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response ) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if ( 0 == option ) + { + // open in external browser because we don't support + // creation of our own secondary browser windows + LLWeb::loadURLExternal( notification["payload"]["external_url"].asString() ); + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// inherited from LLViewerMediaObserver +//virtual +void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + switch(event) + { + case MEDIA_EVENT_CONTENT_UPDATED: + { + // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL; + }; + break; + + case MEDIA_EVENT_TIME_DURATION_UPDATED: + { + // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_SIZE_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL; + LLRect r = getRect(); + reshape( r.getWidth(), r.getHeight(), FALSE ); + }; + break; + + case MEDIA_EVENT_CURSOR_CHANGED: + { + LL_INFOS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL; + + std::string cursor = self->getCursorName(); + + if(cursor == "arrow") + mLastSetCursor = UI_CURSOR_ARROW; + else if(cursor == "ibeam") + mLastSetCursor = UI_CURSOR_IBEAM; + else if(cursor == "splith") + mLastSetCursor = UI_CURSOR_SIZEWE; + else if(cursor == "splitv") + mLastSetCursor = UI_CURSOR_SIZENS; + else if(cursor == "hand") + mLastSetCursor = UI_CURSOR_HAND; + else // for anything else, default to the arrow + mLastSetCursor = UI_CURSOR_ARROW; + }; + break; + + case MEDIA_EVENT_NAVIGATE_BEGIN: + { + LL_INFOS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL; + if(mMediaSource && mHideLoading) + { + mMediaSource->suspendUpdates(true); + } + }; + break; + + case MEDIA_EVENT_NAVIGATE_COMPLETE: + { + LL_INFOS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; + if(mMediaSource && mHideLoading) + { + mMediaSource->suspendUpdates(false); + } + }; + break; + + case MEDIA_EVENT_PROGRESS_UPDATED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL; + }; + break; + + case MEDIA_EVENT_STATUS_TEXT_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_LOCATION_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_CLICK_LINK_HREF: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; + onClickLinkHref(self); + }; + break; + + case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; + onClickLinkNoFollow(self); + }; + break; + + case MEDIA_EVENT_PLUGIN_FAILED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; + }; + break; + + case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; + }; + break; + + case MEDIA_EVENT_NAME_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; + }; + break; + }; + + // chain all events to any potential observers of this object. + emitEvent(self, event); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self ) +{ + // retrieve the event parameters + std::string target = self->getClickTarget(); + std::string url = self->getClickURL(); + + // if there is a value for the target + if ( !target.empty() ) + { + if ( target == "_external" ) + { + mExternalUrl = url; + LLSD payload; + payload["external_url"] = mExternalUrl; + LLNotifications::instance().add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); + return; + } + } + + const std::string protocol1( "http://" ); + const std::string protocol2( "https://" ); + if( mOpenLinksInExternalBrowser ) + { + if ( !url.empty() ) + { + if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 || + LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 ) + { + LLWeb::loadURLExternal( url ); + } + } + } + else + if( mOpenLinksInInternalBrowser ) + { + if ( !url.empty() ) + { + if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 || + LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 ) + { + // If we spawn a new LLFloaterHTML, assume we want it to + // follow this LLMediaCtrl's trust for whether or + // not to open secondlife:///app/ links. JC. +// const bool open_links_externally = false; +// LLFloaterHtml::getInstance()->show( +// event_in.mStringPayload, +// "Second Life Browser", +// open_links_externally, +// mTrusted); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self ) +{ + std::string url = self->getClickURL(); + if (LLURLDispatcher::isSLURLCommand(url) + && !mTrusted) + { + // block handling of this secondlife:///app/ URL + LLNotifications::instance().add("UnableToOpenCommandURL"); + return; + } + + LLURLDispatcher::dispatch(url, this, mTrusted); +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLMediaCtrl* browserCtrl, viewer_media_t media_source ) : + LLDynamicTexture( 512, 512, 4, ORDER_FIRST, TRUE ), + mNeedsUpdate( true ), + mNeedsResize( false ), + mTextureCoordsOpenGL( true ), + mWebBrowserCtrl( browserCtrl ), + mMediaSource(media_source) +{ + mElapsedTime.start(); + + resize( width, height ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLWebBrowserTexture::~LLWebBrowserTexture() +{ + mElapsedTime.stop(); + mMediaSource = NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLWebBrowserTexture::needsRender() +{ + bool texture_dirty = false; + + if ( mWebBrowserCtrl->getFrequentUpdates() || + mWebBrowserCtrl->getAlwaysRefresh() || + mWebBrowserCtrl->getForceUpdate() ) + { + // All of these force an update + return TRUE; + } + + // If the texture needs updating, render needs to be called. + if (mMediaSource && mMediaSource->hasMedia()) + { + LLPluginClassMedia* media = mMediaSource->getMediaPlugin(); + + if(media->textureValid() && media->getDirty()) + { + texture_dirty = true; + } + } + + + return texture_dirty; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLWebBrowserTexture::render() +{ + if(updateBrowserTexture()) + { + // updateBrowserTexture already verified that the media plugin is there and the texture is valid. + LLPluginClassMedia* media_plugin = mMediaSource->getMediaPlugin(); + LLRect dirty_rect; + + if(mNeedsUpdate) + { + // If we need an update, use the whole rect instead of the dirty rect. + dirty_rect.mLeft = 0; + dirty_rect.mBottom = 0; + dirty_rect.mRight = media_plugin->getWidth(); + dirty_rect.mTop = media_plugin->getHeight(); + } + else + { + mNeedsUpdate = media_plugin->getDirty(&dirty_rect); + } + + if ( mNeedsUpdate ) + { + mNeedsUpdate = false; + mWebBrowserCtrl->setForceUpdate(false); + + // Constrain the dirty rect to be inside the texture + S32 x_pos = llmax(dirty_rect.mLeft, 0); + S32 y_pos = llmax(dirty_rect.mBottom, 0); + S32 width = llmin(dirty_rect.mRight, getWidth()) - x_pos; + S32 height = llmin(dirty_rect.mTop, getHeight()) - y_pos; + + if(width > 0 && height > 0) + { + U8* data = media_plugin->getBitsData(); + + // Offset the pixels pointer to match x_pos and y_pos + data += ( x_pos * media_plugin->getTextureDepth() * media_plugin->getBitsWidth() ); + data += ( y_pos * media_plugin->getTextureDepth() ); + + mTexture->setSubImage( + data, + media_plugin->getBitsWidth(), + media_plugin->getBitsHeight(), + x_pos, + y_pos, + width, + height, + TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) + } + + media_plugin->resetDirty(); + + return TRUE; + }; + }; + + return FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// +// +S32 LLWebBrowserTexture::getMediaWidth() +{ + return mMediaWidth; +} + +//////////////////////////////////////////////////////////////////////////////// +// +S32 LLWebBrowserTexture::getMediaHeight() +{ + return mMediaHeight; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLWebBrowserTexture::setNeedsUpdate() +{ + mNeedsUpdate = true; +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLWebBrowserTexture::getNeedsUpdate() +{ + return mNeedsUpdate; +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLWebBrowserTexture::getTextureCoordsOpenGL() +{ + return mTextureCoordsOpenGL; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) +{ + F32 scale_ratio = 1.f; + if (new_width > MAX_DIMENSION) + { + scale_ratio = (F32)MAX_DIMENSION / (F32)new_width; + } + if (new_height > MAX_DIMENSION) + { + scale_ratio = llmin(scale_ratio, (F32)MAX_DIMENSION / (F32)new_height); + } + + mMediaWidth = llround(scale_ratio * (F32)new_width); + mMediaHeight = llround(scale_ratio * (F32)new_height); + + adjustSize(); +} + +bool LLWebBrowserTexture::adjustSize() +{ + if (mMediaSource && mMediaSource->hasMedia()) + { + int natural_width = mMediaSource->getMediaPlugin()->getNaturalWidth(); + int natural_height = mMediaSource->getMediaPlugin()->getNaturalHeight(); + + if(natural_width != 0) + { + // If the media has a "natural size", use it. + mMediaWidth = natural_width; + mMediaHeight = natural_height; + } + + mMediaSource->setSize(mMediaWidth, mMediaHeight); + mNeedsResize = false; + + return true; + } + else + { + // The media isn't fully initialized yet, delay the resize until later. + mNeedsResize = true; + } + + return false; +} + +bool LLWebBrowserTexture::updateBrowserTexture() +{ + if (!adjustSize()) + return false; + + LLPluginClassMedia* media = mMediaSource->getMediaPlugin(); + + if(!media->textureValid()) + return false; + + if(mMediaSource->mNeedsNewTexture + || media->getTextureWidth() != mWidth + || media->getTextureHeight() != mHeight ) + { + releaseGLTexture(); + + mWidth = media->getTextureWidth(); + mHeight = media->getTextureHeight(); + mTextureCoordsOpenGL = media->getTextureCoordsOpenGL(); + + // will create mWidth * mHeight sized texture, using the texture params specified by the media. + LLDynamicTexture::generateGLTexture( + media->getTextureFormatInternal(), + media->getTextureFormatPrimary(), + media->getTextureFormatType(), + media->getTextureFormatSwapBytes()); + + + mMediaSource->mNeedsNewTexture = false; + } + + return true; +} +// virtual +LLXMLNodePtr LLMediaCtrl::getXML(bool save_children) const +{ + LLXMLNodePtr node = LLUICtrl::getXML(); + + node->setName(LL_WEB_BROWSER_CTRL_TAG); + + return node; +} + +LLView* LLMediaCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +{ + std::string name("web_browser"); + node->getAttributeString("name", name); + + std::string start_url(""); + node->getAttributeString("start_url", start_url ); + + BOOL border_visible = true; + node->getAttributeBOOL("border_visible", border_visible); + + LLRect rect; + createRect(node, rect, parent, LLRect()); + + LLMediaCtrl* web_browser = new LLMediaCtrl( name, rect ); + + if(node->hasAttribute("caret_color")) + { + LLColor4 color; + LLUICtrlFactory::getAttributeColor(node, "caret_color", color); + LLColor4U colorU = LLColor4U(color); + web_browser->setCaretColor( colorU.mV[0], colorU.mV[1], colorU.mV[2] ); + } + + BOOL ignore_ui_scale = web_browser->getIgnoreUIScale(); + node->getAttributeBOOL("ignore_ui_scale", ignore_ui_scale); + web_browser->setIgnoreUIScale((bool)ignore_ui_scale); + + web_browser->initFromXML(node, parent); + + web_browser->setHomePageUrl( start_url ); + + web_browser->setBorderVisible( border_visible ); + + if(! start_url.empty()) + { + web_browser->navigateHome(); + } + + return web_browser; +} + +std::string LLMediaCtrl::getCurrentNavUrl() +{ + return mCurrentNavUrl; +} + diff --git a/linden/indra/newview/llmediactrl.h b/linden/indra/newview/llmediactrl.h new file mode 100644 index 000000000..77f59c7e7 --- /dev/null +++ b/linden/indra/newview/llmediactrl.h @@ -0,0 +1,201 @@ +/** + * @file llmediactrl.h + * @brief Web browser UI control + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLMediaCtrl_H +#define LL_LLMediaCtrl_H + +#include "llviewermedia.h" + +#include "lluictrl.h" +#include "llframetimer.h" +#include "lldynamictexture.h" + +class LLViewBorder; +class LLWebBrowserTexture; +class LLUICtrlFactory; + +//////////////////////////////////////////////////////////////////////////////// +// +class LLMediaCtrl : + public LLUICtrl, + public LLViewerMediaObserver, + public LLViewerMediaEventEmitter +{ + public: + LLMediaCtrl( const std::string& name, const LLRect& rect ); + virtual ~LLMediaCtrl(); + + void setBorderVisible( BOOL border_visible ); + + // For the tutorial window, we don't want to take focus on clicks, + // as the examples include how to move around with the arrow + // keys. Thus we keep focus on the app by setting this false. + // Defaults to true. + void setTakeFocusOnClick( bool take_focus ); + + virtual LLXMLNodePtr getXML(bool save_children = true) const; + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + + // handle mouse related methods + virtual BOOL handleHover( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); + virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); + virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); + + // navigation + void navigateTo( std::string url_in, std::string mime_type = ""); + void navigateBack(); + void navigateHome(); + void navigateForward(); + void navigateToLocalPage( const std::string& subdir, const std::string& filename_in ); + bool canNavigateBack(); + bool canNavigateForward(); + void setOpenInExternalBrowser( bool valIn ); + void setOpenInInternalBrowser( bool valIn ); + std::string getCurrentNavUrl(); + + // By default, we do not handle "secondlife:///app/" SLURLs, because + // those can cause teleports, open windows, etc. We cannot be sure + // that each "click" is actually due to a user action, versus + // Javascript or some other mechanism. However, we need the search + // floater and login page to handle these URLs. Those are safe + // because we control the page content. See DEV-9530. JC. + void setTrusted( bool valIn ); + + void setHomePageUrl( const std::string urlIn ); + std::string getHomePageUrl(); + + // set/clear URL to visit when a 404 page is reached + void set404RedirectUrl( std::string redirect_url ); + void clr404RedirectUrl(); + + // accessor/mutator for flag that indicates if frequent updates to texture happen + bool getFrequentUpdates() { return mFrequentUpdates; }; + void setFrequentUpdates( bool frequentUpdatesIn ) { mFrequentUpdates = frequentUpdatesIn; }; + + void setIgnoreUIScale(bool ignore) { mIgnoreUIScale = ignore; } + bool getIgnoreUIScale() { return mIgnoreUIScale; } + + void setAlwaysRefresh(bool refresh) { mAlwaysRefresh = refresh; } + bool getAlwaysRefresh() { return mAlwaysRefresh; } + + void setForceUpdate(bool force_update) { mForceUpdate = force_update; } + bool getForceUpdate() { return mForceUpdate; } + + LLPluginClassMedia* getMediaPlugin(); + + bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ); + + + // over-rides + virtual BOOL handleKeyHere( KEY key, MASK mask); + virtual void handleVisibilityChange ( BOOL new_visibility ); + virtual BOOL handleUnicodeCharHere(llwchar uni_char); + virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE); + virtual void draw(); + virtual void onVisibilityChange ( BOOL curVisibilityIn ); + + // focus overrides + void onFocusLost(); + void onFocusReceived(); + + // Incoming media event dispatcher + virtual void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); + + // handlers for individual events (could be done inside the switch in handleMediaEvent, they're just individual functions for clarity) + void onClickLinkHref( LLPluginClassMedia* self ); + void onClickLinkNoFollow( LLPluginClassMedia* self ); + + protected: + void convertInputCoords(S32& x, S32& y); + + private: + static bool onClickLinkExternalTarget( const LLSD&, const LLSD& ); + + const S32 mTextureDepthBytes; + LLWebBrowserTexture* mWebBrowserImage; + LLViewBorder* mBorder; + bool mFrequentUpdates; + bool mForceUpdate; + bool mOpenLinksInExternalBrowser; + bool mOpenLinksInInternalBrowser; + bool mTrusted; + std::string mHomePageUrl; + std::string mExternalUrl; + std::string mCurrentNavUrl; + bool mIgnoreUIScale; + bool mAlwaysRefresh; + viewer_media_t mMediaSource; + bool mTakeFocusOnClick; + ECursorType mLastSetCursor; + bool mStretchToFill; + bool mMaintainAspectRatio; + bool mHideLoading; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +class LLWebBrowserTexture : public LLDynamicTexture +{ +LOG_CLASS(LLWebBrowserTexture); + public: + LLWebBrowserTexture( S32 width, S32 height, LLMediaCtrl* browserCtrl, viewer_media_t media_source ); + virtual ~LLWebBrowserTexture(); + + virtual BOOL needsRender(); + virtual void preRender( BOOL clear_depth = TRUE ) {}; + virtual void postRender( BOOL success ) {}; + virtual BOOL render(); + + bool adjustSize(); + S32 getMediaWidth(); + S32 getMediaHeight(); + bool getNeedsUpdate(); + void setNeedsUpdate(); + bool getTextureCoordsOpenGL(); + + void resize( S32 new_width, S32 new_height ); + bool updateBrowserTexture(); + + protected: + S32 mMediaWidth; + S32 mMediaHeight; + bool mNeedsUpdate; + bool mNeedsResize; + bool mTextureCoordsOpenGL; + LLFrameTimer mElapsedTime; + LLMediaCtrl* mWebBrowserCtrl; + viewer_media_t mMediaSource; +}; + +#endif // LL_LLMediaCtrl_H diff --git a/linden/indra/newview/llmediaremotectrl.cpp b/linden/indra/newview/llmediaremotectrl.cpp index f2ec414ac..a62973a83 100644 --- a/linden/indra/newview/llmediaremotectrl.cpp +++ b/linden/indra/newview/llmediaremotectrl.cpp @@ -34,7 +34,7 @@ #include "llmediaremotectrl.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "lliconctrl.h" #include "llmimetypes.h" #include "lloverlaybar.h" @@ -86,6 +86,7 @@ BOOL LLMediaRemoteCtrl::postBuild() childSetAction("media_stop",LLOverlayBar::mediaStop,this); childSetAction("music_stop",LLOverlayBar::toggleMusicPlay,this); childSetAction("media_pause",LLOverlayBar::toggleMediaPlay,this); + childSetAction("music_pause",LLOverlayBar::toggleMusicPlay,this); childSetAction("expand", onClickExpandBtn, this); return TRUE; @@ -135,9 +136,11 @@ void* LLMediaRemoteCtrl::createVolumePanel(void* data) // Virtual void LLMediaRemoteCtrl::setToolTip(const std::string& msg) { - std::string mime_type = LLMIMETypes::translate(LLViewerMedia::getMimeType()); - std::string tool_tip = LLMIMETypes::findToolTip(LLViewerMedia::getMimeType()); - std::string play_tip = LLMIMETypes::findPlayTip(LLViewerMedia::getMimeType()); + // TODO: this gets removed for Media on a Prim + + const std::string mime_type = LLViewerParcelMedia::getMimeType(); + std::string tool_tip = LLMIMETypes::findToolTip(mime_type); + std::string play_tip = LLMIMETypes::findPlayTip(mime_type); // childSetToolTip("media_stop", mControls->getString("stop_label") + "\n" + tool_tip); childSetToolTip("media_icon", tool_tip); childSetToolTip("media_play", play_tip); @@ -150,6 +153,7 @@ void LLMediaRemoteCtrl::enableMediaButtons() bool stop_media_enabled = false; bool play_music_enabled = false; bool stop_music_enabled = false; + bool music_show_pause = false; bool media_show_pause = false; LLColor4 music_icon_color = LLUI::sColorsGroup->getColor( "IconDisabledColor" ); LLColor4 media_icon_color = LLUI::sColorsGroup->getColor( "IconDisabledColor" ); @@ -161,7 +165,7 @@ void LLMediaRemoteCtrl::enableMediaButtons() if (gSavedSettings.getBOOL("AudioStreamingVideo")) { - if ( parcel && parcel->getMediaURL()[0]) + if ( parcel && !parcel->getMediaURL().empty()) { // Set the tooltip // Put this text into xui file @@ -171,23 +175,22 @@ void LLMediaRemoteCtrl::enableMediaButtons() play_media_enabled = true; media_icon_color = LLUI::sColorsGroup->getColor( "IconEnabledColor" ); - LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getStatus(); switch(status) { - case LLMediaBase::STATUS_STOPPED: - case LLMediaBase::STATUS_UNKNOWN: + case LLViewerMediaImpl::MEDIA_NONE: media_show_pause = false; stop_media_enabled = false; break; - case LLMediaBase::STATUS_STARTED: - case LLMediaBase::STATUS_NAVIGATING: - case LLMediaBase::STATUS_RESETTING: + case LLViewerMediaImpl::MEDIA_LOADING: + case LLViewerMediaImpl::MEDIA_LOADED: + case LLViewerMediaImpl::MEDIA_PLAYING: // HACK: only show the pause button for movie types media_show_pause = LLMIMETypes::widgetType(parcel->getMediaType()) == "movie" ? true : false; stop_media_enabled = true; play_media_enabled = false; break; - case LLMediaBase::STATUS_PAUSED: + case LLViewerMediaImpl::MEDIA_PAUSED: media_show_pause = false; stop_media_enabled = true; break; @@ -197,46 +200,42 @@ void LLMediaRemoteCtrl::enableMediaButtons() } } } + if (gSavedSettings.getBOOL("AudioStreamingMusic") && gAudiop) { - - if ( parcel && parcel->getMusicURL()[0]) + if ( parcel && !parcel->getMusicURL().empty()) { + play_music_enabled = true; music_icon_color = LLUI::sColorsGroup->getColor( "IconEnabledColor" ); if (gOverlayBar->musicPlaying()) { - play_music_enabled = false; + music_show_pause = true; stop_music_enabled = true; } else { - play_music_enabled = true; + music_show_pause = false; stop_music_enabled = false; } } - // if no mime type has been set disable play - if( LLViewerMedia::getMimeType().empty() - || LLViewerMedia::getMimeType() == "none/none") - { - play_media_enabled = false; - stop_media_enabled = false; - } + // Don't test the mime-type: this is not updated in a consistent basis. The existence of a valid gAudiop is enough guarantee. } const std::string media_icon_name = LLMIMETypes::findIcon(media_type); - LLButton* music_play_btn = getChild<LLButton>("music_play"); LLButton* music_stop_btn = getChild<LLButton>("music_stop"); - - music_play_btn->setEnabled(play_music_enabled); - music_stop_btn->setEnabled(stop_music_enabled); - childSetColor("music_icon", music_icon_color); - + LLButton* music_pause_btn = getChild<LLButton>("music_pause"); LLButton* media_play_btn = getChild<LLButton>("media_play"); LLButton* media_stop_btn = getChild<LLButton>("media_stop"); LLButton* media_pause_btn = getChild<LLButton>("media_pause"); LLIconCtrl* media_icon = getChild<LLIconCtrl>("media_icon"); + music_play_btn->setEnabled(play_music_enabled); + music_stop_btn->setEnabled(stop_music_enabled); + music_pause_btn->setEnabled(music_show_pause); + music_pause_btn->setVisible(music_show_pause); + music_play_btn->setVisible(! music_show_pause); + childSetColor("music_icon", music_icon_color); if(!media_icon_name.empty()) { media_icon->setImage(media_icon_name); diff --git a/linden/indra/newview/llmimetypes.cpp b/linden/indra/newview/llmimetypes.cpp index bfbc81aa6..525e89cdf 100644 --- a/linden/indra/newview/llmimetypes.cpp +++ b/linden/indra/newview/llmimetypes.cpp @@ -46,6 +46,8 @@ std::string sDefaultWidgetType; // Returned when we don't know what widget set to use std::string sDefaultImpl; // Returned when we don't know what impl to use +std::string sXMLFilename; + // Squirrel away XML filename so we know how to reset ///////////////////////////////////////////////////////////////////////////// @@ -146,6 +148,8 @@ bool LLMIMETypes::parseMIMETypes(const std::string& xml_filename) sWidgetMap[set_name] = info; } } + + sXMLFilename = xml_filename; return true; } @@ -267,3 +271,23 @@ bool LLMIMETypes::findAllowLooping(const std::string& mime_type) } return allow_looping; } + +// static +bool LLMIMETypes::isTypeHandled(const std::string& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return true; + } + return false; +} + +// static +void LLMIMETypes::reload(void*) +{ + sMap.clear(); + sWidgetMap.clear(); + (void)LLMIMETypes::parseMIMETypes(sXMLFilename); +} + diff --git a/linden/indra/newview/llmimetypes.h b/linden/indra/newview/llmimetypes.h index 7a50c2942..b217ce7a8 100644 --- a/linden/indra/newview/llmimetypes.h +++ b/linden/indra/newview/llmimetypes.h @@ -72,6 +72,12 @@ class LLMIMETypes static bool findAllowLooping(const std::string& mime_type); // accessor for flag to enable/disable media looping checkbox + static bool isTypeHandled(const std::string& mime_type); + // determines if the specific mime type is handled by the media system + + static void reload(void*); + // re-loads the MIME types file from the file path last passed into parseMIMETypes + public: struct LLMIMEInfo { diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index 6191a0134..db4422d66 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp @@ -38,7 +38,7 @@ #include "lloverlaybar.h" #include "aoremotectrl.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "llrender.h" #include "llagent.h" #include "llbutton.h" @@ -63,7 +63,7 @@ #include "llvoiceclient.h" #include "llvoavatar.h" #include "llvoiceremotectrl.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" #include "llwindlightremotectrl.h" #include "llselectmgr.h" @@ -75,13 +75,14 @@ LLOverlayBar *gOverlayBar = NULL; extern S32 MENU_BAR_HEIGHT; - +//awfixme +/* class LLTitleObserver : public LLMediaObserver { public: void init(std::string url); - /*virtual*/ void onMediaTitleChange(const EventType& event_in); + *//*virtual*//* void onMediaTitleChange(const EventType& event_in); private: LLMediaBase* mMediaSource; }; @@ -120,7 +121,7 @@ void LLTitleObserver::onMediaTitleChange(const EventType& event_in) chat.mText = playing_msg; LLFloaterChat::addChat(chat, FALSE, FALSE); } - +*/ // // Functions @@ -445,11 +446,11 @@ void LLOverlayBar::toggleMediaPlay(void*) } - if (LLViewerMedia::isMediaPaused()) + if (LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PAUSED) { LLViewerParcelMedia::start(); } - else if(LLViewerMedia::isMediaPlaying()) + else if(LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PLAYING) { LLViewerParcelMedia::pause(); } @@ -490,7 +491,7 @@ void LLOverlayBar::toggleMusicPlay(void*) // if ( gAudiop->isInternetStreamPlaying() == 0 ) { gAudiop->startInternetStream(parcel->getMusicURL()); - sTitleObserver.init(parcel->getMusicURL()); +//awfixme sTitleObserver.init(parcel->getMusicURL()); } } } diff --git a/linden/indra/newview/llpanelaudioprefs.cpp b/linden/indra/newview/llpanelaudioprefs.cpp index 2bb3ab406..d4c8e9fc0 100644 --- a/linden/indra/newview/llpanelaudioprefs.cpp +++ b/linden/indra/newview/llpanelaudioprefs.cpp @@ -42,7 +42,7 @@ #include "llfontgl.h" // project includes -#include "audioengine.h" +#include "llaudioengine.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" @@ -105,7 +105,6 @@ void LLPanelAudioPrefs::refreshValues() mPreviousMusicVolume = gSavedSettings.getF32("AudioLevelMusic"); mPreviousMediaVolume = gSavedSettings.getF32("AudioLevelMedia"); mPreviousDoppler = gSavedSettings.getF32("AudioLevelDoppler"); - mPreviousDistance = gSavedSettings.getF32("AudioLevelDistance"); mPreviousRolloff = gSavedSettings.getF32("AudioLevelRolloff"); mPreviousMoneyThreshold = gSavedSettings.getF32("UISndMoneyChangeThreshold"); @@ -134,7 +133,6 @@ void LLPanelAudioPrefs::cancel() gSavedSettings.setF32("AudioLevelMusic", mPreviousMusicVolume); gSavedSettings.setF32("AudioLevelMedia", mPreviousMediaVolume); gSavedSettings.setF32("AudioLevelDoppler", mPreviousDoppler ); - gSavedSettings.setF32("AudioLevelDistance", mPreviousDistance ); gSavedSettings.setF32("AudioLevelRolloff", mPreviousRolloff ); gSavedSettings.setF32("UISndMoneyChangeThreshold", mPreviousMoneyThreshold ); diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp index 33f4cd6c9..288dbcddf 100644 --- a/linden/indra/newview/llpanelavatar.cpp +++ b/linden/indra/newview/llpanelavatar.cpp @@ -64,6 +64,7 @@ #include "llmutelist.h" #include "llpanelclassified.h" #include "llpanelpick.h" +#include "llpluginclassmedia.h" #include "llscrolllistctrl.h" #include "llstatusbar.h" #include "lltabcontainer.h" @@ -410,14 +411,12 @@ BOOL LLPanelAvatarWeb::postBuild(void) childSetControlName("auto_load","AutoLoadWebProfiles"); - mWebBrowser = getChild<LLWebBrowserCtrl>("profile_html"); + mWebBrowser = getChild<LLMediaCtrl>("profile_html"); + mWebBrowser->addObserver(this); // links open in internally mWebBrowser->setOpenInExternalBrowser( false ); - // observe browser events - mWebBrowser->addObserver( this ); - return TRUE; } @@ -476,18 +475,22 @@ LLPanelAvatarWeb::LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatarWeb::~LLPanelAvatarWeb() { - // stop observing browser events - if ( mWebBrowser ) +} + +void LLPanelAvatarWeb::refresh() +{ + if (mNavigateTo != "") { - mWebBrowser->remObserver( this ); - }; + llinfos << "Loading " << mNavigateTo << llendl; + mWebBrowser->navigateTo( mNavigateTo ); + mNavigateTo = ""; + } } + void LLPanelAvatarWeb::enableControls(BOOL self) { childSetEnabled("url_edit",self); - childSetVisible("status_text",!self && !mHome.empty()); - childSetText("status_text", LLStringUtil::null); } void LLPanelAvatarWeb::setWebURL(std::string url) @@ -511,11 +514,8 @@ void LLPanelAvatarWeb::setWebURL(std::string url) else { childSetVisible("profile_html",false); + childSetVisible("status_text", false); } - - BOOL own_avatar = (getPanelAvatar()->getAvatarID() == gAgent.getID() ); - childSetVisible("status_text",!own_avatar && !mHome.empty()); - } // static @@ -538,13 +538,15 @@ void LLPanelAvatarWeb::load(std::string url) { bool have_url = (!url.empty()); + + childSetVisible("profile_html", have_url); + childSetVisible("status_text", have_url); + childSetText("status_text", LLStringUtil::null); + if (have_url) { - llinfos << "Loading " << url << llendl; - mWebBrowser->navigateTo( url ); + mNavigateTo = url; } - - childSetVisible("profile_html", have_url); } //static @@ -586,14 +588,22 @@ void LLPanelAvatarWeb::onCommitLoad(LLUICtrl* ctrl, void* data) } } -void LLPanelAvatarWeb::onStatusTextChange( const EventType& eventIn ) -{ - childSetText("status_text", eventIn.getStringValue() ); -} - -void LLPanelAvatarWeb::onLocationChange( const EventType& eventIn ) +void LLPanelAvatarWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) { - childSetText("url_edit", eventIn.getStringValue() ); + switch(event) + { + case MEDIA_EVENT_STATUS_TEXT_CHANGED: + childSetText("status_text", self->getStatusText() ); + break; + + case MEDIA_EVENT_LOCATION_CHANGED: + childSetText("url_edit", self->getLocation() ); + break; + + default: + // Having a default case makes the compiler happy. + break; + } } diff --git a/linden/indra/newview/llpanelavatar.h b/linden/indra/newview/llpanelavatar.h index 72a47f579..b687cd8d3 100644 --- a/linden/indra/newview/llpanelavatar.h +++ b/linden/indra/newview/llpanelavatar.h @@ -36,7 +36,7 @@ #include "llpanel.h" #include "v3dmath.h" #include "lluuid.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" class LLButton; class LLCheckBoxCtrl; @@ -55,7 +55,7 @@ class LLViewerImage; class LLViewerObject; class LLMessageSystem; class LLIconCtrl; -class LLWebBrowserCtrl; +class LLMediaCtrl; enum EOnlineStatus { @@ -137,13 +137,15 @@ class LLPanelAvatarSecondLife // WARNING! The order of the inheritance here matters!! Do not change. - KLW class LLPanelAvatarWeb : public LLPanelAvatarTab - , public LLWebBrowserCtrlObserver + , public LLViewerMediaObserver { public: LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar); /*virtual*/ ~LLPanelAvatarWeb(); /*virtual*/ BOOL postBuild(void); + /*virtual*/ void refresh(); + void enableControls(BOOL own_avatar); void setWebURL(std::string url); @@ -154,13 +156,13 @@ class LLPanelAvatarWeb : static void onCommitURL(LLUICtrl* ctrl, void* data); static void onClickWebProfileHelp(void *); - // browser observer impls - virtual void onStatusTextChange( const EventType& eventIn ); - virtual void onLocationChange( const EventType& eventIn ); + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); private: std::string mHome; - LLWebBrowserCtrl* mWebBrowser; + std::string mNavigateTo; + LLMediaCtrl* mWebBrowser; }; diff --git a/linden/indra/newview/llpanelclassified.cpp b/linden/indra/newview/llpanelclassified.cpp index 36fc86d13..22500127a 100644 --- a/linden/indra/newview/llpanelclassified.cpp +++ b/linden/indra/newview/llpanelclassified.cpp @@ -142,7 +142,7 @@ class LLClassifiedTeleportHandler : public LLCommandHandler const bool from_search = true; LLPanelClassified::sendClassifiedClickMessage(classified_id, "teleport", from_search); // Invoke teleport - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; const bool trusted_browser = true; return LLURLDispatcher::dispatch(url, web, trusted_browser); } diff --git a/linden/indra/newview/llpaneldebug.cpp b/linden/indra/newview/llpaneldebug.cpp index c804fcea9..745daf597 100644 --- a/linden/indra/newview/llpaneldebug.cpp +++ b/linden/indra/newview/llpaneldebug.cpp @@ -42,7 +42,7 @@ #include "llfontgl.h" // project includes -#include "audioengine.h" +#include "llaudioengine.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcolorswatch.h" diff --git a/linden/indra/newview/llpaneldirfind.cpp b/linden/indra/newview/llpaneldirfind.cpp index 609f5cccd..14c4a909c 100644 --- a/linden/indra/newview/llpaneldirfind.cpp +++ b/linden/indra/newview/llpaneldirfind.cpp @@ -50,6 +50,7 @@ #include "llviewercontrol.h" #include "llmenucommands.h" #include "llmenugl.h" +#include "llpluginclassmedia.h" #include "lltextbox.h" #include "lluiconstants.h" #include "llviewerimagelist.h" @@ -143,9 +144,11 @@ BOOL LLPanelDirFind::postBuild() } - mWebBrowser = getChild<LLWebBrowserCtrl>(mBrowserName); + mWebBrowser = getChild<LLMediaCtrl>(mBrowserName); if (mWebBrowser) { + mWebBrowser->addObserver(this); + // new pages appear in same window as the results page now mWebBrowser->setOpenInInternalBrowser( false ); mWebBrowser->setOpenInExternalBrowser( false ); @@ -156,9 +159,6 @@ BOOL LLPanelDirFind::postBuild() // redirect 404 pages from S3 somewhere else mWebBrowser->set404RedirectUrl( getString("redirect_404_url") ); - // Track updates for progress display. - mWebBrowser->addObserver(this); - navigateToDefaultPage(); } @@ -167,8 +167,6 @@ BOOL LLPanelDirFind::postBuild() LLPanelDirFind::~LLPanelDirFind() { - if (mWebBrowser) - mWebBrowser->remObserver(this); } // virtual @@ -485,19 +483,27 @@ void LLPanelDirFind::onClickSearch(void* data) LLFloaterDirectory::sNewSearchCount++; } -void LLPanelDirFind::onNavigateBegin( const EventType& eventIn ) -{ - childSetText("status_text", getString("loading_text")); -} - -void LLPanelDirFind::onNavigateComplete( const EventType& eventIn ) +void LLPanelDirFind::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) { - childSetText("status_text", getString("done_text")); -} - -void LLPanelDirFind::onLocationChange( const EventType& eventIn ) -{ - llinfos << eventIn.getStringValue() << llendl; + switch(event) + { + case MEDIA_EVENT_NAVIGATE_BEGIN: + childSetText("status_text", getString("loading_text")); + break; + + case MEDIA_EVENT_NAVIGATE_COMPLETE: + childSetText("status_text", getString("done_text")); + break; + + case MEDIA_EVENT_LOCATION_CHANGED: + // Debugging info to console + llinfos << self->getLocation() << llendl; + break; + + default: + // Having a default case makes the compiler happy. + break; + } } //--------------------------------------------------------------------------- diff --git a/linden/indra/newview/llpaneldirfind.h b/linden/indra/newview/llpaneldirfind.h index 1a97f4b58..d3dda6e7b 100644 --- a/linden/indra/newview/llpaneldirfind.h +++ b/linden/indra/newview/llpaneldirfind.h @@ -34,19 +34,18 @@ #define LL_LLPANELDIRFIND_H #include "llpaneldirbrowser.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" class LLUICtrl; class LLLineEditor; class LLPanelDirFindAll; class LLFloaterDirectory; -class LLWebBrowserCtrlObserver; // This class in an abstract base class for all new style search widgets. It contains a pointer to a web browser control // class LLPanelDirFind : public LLPanelDirBrowser, - public LLWebBrowserCtrlObserver + public LLViewerMediaObserver { public: LLPanelDirFind(const std::string& name, LLFloaterDirectory* floater, const std::string& browser_name); @@ -73,15 +72,11 @@ class LLPanelDirFind static void onCommitSearch(LLUICtrl*, void* data); static void onClickHelp( void* data ); - /*virtual*/ void onNavigateBegin( const EventType& eventIn ); - /*virtual*/ void onNavigateComplete( const EventType& eventIn ); - - // Used to update progress indicator - /*virtual*/ void onLocationChange( const EventType& eventIn ); - // Debugging info to console + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); protected: - LLWebBrowserCtrl* mWebBrowser; + LLMediaCtrl* mWebBrowser; std::string mBrowserName; }; diff --git a/linden/indra/newview/llpaneldirgroups.cpp b/linden/indra/newview/llpaneldirgroups.cpp index 1aa2e8625..411951466 100644 --- a/linden/indra/newview/llpaneldirgroups.cpp +++ b/linden/indra/newview/llpaneldirgroups.cpp @@ -41,6 +41,7 @@ #include "llqueryflags.h" #include "llviewercontrol.h" #include "llviewerwindow.h" +#include "llmediactrl.h" LLPanelDirGroups::LLPanelDirGroups(const std::string& name, LLFloaterDirectory* floater) : LLPanelDirBrowser(name, floater) diff --git a/linden/indra/newview/llpanelface.cpp b/linden/indra/newview/llpanelface.cpp index 68e603e83..b9a40da53 100644 --- a/linden/indra/newview/llpanelface.cpp +++ b/linden/indra/newview/llpanelface.cpp @@ -66,6 +66,7 @@ #include "llviewerstats.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" +#include "llpluginclassmedia.h" // // Methods @@ -77,7 +78,6 @@ BOOL LLPanelFace::postBuild() LLTextureCtrl* mTextureCtrl; LLColorSwatchCtrl* mColorSwatch; - LLTextBox* mLabelTexGen; LLComboBox* mComboTexGen; LLCheckBoxCtrl *mCheckFullbright; @@ -85,7 +85,6 @@ BOOL LLPanelFace::postBuild() LLTextBox* mLabelColorTransp; LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha - LLTextBox* mLabelGlow; LLSpinCtrl* mCtrlGlow; setMouseOpaque(FALSE); @@ -156,7 +155,7 @@ BOOL LLPanelFace::postBuild() mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright); mCheckFullbright->setCallbackUserData( this ); } - mLabelTexGen = getChild<LLTextBox>("tex gen"); + mComboTexGen = getChild<LLComboBox>("combobox texgen"); if(mComboTexGen) { @@ -165,7 +164,6 @@ BOOL LLPanelFace::postBuild() mComboTexGen->setCallbackUserData( this ); } - mLabelGlow = getChild<LLTextBox>("glow label"); mCtrlGlow = getChild<LLSpinCtrl>("glow"); if(mCtrlGlow) { @@ -507,11 +505,6 @@ void LLPanelFace::getState() childSetEnabled("button align",FALSE); //mBtnAutoFix->setEnabled ( FALSE ); - if(LLViewerMedia::hasMedia()) - { - childSetEnabled("textbox autofix",editable); - childSetEnabled("button align",editable); - } //if ( LLMediaEngine::getInstance()->getMediaRenderer () ) // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) // { @@ -568,7 +561,15 @@ void LLPanelFace::getState() } } } + + if(LLViewerMedia::textureHasMedia(id)) + { + childSetEnabled("textbox autofix",editable); + childSetEnabled("button align",editable); + } + } + LLAggregatePermissions texture_perms; if(texture_ctrl) @@ -1117,14 +1118,18 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor { virtual bool apply(LLViewerObject* object, S32 te) { + // TODO: the media impl pointer should actually be stored by the texture + viewer_media_t pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(object->getTE ( te )->getID()); // only do this if it's a media texture - if ( object->getTE ( te )->getID() == LLViewerMedia::getMediaTextureID() ) + if ( pMediaImpl.notNull()) { - S32 media_width, media_height; - S32 texture_width, texture_height; - if ( LLViewerMedia::getMediaSize( &media_width, &media_height ) - && LLViewerMedia::getTextureSize( &texture_width, &texture_height ) ) + LLPluginClassMedia *media = pMediaImpl->getMediaPlugin(); + if(media) { + S32 media_width = media->getWidth(); + S32 media_height = media->getHeight(); + S32 texture_width = media->getTextureWidth(); + S32 texture_height = media->getTextureHeight(); F32 scale_s = (F32)media_width / (F32)texture_width; F32 scale_t = (F32)media_height / (F32)texture_height; diff --git a/linden/indra/newview/llpanellandaudio.cpp b/linden/indra/newview/llpanellandaudio.cpp new file mode 100644 index 000000000..0247009bb --- /dev/null +++ b/linden/indra/newview/llpanellandaudio.cpp @@ -0,0 +1,195 @@ +/** + * @file llpanellandaudio.cpp + * @brief Allows configuration of "media" for a land parcel, + * for example movies, web pages, and audio. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanellandaudio.h" + +// viewer includes +#include "llmimetypes.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "lluictrlfactory.h" + +// library includes +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloaterurlentry.h" +#include "llfocusmgr.h" +#include "lllineeditor.h" +#include "llparcel.h" +#include "lltextbox.h" +#include "llradiogroup.h" +#include "llspinctrl.h" +#include "llsdutil.h" +#include "lltexturectrl.h" +#include "roles_constants.h" +#include "llscrolllistctrl.h" + +// Values for the parcel voice settings radio group +enum +{ + kRadioVoiceChatEstate = 0, + kRadioVoiceChatPrivate = 1, + kRadioVoiceChatDisable = 2 +}; + +//--------------------------------------------------------------------------- +// LLPanelLandAudio +//--------------------------------------------------------------------------- + +LLPanelLandAudio::LLPanelLandAudio(LLParcelSelectionHandle& parcel) +: LLPanel(std::string("land_media_panel")), mParcel(parcel) +{ +} + + +// virtual +LLPanelLandAudio::~LLPanelLandAudio() +{ +} + + +BOOL LLPanelLandAudio::postBuild() +{ + mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check_sound_local"); + childSetCommitCallback("check_sound_local", onCommitAny, this); + + mRadioVoiceChat = getChild<LLRadioGroup>("parcel_voice_channel"); + childSetCommitCallback("parcel_voice_channel", onCommitAny, this); + + mMusicURLEdit = getChild<LLLineEditor>("music_url"); + childSetCommitCallback("music_url", onCommitAny, this); + + mMusicUrlCheck = getChild<LLCheckBoxCtrl>("hide_music_url"); + childSetCommitCallback("hide_music_url", onCommitAny, this); + + return TRUE; +} + + +// public +void LLPanelLandAudio::refresh() +{ + LLParcel *parcel = mParcel->getParcel(); + + if (!parcel) + { + clearCtrls(); + } + else + { + // something selected, hooray! + + // Display options + BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); + + mMusicURLEdit->setText(parcel->getMusicURL()); + mMusicURLEdit->setEnabled( can_change_media ); + + mMusicUrlCheck->set( parcel->getObscureMusic() ); + mMusicUrlCheck->setEnabled( can_change_media ); + + mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->setEnabled( can_change_media ); + + if(parcel->getParcelFlagAllowVoice()) + { + if(parcel->getParcelFlagUseEstateVoiceChannel()) + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); + else + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); + } + else + { + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); + } + + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + mRadioVoiceChat->setEnabled( region && region->isVoiceEnabled() && can_change_media ); + } +} +// static +void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata) +{ + LLPanelLandAudio *self = (LLPanelLandAudio *)userdata; + + LLParcel* parcel = self->mParcel->getParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL sound_local = self->mCheckSoundLocal->get(); + int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); + std::string music_url = self->mMusicURLEdit->getText(); + U8 obscure_music = self->mMusicUrlCheck->get(); + + + BOOL voice_enabled; + BOOL voice_estate_chan; + + switch(voice_setting) + { + default: + case kRadioVoiceChatEstate: + voice_enabled = TRUE; + voice_estate_chan = TRUE; + break; + case kRadioVoiceChatPrivate: + voice_enabled = TRUE; + voice_estate_chan = FALSE; + break; + case kRadioVoiceChatDisable: + voice_enabled = FALSE; + voice_estate_chan = FALSE; + break; + } + + // Remove leading/trailing whitespace (common when copying/pasting) + LLStringUtil::trim(music_url); + + // Push data into current parcel + parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); + parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); + parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); + parcel->setMusicURL(music_url); + parcel->setObscureMusic(obscure_music); + + // Send current parcel data upstream to server + LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} diff --git a/linden/indra/llmedia/llmediaimplexample2.h b/linden/indra/newview/llpanellandaudio.h similarity index 54% rename from linden/indra/llmedia/llmediaimplexample2.h rename to linden/indra/newview/llpanellandaudio.h index 6a4f80b3d..3d5d63347 100644 --- a/linden/indra/llmedia/llmediaimplexample2.h +++ b/linden/indra/newview/llpanellandaudio.h @@ -1,6 +1,7 @@ /** - * @file llmediaimplexample2.h - * @brief Example 2 of a media impl concrete class + * @file llpanellandaudio.h + * @brief Allows configuration of "audio" for a land parcel. + * * * $LicenseInfo:firstyear=2007&license=viewergpl$ * @@ -30,47 +31,33 @@ * $/LicenseInfo$ */ -#ifndef LLMEDIAIMPLEXAMPLE2_H -#define LLMEDIAIMPLEXAMPLE2_H +#ifndef LLPANELLANDAUDIO_H +#define LLPANELLANDAUDIO_H -#include "llmediaimplcommon.h" -#include "llmediaimplfactory.h" +#include "lllineeditor.h" +#include "llpanel.h" +#include "llparcelselection.h" +#include "lluifwd.h" // widget pointer types -class LLMediaManagerData; -class LLMediaImplMaker; - -class LLMediaImplExample2 : - public LLMediaImplCommon -{ - public: - LLMediaImplExample2(); - - static bool startup( LLMediaManagerData* init_data ); - static bool closedown(); - - /* virtual */ bool init(); - /* virtual */ bool navigateTo( const std::string url ); - /* virtual */ bool load( const std::string url ); - /* virtual */ std::string getVersion(); - /* virtual */ bool updateMedia(); - /* virtual */ unsigned char* getMediaData(); - /* virtual */ bool reset(); - /* virtual */ bool setRequestedMediaSize( int width, int height ); - - private: - unsigned char* mMediaPixels; - int mXpos; - int mYpos; -}; - -class LLMediaImplExample2Maker : public LLMediaImplMaker +class LLPanelLandAudio + : public LLPanel { - public: - LLMediaImplExample2Maker(); - LLMediaImplExample2* create() - { - return new LLMediaImplExample2(); - } +public: + LLPanelLandAudio(LLSafeHandle<LLParcelSelection>& parcelp); + /*virtual*/ ~LLPanelLandAudio(); + /*virtual*/ BOOL postBuild(); + void refresh(); + +private: + static void onCommitAny(LLUICtrl* ctrl, void *userdata); + +private: + LLCheckBoxCtrl* mCheckSoundLocal; + LLRadioGroup* mRadioVoiceChat; + LLLineEditor* mMusicURLEdit; + LLCheckBoxCtrl* mMusicUrlCheck; + + LLSafeHandle<LLParcelSelection>& mParcel; }; -#endif // LLMEDIAIMPLEXAMPLE2_H +#endif diff --git a/linden/indra/newview/llpanellandmedia.cpp b/linden/indra/newview/llpanellandmedia.cpp index bebd69e4e..a8e7c4aea 100644 --- a/linden/indra/newview/llpanellandmedia.cpp +++ b/linden/indra/newview/llpanellandmedia.cpp @@ -39,6 +39,8 @@ #include "llmimetypes.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" #include "lluictrlfactory.h" // library includes @@ -54,6 +56,7 @@ #include "llsdutil.h" #include "lltexturectrl.h" #include "roles_constants.h" +#include "llscrolllistctrl.h" #include "hippoGridManager.h" @@ -62,15 +65,8 @@ //--------------------------------------------------------------------------- LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) -: LLPanel(std::string("land_media_panel")), - +: LLPanel(), mParcel(parcel), - mCheckSoundLocal(NULL), - mSoundHelpButton(NULL), - mCheckEnableVoiceChat(NULL), - mCheckEnableVoiceChatIsEstateDisabled(NULL), - mCheckEnableVoiceChatParcel(NULL), - mMusicURLEdit(NULL), mMediaURLEdit(NULL), mMediaDescEdit(NULL), mMediaTypeCombo(NULL), @@ -81,8 +77,7 @@ LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) mMediaTextureCtrl(NULL), mMediaAutoScaleCheck(NULL), mMediaLoopCheck(NULL), - mMediaUrlCheck(NULL), - mMusicUrlCheck(NULL) + mMediaUrlCheck(NULL) { } @@ -90,34 +85,10 @@ LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) // virtual LLPanelLandMedia::~LLPanelLandMedia() { - // close LLFloaterURLEntry? -} - - -// static -void LLPanelLandMedia::onClickSoundHelp(void*) -{ - LLNotifications::instance().add("ClickSoundHelpLand"); } - BOOL LLPanelLandMedia::postBuild() { - mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check sound local"); - childSetCommitCallback("check sound local", onCommitAny, this); - - mSoundHelpButton = getChild<LLButton>("?"); - mSoundHelpButton->setClickedCallback(onClickSoundHelp, this); - - mCheckEnableVoiceChat = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel"); - childSetCommitCallback("parcel_enable_voice_channel", onCommitAny, this); - mCheckEnableVoiceChatIsEstateDisabled = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_is_estate_disabled"); - childSetCommitCallback("parcel_enable_voice_channel_is_estate_disabled", onCommitAny, this); - mCheckEnableVoiceChatParcel = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_parcel"); - childSetCommitCallback("parcel_enable_voice_channel_parcel", onCommitAny, this); - - mMusicURLEdit = getChild<LLLineEditor>("music_url"); - childSetCommitCallback("music_url", onCommitAny, this); mMediaTextureCtrl = getChild<LLTextureCtrl>("media texture"); mMediaTextureCtrl->setCommitCallback( onCommitAny ); @@ -130,16 +101,13 @@ BOOL LLPanelLandMedia::postBuild() childSetCommitCallback("media_auto_scale", onCommitAny, this); mMediaLoopCheck = getChild<LLCheckBoxCtrl>("media_loop"); - childSetCommitCallback("media_loop", onCommitAny, this); + childSetCommitCallback("media_loop", onCommitAny, this ); mMediaUrlCheck = getChild<LLCheckBoxCtrl>("hide_media_url"); - childSetCommitCallback("hide_media_url", onCommitAny, this); - - mMusicUrlCheck = getChild<LLCheckBoxCtrl>("hide_music_url"); - childSetCommitCallback("hide_music_url", onCommitAny, this); + childSetCommitCallback("hide_media_url", onCommitAny, this ); mMediaURLEdit = getChild<LLLineEditor>("media_url"); - childSetCommitCallback("media_url", onCommitAny, this); + childSetCommitCallback("media_url", onCommitAny, this ); mMediaDescEdit = getChild<LLLineEditor>("url_description"); childSetCommitCallback("url_description", onCommitAny, this); @@ -148,15 +116,41 @@ BOOL LLPanelLandMedia::postBuild() childSetCommitCallback("media type", onCommitType, this); populateMIMECombo(); + mMediaResetCtrl = getChild<LLSpinCtrl>("media_reset_time"); + childSetCommitCallback("media_reset_time", onCommitAny, this); + mMediaResetCtrlLabel = getChild<LLTextBox>("media_reset"); + mMediaWidthCtrl = getChild<LLSpinCtrl>("media_size_width"); childSetCommitCallback("media_size_width", onCommitAny, this); mMediaHeightCtrl = getChild<LLSpinCtrl>("media_size_height"); childSetCommitCallback("media_size_height", onCommitAny, this); mMediaSizeCtrlLabel = getChild<LLTextBox>("media_size"); + mMediaNavigateAllowCheck = getChild<LLCheckBoxCtrl>("check navigate allow"); + childSetCommitCallback("check navigate allow", onCommitAny, this); + mMediaURLFilterCheck = getChild<LLCheckBoxCtrl>("check navigate filter"); + childSetCommitCallback("check navigate filter", onCommitAny, this); + mSetURLButton = getChild<LLButton>("set_media_url"); childSetAction("set_media_url", onSetBtn, this); + mResetURLButton = getChild<LLButton>("reset_media_url"); + childSetAction("reset_media_url", onResetBtn, this); + + mURLFilterList = getChild<LLScrollListCtrl>("filter_list"); + + mMediaURLFilterDomainEdit = getChild<LLLineEditor>("navigate_filter_domain"); + + mMediaURLFilterAddButton = getChild<LLButton>("add_navigate_filter"); + childSetAction("add_navigate_filter", onClickAddURLFilter, this); + + mMediaURLFilterRemoveButton = getChild<LLButton>("remove_navigate_filter"); + childSetAction("remove_navigate_filter", onClickRemoveURLFilter, this); + + mRadioNavigateControl = getChild<LLRadioGroup>("radio_navigate_allow"); + childSetCommitCallback("radio_navigate_allow", onCommitAny, this); + + return TRUE; } @@ -177,8 +171,8 @@ void LLPanelLandMedia::refresh() // Display options BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); - mCheckSoundLocal->set( parcel->getSoundLocal() ); - mCheckSoundLocal->setEnabled( can_change_media ); +//imprudence fixme mCheckSoundLocal->set( parcel->getSoundLocal() ); +//imprudence fixme mCheckSoundLocal->setEnabled( can_change_media ); LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if (!region) @@ -194,42 +188,43 @@ void LLPanelLandMedia::refresh() { if (region && region->isVoiceEnabled()) // estate-wide voice-disable overrides all { - mCheckEnableVoiceChatIsEstateDisabled->setVisible(false); +//imprudence fixme mCheckEnableVoiceChatIsEstateDisabled->setVisible(false); - mCheckEnableVoiceChat->setVisible(true); - mCheckEnableVoiceChat->setEnabled( can_change_media ); - mCheckEnableVoiceChat->set(allow_voice); +//imprudence fixme mCheckEnableVoiceChat->setVisible(true); +//imprudence fixme mCheckEnableVoiceChat->setEnabled( can_change_media ); +//imprudence fixme mCheckEnableVoiceChat->set(allow_voice); - mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); +//imprudence fixme mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); } else // disabled at region level { - mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); // always disabled - mCheckEnableVoiceChat->setVisible(false); - mCheckEnableVoiceChat->setEnabled(false); - mCheckEnableVoiceChat->set(false); +//imprudence fixme mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); // always disabled +//imprudence fixme mCheckEnableVoiceChat->setVisible(false); +//imprudence fixme mCheckEnableVoiceChat->setEnabled(false); +//imprudence fixme mCheckEnableVoiceChat->set(false); - mCheckEnableVoiceChatParcel->setEnabled(false); +//imprudence fixme mCheckEnableVoiceChatParcel->setEnabled(false); } } else { - mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); +//imprudence fixme mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); - mCheckEnableVoiceChat->setVisible(true); - mCheckEnableVoiceChat->setEnabled( can_change_media ); - mCheckEnableVoiceChat->set(allow_voice); +//imprudence fixme mCheckEnableVoiceChat->setVisible(true); +//imprudence fixme mCheckEnableVoiceChat->setEnabled( can_change_media ); +//imprudence fixme mCheckEnableVoiceChat->set(allow_voice); - mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); +//imprudence fixme mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); } - mCheckEnableVoiceChatParcel->set(!parcel->getParcelFlagUseEstateVoiceChannel()); +//imprudence fixme mCheckEnableVoiceChatParcel->set(!parcel->getParcelFlagUseEstateVoiceChannel()); + +//imprudence fixme mMusicURLEdit->setText(parcel->getMusicURL()); +//imprudence fixme mMusicURLEdit->setEnabled( can_change_media ); + - mMusicURLEdit->setText(parcel->getMusicURL()); - mMusicURLEdit->setEnabled( can_change_media ); - mMediaURLEdit->setText(parcel->getMediaURL()); - mMediaURLEdit->setEnabled( FALSE ); + childSetText("current_url", parcel->getMediaCurrentURL()); mMediaDescEdit->setText(parcel->getMediaDesc()); mMediaDescEdit->setEnabled( can_change_media ); @@ -246,15 +241,11 @@ void LLPanelLandMedia::refresh() mMediaUrlCheck->set( parcel->getObscureMedia() ); mMediaUrlCheck->setEnabled( can_change_media ); - mMusicUrlCheck->set( parcel->getObscureMusic() ); - mMusicUrlCheck->setEnabled( can_change_media ); - // don't display urls if you're not able to change it // much requested change in forums so people can't 'steal' urls // NOTE: bug#2009 means this is still vunerable - however, bug // should be closed since this bug opens up major security issues elsewhere. bool obscure_media = ! can_change_media && parcel->getObscureMedia(); - bool obscure_music = ! can_change_media && parcel->getObscureMusic(); // Special code to disable asterixes for html type if(mime_type == "text/html") @@ -264,7 +255,6 @@ void LLPanelLandMedia::refresh() mMediaUrlCheck->setEnabled( false ); } - mMusicURLEdit->setDrawAsterixes( obscure_music ); mMediaURLEdit->setDrawAsterixes( obscure_media ); mMediaAutoScaleCheck->set( parcel->getMediaAutoScale () ); @@ -278,6 +268,10 @@ void LLPanelLandMedia::refresh() else mMediaLoopCheck->set( false ); mMediaLoopCheck->setEnabled ( can_change_media && allow_looping ); + + mMediaResetCtrl->set( parcel->getMediaURLTimeout() ); + mMediaResetCtrl->setEnabled( can_change_media ); + mMediaResetCtrlLabel->setEnabled( can_change_media ); // disallow media size change for mime types that don't allow it bool allow_resize = LLMIMETypes::findAllowResize( mime_type ); @@ -301,28 +295,45 @@ void LLPanelLandMedia::refresh() mMediaTextureCtrl->setEnabled( can_change_media ); mSetURLButton->setEnabled( can_change_media ); + mResetURLButton->setEnabled( can_change_media ); - #if 0 - // there is a media url and a media texture selected - if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) - { - // turn on transport controls if allowed for this parcel - mMediaStopButton->setEnabled ( editable ); - mMediaStartButton->setEnabled ( editable ); - } - else - { - // no media url or no media texture - mMediaStopButton->setEnabled ( FALSE ); - mMediaStartButton->setEnabled ( FALSE ); - }; - #endif + mMediaURLFilterCheck->set( parcel->getMediaURLFilterEnable() ); + mMediaURLFilterCheck->setEnabled( can_change_media ); LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get(); if (floater_url_entry) { floater_url_entry->updateFromLandMediaPanel(); } + + // This radial control is really just an inverse mapping to the boolean allow_navigate value. + // It is set as a radial merely for user readability. + mRadioNavigateControl->setSelectedIndex(! parcel->getMediaAllowNavigate()); + mRadioNavigateControl->setEnabled( can_change_media ); + + mMediaURLFilterDomainEdit->setEnabled( can_change_media ); + mMediaURLFilterAddButton->setEnabled( can_change_media ); + mMediaURLFilterRemoveButton->setEnabled( can_change_media ); + + if (mURLFilterList) + { + mURLFilterList->setEnabled( can_change_media ); + + mURLFilterList->deleteAllItems(); + + LLSD list = parcel->getMediaURLFilterList(); + + for (LLSD::array_iterator i = list.beginArray(); i != list.endArray(); ++i) + { + std::string domain = (*i).asString(); + + LLSD element; + element["id"] = domain; + element["columns"][0]["value"] = domain; + + mURLFilterList->addElement(element); + } + } } } @@ -364,12 +375,19 @@ void LLPanelLandMedia::setMediaType(const std::string& mime_type) void LLPanelLandMedia::setMediaURL(const std::string& media_url) { mMediaURLEdit->setText(media_url); + LLParcel *parcel = mParcel->getParcel(); + if(parcel) + parcel->setMediaCurrentURL(media_url); + // LLViewerMedia::navigateHome(); + + mMediaURLEdit->onCommit(); + // LLViewerParcelMedia::sendMediaNavigateMessage(media_url); + childSetText("current_url", media_url); } - std::string LLPanelLandMedia::getMediaURL() { - return mMediaURLEdit->getText(); + return mMediaURLEdit->getText(); } // static @@ -398,33 +416,26 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata) } // Extract data from UI - BOOL sound_local = self->mCheckSoundLocal->get(); - std::string music_url = self->mMusicURLEdit->getText(); std::string media_url = self->mMediaURLEdit->getText(); std::string media_desc = self->mMediaDescEdit->getText(); std::string mime_type = self->childGetText("mime_type"); U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); U8 media_loop = self->mMediaLoopCheck->get(); U8 obscure_media = self->mMediaUrlCheck->get(); - U8 obscure_music = self->mMusicUrlCheck->get(); + F32 media_reset_time = (F32)self->mMediaResetCtrl->get(); S32 media_width = (S32)self->mMediaWidthCtrl->get(); S32 media_height = (S32)self->mMediaHeightCtrl->get(); LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); + U8 navigate_allow = ! self->mRadioNavigateControl->getSelectedIndex(); + U8 navigate_filter = self->mMediaURLFilterCheck->get(); - BOOL voice_enabled = self->mCheckEnableVoiceChat->get(); - BOOL voice_estate_chan = ! self->mCheckEnableVoiceChatParcel->get(); self->childSetText("mime_type", mime_type); // Remove leading/trailing whitespace (common when copying/pasting) - LLStringUtil::trim(music_url); LLStringUtil::trim(media_url); // Push data into current parcel - parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); - parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); - parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); - parcel->setMusicURL(music_url); parcel->setMediaURL(media_url); parcel->setMediaType(mime_type); parcel->setMediaDesc(media_desc); @@ -434,7 +445,10 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata) parcel->setMediaAutoScale ( media_auto_scale ); parcel->setMediaLoop ( media_loop ); parcel->setObscureMedia( obscure_media ); - parcel->setObscureMusic( obscure_music ); + parcel->setMediaURLFilterEnable(navigate_filter); + parcel->setMediaAllowNavigate(navigate_allow); + parcel->setMediaURLTimeout(media_reset_time); + // Send current parcel data upstream to server LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); @@ -453,3 +467,91 @@ void LLPanelLandMedia::onSetBtn(void *userdata) parent_floater->addDependentFloater(self->mURLEntryFloater.get()); } } + +// static +void LLPanelLandMedia::onResetBtn(void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + LLParcel* parcel = self->mParcel->getParcel(); + // LLViewerMedia::navigateHome(); + self->refresh(); + self->childSetText("current_url", parcel->getMediaURL()); + // LLViewerParcelMedia::sendMediaNavigateMessage(parcel->getMediaURL()); + +} +// static +void LLPanelLandMedia::onClickAddURLFilter(void *userdata) +{ + LLPanelLandMedia *panelp = (LLPanelLandMedia *)userdata; + LLParcel* parcel = panelp->mParcel->getParcel(); + + LLSD list = parcel->getMediaURLFilterList(); + + std::string domain = panelp->mMediaURLFilterDomainEdit->getText(); + LLStringUtil::trim(domain); + + BOOL add = TRUE; + if (domain == "") + { + add = FALSE; + } + + // check for dupes + for(S32 i = 0; i < list.size(); i++) + { + if (list[i].asString() == domain) + { + add = FALSE; + break; + } + } + + if (add) + { + list.append(domain); + parcel->setMediaURLFilterList(list); + + LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); + + panelp->mMediaURLFilterDomainEdit->setText(std::string("")); + + panelp->refresh(); + } + +} + +// static +void LLPanelLandMedia::onClickRemoveURLFilter(void *data) +{ + LLPanelLandMedia* panelp = (LLPanelLandMedia*)data; + if (panelp && panelp->mURLFilterList) + { + LLParcel* parcel = panelp->mParcel->getParcel(); + if (parcel) + { + LLSD list = parcel->getMediaURLFilterList(); + + std::vector<LLScrollListItem*> domains = panelp->mURLFilterList->getAllSelected(); + for (std::vector<LLScrollListItem*>::iterator iter = domains.begin(); iter != domains.end(); iter++) + { + LLScrollListItem* item = *iter; + const std::string domain = item->getValue().asString(); + + for(S32 i = 0; i < list.size(); i++) + { + if (list[i].asString() == domain) + { + list.erase(i); + break; + } + } + } + + parcel->setMediaURLFilterList(list); + LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); + + panelp->refresh(); + } + } + +} diff --git a/linden/indra/newview/llpanellandmedia.h b/linden/indra/newview/llpanellandmedia.h index 6a53dd42a..c883d9801 100644 --- a/linden/indra/newview/llpanellandmedia.h +++ b/linden/indra/newview/llpanellandmedia.h @@ -56,29 +56,36 @@ class LLPanelLandMedia static void onCommitAny(LLUICtrl* ctrl, void *userdata); static void onCommitType(LLUICtrl* ctrl, void *userdata); static void onSetBtn(void* userdata); - static void onClickSoundHelp(void*); - + static void onResetBtn(void* userdata); + static void onClickAddURLFilter(void *userdata); + static void onClickRemoveURLFilter(void *userdata); + private: - LLCheckBoxCtrl* mCheckSoundLocal; - LLButton* mSoundHelpButton; - LLCheckBoxCtrl* mCheckEnableVoiceChat; - LLCheckBoxCtrl* mCheckEnableVoiceChatIsEstateDisabled; - LLCheckBoxCtrl* mCheckEnableVoiceChatParcel; - LLLineEditor* mMusicURLEdit; LLLineEditor* mMediaURLEdit; LLLineEditor* mMediaDescEdit; LLComboBox* mMediaTypeCombo; LLButton* mSetURLButton; + LLButton* mResetURLButton; + LLSpinCtrl* mMediaResetCtrl; LLSpinCtrl* mMediaHeightCtrl; LLSpinCtrl* mMediaWidthCtrl; + LLTextBox* mMediaResetCtrlLabel; LLTextBox* mMediaSizeCtrlLabel; LLTextureCtrl* mMediaTextureCtrl; LLCheckBoxCtrl* mMediaAutoScaleCheck; LLCheckBoxCtrl* mMediaLoopCheck; LLCheckBoxCtrl* mMediaUrlCheck; - LLCheckBoxCtrl* mMusicUrlCheck; LLHandle<LLFloater> mURLEntryFloater; + LLCheckBoxCtrl* mMediaNavigateAllowCheck; + LLCheckBoxCtrl* mMediaURLFilterCheck; + LLLineEditor* mMediaURLFilterDomainEdit; + LLButton* mMediaURLFilterAddButton; + LLButton* mMediaURLFilterRemoveButton; + LLScrollListCtrl* mURLFilterList; + LLRadioGroup* mRadioNavigateControl; + + LLSafeHandle<LLParcelSelection>& mParcel; }; diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp index 23b7785b5..a8b71064e 100644 --- a/linden/indra/newview/llpanellogin.cpp +++ b/linden/indra/newview/llpanellogin.cpp @@ -73,12 +73,10 @@ #include "lluictrlfactory.h" #include "llhttpclient.h" #include "llweb.h" -#include "llwebbrowserctrl.h" #include "viewerversion.h" +#include "llmediactrl.h" -#include "llfloaterhtml.h" - -#include "llfloaterhtmlhelp.h" +#include "llfloatermediabrowser.h" #include "llfloatertos.h" #include "llglheaders.h" @@ -101,7 +99,7 @@ class LLLoginRefreshHandler : public LLCommandHandler public: // don't allow from external browsers LLLoginRefreshHandler() : LLCommandHandler("login_refresh", true) { } - bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web) + bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) { @@ -291,16 +289,15 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, #endif // get the web browser control - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("login_html"); + LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); + web_browser->addObserver(this); + // Need to handle login secondlife:///app/ URLs web_browser->setTrusted( true ); - // observe browser events - web_browser->addObserver( this ); - // don't make it a tab stop until SL-27594 is fixed web_browser->setTabStop(FALSE); - web_browser->navigateToLocalPage( "loading", "loading.html" ); + // web_browser->navigateToLocalPage( "loading", "loading.html" ); // make links open in external browser web_browser->setOpenInExternalBrowser( true ); @@ -335,7 +332,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, void LLPanelLogin::setSiteIsAlive( bool alive ) { - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("login_html"); + LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); // if the contents of the site was retrieved if ( alive ) { @@ -398,6 +395,11 @@ LLPanelLogin::~LLPanelLogin() //// We know we're done with the image, so be rid of it. //gImageList.deleteImage( mLogoImage ); + + if ( gFocusMgr.getDefaultKeyboardFocus() == this ) + { + gFocusMgr.setDefaultKeyboardFocus(NULL); + } } // virtual @@ -779,7 +781,7 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh) { if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return; - LLWebBrowserCtrl* web_browser = sInstance->getChild<LLWebBrowserCtrl>("login_html"); + LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); if (web_browser) { @@ -952,25 +954,28 @@ void LLPanelLogin::loadLoginPage() #endif #endif - LLWebBrowserCtrl* web_browser = sInstance->getChild<LLWebBrowserCtrl>("login_html"); + LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); // navigate to the "real" page - web_browser->navigateTo( oStr.str() ); + web_browser->navigateTo( oStr.str(), "text/html" ); } -void LLPanelLogin::onNavigateComplete( const EventType& eventIn ) +void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event) { - LLWebBrowserCtrl* web_browser = sInstance->getChild<LLWebBrowserCtrl>("login_html"); - if (web_browser) + if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) { - // *HACK HACK HACK HACK! - /* Stuff a Tab key into the browser now so that the first field will - ** get the focus! The embedded javascript on the page that properly - ** sets the initial focus in a real web browser is not working inside - ** the viewer, so this is an UGLY HACK WORKAROUND for now. - */ - // Commented out as it's not reliable - //web_browser->handleKey(KEY_TAB, MASK_NONE, false); + LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); + if (web_browser) + { + // *HACK HACK HACK HACK! + /* Stuff a Tab key into the browser now so that the first field will + ** get the focus! The embedded javascript on the page that properly + ** sets the initial focus in a real web browser is not working inside + ** the viewer, so this is an UGLY HACK WORKAROUND for now. + */ + // Commented out as it's not reliable + //web_browser->handleKey(KEY_TAB, MASK_NONE, false); + } } } diff --git a/linden/indra/newview/llpanellogin.h b/linden/indra/newview/llpanellogin.h index 15c2d2804..c99fa3064 100644 --- a/linden/indra/newview/llpanellogin.h +++ b/linden/indra/newview/llpanellogin.h @@ -35,14 +35,14 @@ #include "llpanel.h" #include "llmemory.h" // LLPointer<> -#include "llwebbrowserctrl.h" // LLWebBrowserCtrlObserver +#include "llmediactrl.h" // LLMediaCtrlObserver class LLUIImage; class LLPanelLogin: public LLPanel, - public LLWebBrowserCtrlObserver + public LLViewerMediaObserver { LOG_CLASS(LLPanelLogin); public: @@ -84,6 +84,9 @@ class LLPanelLogin: static void setAlwaysRefresh(bool refresh); static void mungePassword(LLUICtrl* caller, void* user_data); + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); + private: static void onClickConnect(void*); static void onClickGrid(void*); @@ -91,7 +94,6 @@ class LLPanelLogin: static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response); static void onClickQuit(void*); static void onClickVersion(void*); - virtual void onNavigateComplete( const EventType& eventIn ); static void onClickForgotPassword(void*); static void onPassKey(LLLineEditor* caller, void* user_data); static void onSelectServer(LLUICtrl*, void*); diff --git a/linden/indra/newview/llpanelmediahud.cpp b/linden/indra/newview/llpanelmediahud.cpp new file mode 100644 index 000000000..39c4b637b --- /dev/null +++ b/linden/indra/newview/llpanelmediahud.cpp @@ -0,0 +1,667 @@ +/** + * @file llpanelmsgs.cpp + * @brief Message popup preferences panel + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +//LLPanelMediaHUD +#include "llagent.h" +#include "llparcel.h" +#include "llpanel.h" +#include "llselectmgr.h" +#include "llrender.h" +#include "lldrawable.h" +#include "llviewerwindow.h" +#include "lluictrlfactory.h" +#include "llbutton.h" +#include "llface.h" +#include "llhudview.h" +#include "lliconctrl.h" +#include "lltoolpie.h" +#include "llviewercamera.h" +#include "llpanelmediahud.h" +#include "llpluginclassmedia.h" +#include "llviewercontrol.h" +#include "llviewerparcelmgr.h" +#include "llviewermedia.h" +#include "llviewermediafocus.h" +#include "llvovolume.h" +#include "llweb.h" + +glh::matrix4f glh_get_current_modelview(); +glh::matrix4f glh_get_current_projection(); + +const F32 ZOOM_NEAR_PADDING = 1.0f; +const F32 ZOOM_MEDIUM_PADDING = 1.2f; +const F32 ZOOM_FAR_PADDING = 1.5f; + +// +// LLPanelMediaHUD +// + +LLPanelMediaHUD::LLPanelMediaHUD(viewer_media_t media_impl) + : mMediaImpl(media_impl) +{ + mMediaFocus = false; + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_hud.xml"); + mMouseMoveTimer.reset(); + mFadeTimer.stop(); + mCurrentZoom = ZOOM_NONE; + mScrollState = SCROLL_NONE; + + mPanelHandle.bind(this); +} +LLPanelMediaHUD::~LLPanelMediaHUD() +{ + mMediaImpl = NULL; +} + +BOOL LLPanelMediaHUD::postBuild() +{ + LLButton* close_btn = getChild<LLButton>("close"); + close_btn->setClickedCallback(onClickClose, this); + + LLButton* back_btn = getChild<LLButton>("back"); + back_btn->setClickedCallback(onClickBack, this); + + LLButton* fwd_btn = getChild<LLButton>("fwd"); + fwd_btn->setClickedCallback(onClickForward, this); + + LLButton* home_btn = getChild<LLButton>("home"); + home_btn->setClickedCallback(onClickHome, this); + + LLButton* stop_btn = getChild<LLButton>("stop"); + stop_btn->setClickedCallback(onClickStop, this); + + LLButton* media_stop_btn = getChild<LLButton>("media_stop"); + media_stop_btn->setClickedCallback(onClickStop, this); + + LLButton* reload_btn = getChild<LLButton>("reload"); + reload_btn->setClickedCallback(onClickReload, this); + + LLButton* play_btn = getChild<LLButton>("play"); + play_btn->setClickedCallback(onClickPlay, this); + + LLButton* pause_btn = getChild<LLButton>("pause"); + pause_btn->setClickedCallback(onClickPause, this); + + LLButton* open_btn = getChild<LLButton>("new_window"); + open_btn->setClickedCallback(onClickOpen, this); + + LLButton* zoom_btn = getChild<LLButton>("zoom_frame"); + zoom_btn->setClickedCallback(onClickZoom, this); + + LLButton* open_btn_h = getChild<LLButton>("new_window_hover"); + open_btn_h->setClickedCallback(onClickOpen, this); + + LLButton* zoom_btn_h = getChild<LLButton>("zoom_frame_hover"); + zoom_btn_h->setClickedCallback(onClickZoom, this); + + LLButton* scroll_up_btn = getChild<LLButton>("scrollup"); + scroll_up_btn->setClickedCallback(onScrollUp, this); + scroll_up_btn->setHeldDownCallback(onScrollUpHeld); + scroll_up_btn->setMouseUpCallback(onScrollStop); + LLButton* scroll_left_btn = getChild<LLButton>("scrollleft"); + scroll_left_btn->setClickedCallback(onScrollLeft, this); + scroll_left_btn->setHeldDownCallback(onScrollLeftHeld); + scroll_left_btn->setMouseUpCallback(onScrollStop); + LLButton* scroll_right_btn = getChild<LLButton>("scrollright"); + scroll_right_btn->setClickedCallback(onScrollRight, this); + scroll_right_btn->setHeldDownCallback(onScrollLeftHeld); + scroll_right_btn->setMouseUpCallback(onScrollStop); + LLButton* scroll_down_btn = getChild<LLButton>("scrolldown"); + scroll_down_btn->setClickedCallback(onScrollDown, this); + scroll_down_btn->setHeldDownCallback(onScrollDownHeld); + scroll_down_btn->setMouseUpCallback(onScrollStop); + + mMouseInactiveTime = gSavedSettings.getF32("MediaControlTimeout"); + mControlFadeTime = gSavedSettings.getF32("MediaControlFadeTime"); + + mCurrentZoom = ZOOM_NONE; + // clicks on HUD buttons do not remove keyboard focus from media + setIsChrome(TRUE); + return TRUE; +} + +void LLPanelMediaHUD::updateShape() +{ + const S32 MIN_HUD_WIDTH=200; + const S32 MIN_HUD_HEIGHT=120; + + LLPluginClassMedia* media_plugin = NULL; + if(mMediaImpl.notNull() && mMediaImpl->hasMedia()) + { + media_plugin = mMediaImpl->getMediaPlugin(); + } + + // Early out for no media plugin + if(media_plugin == NULL) + { + setVisible(FALSE); + return; + } + + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + + bool can_navigate = parcel->getMediaAllowNavigate(); + + // LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection(); + + LLSelectNode* nodep = mMediaFocus ? LLSelectMgr::getInstance()->getSelection()->getFirstNode() : LLSelectMgr::getInstance()->getHoverNode(); + if(! nodep) + { + return; + } + setVisible(FALSE); + LLViewerObject* objectp = nodep->getObject(); + + if (objectp) + { + + // Set the state of the buttons + LLButton* back_btn = getChild<LLButton>("back"); + LLButton* fwd_btn = getChild<LLButton>("fwd"); + LLButton* reload_btn = getChild<LLButton>("reload"); + LLButton* play_btn = getChild<LLButton>("play"); + LLButton* pause_btn = getChild<LLButton>("pause"); + LLButton* stop_btn = getChild<LLButton>("stop"); + LLButton* media_stop_btn = getChild<LLButton>("media_stop"); + LLButton* home_btn = getChild<LLButton>("home"); + LLButton* close_btn = getChild<LLButton>("close"); + LLButton* open_btn = getChild<LLButton>("new_window"); + LLPanel* media_focused_panel = getChild<LLPanel>("media_focused_controls"); + LLPanel* media_hover_panel = getChild<LLPanel>("media_hover_controls"); + back_btn->setVisible(true); + fwd_btn->setVisible(true); + reload_btn->setVisible(true); + stop_btn->setVisible(false); + home_btn->setVisible(true); + close_btn->setVisible(true); + open_btn->setVisible(true); + + + if(mMediaFocus) + { + back_btn->setEnabled(mMediaImpl->canNavigateBack() && can_navigate); + fwd_btn->setEnabled(mMediaImpl->canNavigateForward() && can_navigate); + stop_btn->setEnabled(can_navigate); + home_btn->setEnabled(can_navigate); + LLPluginClassMediaOwner::EMediaStatus result = media_plugin->getStatus(); + + if(media_plugin->pluginSupportsMediaTime()) + { + reload_btn->setEnabled(FALSE); + reload_btn->setVisible(FALSE); + media_stop_btn->setVisible(TRUE); + home_btn->setVisible(FALSE); + back_btn->setEnabled(TRUE); + fwd_btn->setEnabled(TRUE); + switch(result) + { + case LLPluginClassMediaOwner::MEDIA_PLAYING: + play_btn->setEnabled(FALSE); + play_btn->setVisible(FALSE); + pause_btn->setEnabled(TRUE); + pause_btn->setVisible(TRUE); + media_stop_btn->setEnabled(TRUE); + break; + case LLPluginClassMediaOwner::MEDIA_PAUSED: + default: + pause_btn->setEnabled(FALSE); + pause_btn->setVisible(FALSE); + play_btn->setEnabled(TRUE); + play_btn->setVisible(TRUE); + media_stop_btn->setEnabled(FALSE); + break; + } + } + else + { + play_btn->setVisible(FALSE); + pause_btn->setVisible(FALSE); + media_stop_btn->setVisible(FALSE); + if(result == LLPluginClassMediaOwner::MEDIA_LOADING) + { + reload_btn->setEnabled(FALSE); + reload_btn->setVisible(FALSE); + stop_btn->setEnabled(TRUE); + stop_btn->setVisible(TRUE); + } + else + { + reload_btn->setEnabled(TRUE); + reload_btn->setVisible(TRUE); + stop_btn->setEnabled(FALSE); + stop_btn->setVisible(FALSE); + } + } + } + media_focused_panel->setVisible(mMediaFocus); + media_hover_panel->setVisible(!mMediaFocus); + + if(media_plugin == NULL) + // Handle Scrolling + switch (mScrollState) + { + case SCROLL_UP: + media_plugin->scrollEvent(0, -1, MASK_NONE); + break; + case SCROLL_DOWN: + media_plugin->scrollEvent(0, 1, MASK_NONE); + break; + case SCROLL_LEFT: + mMediaImpl->handleKeyHere(KEY_LEFT, MASK_NONE); + break; + case SCROLL_RIGHT: + mMediaImpl->handleKeyHere(KEY_RIGHT, MASK_NONE); + break; + case SCROLL_NONE: + default: + break; + } + LLBBox screen_bbox; + setVisible(TRUE); + glh::matrix4f mat = glh_get_current_projection()*glh_get_current_modelview(); + std::vector<LLVector3>::iterator vert_it; + std::vector<LLVector3>::iterator vert_end; + std::vector<LLVector3> vect_face; + + LLVolume* volume = objectp->getVolume(); + + if (volume) + { + const LLVolumeFace& vf = volume->getVolumeFace(nodep->getLastSelectedTE()); + + const LLVector3* ext = vf.mExtents; + + LLVector3 center = (ext[0]+ext[1])*0.5f; + LLVector3 size = (ext[1]-ext[0])*0.5f; + LLVector3 vert[] = + { + center + size.scaledVec(LLVector3(1,1,1)), + center + size.scaledVec(LLVector3(-1,1,1)), + center + size.scaledVec(LLVector3(1,-1,1)), + center + size.scaledVec(LLVector3(-1,-1,1)), + center + size.scaledVec(LLVector3(1,1,-1)), + center + size.scaledVec(LLVector3(-1,1,-1)), + center + size.scaledVec(LLVector3(1,-1,-1)), + center + size.scaledVec(LLVector3(-1,-1,-1)), + }; + + LLVOVolume* vo = (LLVOVolume*) objectp; + + for (U32 i = 0; i < 8; i++) + { + vect_face.push_back(vo->volumePositionToAgent(vert[i])); + } + } + vert_it = vect_face.begin(); + vert_end = vect_face.end(); + + LLVector3 min = LLVector3(1,1,1); + LLVector3 max = LLVector3(-1,-1,-1); + for(; vert_it != vert_end; ++vert_it) + { + // project silhouette vertices into screen space + glh::vec3f screen_vert = glh::vec3f(vert_it->mV); + mat.mult_matrix_vec(screen_vert); + + // add to screenspace bounding box + update_min_max(min, max, LLVector3(screen_vert.v)); + } + + LLCoordGL screen_min; + screen_min.mX = llround((F32)gViewerWindow->getWindowWidth() * (min.mV[VX] + 1.f) * 0.5f); + screen_min.mY = llround((F32)gViewerWindow->getWindowHeight() * (min.mV[VY] + 1.f) * 0.5f); + + LLCoordGL screen_max; + screen_max.mX = llround((F32)gViewerWindow->getWindowWidth() * (max.mV[VX] + 1.f) * 0.5f); + screen_max.mY = llround((F32)gViewerWindow->getWindowHeight() * (max.mV[VY] + 1.f) * 0.5f); + + // grow panel so that screenspace bounding box fits inside "media_region" element of HUD + LLRect media_hud_rect; + getParent()->screenRectToLocal(LLRect(screen_min.mX, screen_max.mY, screen_max.mX, screen_min.mY), &media_hud_rect); + LLView* media_region = getChild<LLView>("media_region"); + media_hud_rect.mLeft -= media_region->getRect().mLeft; + media_hud_rect.mBottom -= media_region->getRect().mBottom; + media_hud_rect.mTop += getRect().getHeight() - media_region->getRect().mTop; + media_hud_rect.mRight += getRect().getWidth() - media_region->getRect().mRight; + + + LLRect old_hud_rect = media_hud_rect; + // keep all parts of HUD on-screen + media_hud_rect.intersectWith(getParent()->getLocalRect()); + + // If we had to clip the rect, don't display the border + childSetVisible("bg_image", false); + + // clamp to minimum size, keeping centered + media_hud_rect.setCenterAndSize(media_hud_rect.getCenterX(), media_hud_rect.getCenterY(), + llmax(MIN_HUD_WIDTH, media_hud_rect.getWidth()), llmax(MIN_HUD_HEIGHT, media_hud_rect.getHeight())); + + userSetShape(media_hud_rect); + + // Test mouse position to see if the cursor is stationary + LLCoordWindow cursor_pos_window; + getWindow()->getCursorPosition(&cursor_pos_window); + + // If last pos is not equal to current pos, the mouse has moved + // We need to reset the timer, and make sure the panel is visible + if(cursor_pos_window.mX != mLastCursorPos.mX || + cursor_pos_window.mY != mLastCursorPos.mY || + mScrollState != SCROLL_NONE) + { + mMouseMoveTimer.start(); + mLastCursorPos = cursor_pos_window; + } + + // Mouse has been stationary, but not for long enough to fade the UI + if(mMouseMoveTimer.getElapsedTimeF32() < mMouseInactiveTime) + { + // If we have started fading, reset the alpha values + if(mFadeTimer.getStarted()) + { + F32 alpha = 1.0f; + setAlpha(alpha); + mFadeTimer.stop(); + } + } + // If we need to start fading the UI (and we have not already started) + else if(! mFadeTimer.getStarted()) + { + mFadeTimer.reset(); + mFadeTimer.start(); + } + } +} +/*virtual*/ +void LLPanelMediaHUD::draw() +{ + if(mFadeTimer.getStarted()) + { + if(mFadeTimer.getElapsedTimeF32() >= mControlFadeTime) + { + setVisible(FALSE); + } + else + { + F32 time = mFadeTimer.getElapsedTimeF32(); + F32 alpha = llmax(lerp(1.0, 0.0, time / mControlFadeTime), 0.0f); + setAlpha(alpha); + } + } + LLPanel::draw(); +} +void LLPanelMediaHUD::setAlpha(F32 alpha) +{ + LLViewQuery query; + + LLView* query_view = mMediaFocus ? getChildView("media_focused_controls") : getChildView("media_hover_controls"); + child_list_t children = query(query_view); + for (child_list_iter_t child_iter = children.begin(); + child_iter != children.end(); ++child_iter) + { + LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(*child_iter); + if (ctrl) + ctrl->setAlpha(alpha); + } + + LLPanel::setAlpha(alpha); +} +BOOL LLPanelMediaHUD::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); +} +bool LLPanelMediaHUD::isMouseOver() +{ + if( ! getVisible() ) + { + return false; + } + LLRect screen_rect; + LLCoordWindow cursor_pos_window; + getWindow()->getCursorPosition(&cursor_pos_window); + + localRectToScreen(getLocalRect(), &screen_rect); + // screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); + + if(screen_rect.pointInRect(cursor_pos_window.mX, cursor_pos_window.mY)) + { + return true; + } + return false; +} + +//static +void LLPanelMediaHUD::onClickClose(void* user_data) +{ + LLViewerMediaFocus::getInstance()->setFocusFace(FALSE, NULL, 0, NULL); + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if(this_panel->mCurrentZoom != ZOOM_NONE) + { + // gAgent.setFocusOnAvatar(TRUE, ANIMATE); + this_panel->mCurrentZoom = ZOOM_NONE; + } + this_panel->setVisible(FALSE); + +} + +//static +void LLPanelMediaHUD::onClickBack(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia()) + { + if(this_panel->mMediaImpl->getMediaPlugin()->pluginSupportsMediaTime()) + { + this_panel->mMediaImpl->getMediaPlugin()->start(-2.0); + } + else + { + this_panel->mMediaImpl->getMediaPlugin()->browse_back(); + } + + } +} +//static +void LLPanelMediaHUD::onClickForward(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia()) + { + if(this_panel->mMediaImpl->getMediaPlugin()->pluginSupportsMediaTime()) + { + this_panel->mMediaImpl->getMediaPlugin()->start(2.0); + } + else + { + this_panel->mMediaImpl->getMediaPlugin()->browse_forward(); + } + } +} +//static +void LLPanelMediaHUD::onClickHome(void* user_data) +{ + //LLViewerMedia::navigateHome(); + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if(this_panel->mMediaImpl.notNull()) + { + this_panel->mMediaImpl->navigateHome(); + } +} +//static +void LLPanelMediaHUD::onClickOpen(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if(this_panel->mMediaImpl.notNull()) + { + LLWeb::loadURL(this_panel->mMediaImpl->getMediaURL()); + } +} +//static +void LLPanelMediaHUD::onClickReload(void* user_data) +{ + //LLViewerMedia::navigateHome(); + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if(objectp && this_panel->mMediaImpl.notNull()) + { + this_panel->mMediaImpl->navigateTo(objectp->getMediaURL()); + } +} +//static +void LLPanelMediaHUD::onClickPlay(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia()) + { + this_panel->mMediaImpl->getMediaPlugin()->start(); + } +} +//static +void LLPanelMediaHUD::onClickPause(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia()) + { + this_panel->mMediaImpl->getMediaPlugin()->pause(); + } +} +//static +void LLPanelMediaHUD::onClickStop(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if (this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia()) + { + if(this_panel->mMediaImpl->getMediaPlugin()->pluginSupportsMediaTime()) + { + this_panel->mMediaImpl->getMediaPlugin()->stop(); + } + else + { + this_panel->mMediaImpl->getMediaPlugin()->browse_stop(); + } + } +} +//static +void LLPanelMediaHUD::onClickZoom(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + this_panel->nextZoomLevel(); +} +void LLPanelMediaHUD::nextZoomLevel() +{ + F32 zoom_padding = 0.0f; + S32 last_zoom_level = (S32)mCurrentZoom; + mCurrentZoom = (EZoomLevel)((last_zoom_level + 1) % (S32)ZOOM_END); + + switch (mCurrentZoom) + { + case ZOOM_NONE: + { + gAgent.setFocusOnAvatar(TRUE, ANIMATE); + break; + } + case ZOOM_MEDIUM: + { + zoom_padding = ZOOM_MEDIUM_PADDING; + break; + } + default: + { + gAgent.setFocusOnAvatar(TRUE, ANIMATE); + break; + } + } + + if (zoom_padding > 0.0f) + LLViewerMediaFocus::getInstance()->setCameraZoom(zoom_padding); +} +void LLPanelMediaHUD::onScrollUp(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if(this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia()) + { + this_panel->mMediaImpl->getMediaPlugin()->scrollEvent(0, -1, MASK_NONE); + } +} +void LLPanelMediaHUD::onScrollUpHeld(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + this_panel->mScrollState = SCROLL_UP; +} +void LLPanelMediaHUD::onScrollRight(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if(this_panel->mMediaImpl.notNull()) + { + this_panel->mMediaImpl->handleKeyHere(KEY_RIGHT, MASK_NONE); + } +} +void LLPanelMediaHUD::onScrollRightHeld(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + this_panel->mScrollState = SCROLL_RIGHT; +} + +void LLPanelMediaHUD::onScrollLeft(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if(this_panel->mMediaImpl.notNull()) + { + this_panel->mMediaImpl->handleKeyHere(KEY_LEFT, MASK_NONE); + } +} +void LLPanelMediaHUD::onScrollLeftHeld(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + this_panel->mScrollState = SCROLL_LEFT; +} + +void LLPanelMediaHUD::onScrollDown(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + if(this_panel->mMediaImpl.notNull() && this_panel->mMediaImpl->hasMedia()) + { + this_panel->mMediaImpl->getMediaPlugin()->scrollEvent(0, 1, MASK_NONE); + } +} +void LLPanelMediaHUD::onScrollDownHeld(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + this_panel->mScrollState = SCROLL_DOWN; +} + +void LLPanelMediaHUD::onScrollStop(void* user_data) +{ + LLPanelMediaHUD* this_panel = static_cast<LLPanelMediaHUD*> (user_data); + this_panel->mScrollState = SCROLL_NONE; +} diff --git a/linden/indra/newview/llpanelmediahud.h b/linden/indra/newview/llpanelmediahud.h new file mode 100644 index 000000000..5f12ebcc5 --- /dev/null +++ b/linden/indra/newview/llpanelmediahud.h @@ -0,0 +1,110 @@ +/** + * @file llpanelmediahud.h + * @brief Media hud panel + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_PANELMEDIAHUD_H +#define LL_PANELMEDIAHUD_H + +#include "llpanel.h" +#include "llviewermedia.h" + +class LLCoordWindow; +class LLViewerMediaImpl; + +class LLPanelMediaHUD : public LLPanel +{ +public: + LLPanelMediaHUD(viewer_media_t media_impl); + virtual ~LLPanelMediaHUD(); + /*virtual*/ BOOL postBuild(); + virtual void draw(); + virtual void setAlpha(F32 alpha); + virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + void updateShape(); + bool isMouseOver(); + void setMediaFocus(bool b) { mMediaFocus = b; } + void nextZoomLevel(); + void resetZoomLevel() { mCurrentZoom = ZOOM_NONE; } + + LLHandle<LLPanelMediaHUD> getHandle() const { return mPanelHandle; } + void setMediaImpl(viewer_media_t media_impl) { mMediaImpl = media_impl; } + + + enum EZoomLevel + { + ZOOM_NONE = 0, + ZOOM_MEDIUM = 1, + ZOOM_END + }; + enum EScrollDir + { + SCROLL_UP = 0, + SCROLL_DOWN, + SCROLL_LEFT, + SCROLL_RIGHT, + SCROLL_NONE + }; + +private: + static void onClickClose(void* user_data); + static void onClickBack(void* user_data); + static void onClickForward(void* user_data); + static void onClickHome(void* user_data); + static void onClickOpen(void* user_data); + static void onClickReload(void* user_data); + static void onClickPlay(void* user_data); + static void onClickPause(void* user_data); + static void onClickStop(void* user_data); + static void onClickZoom(void* user_data); + static void onScrollUp(void* user_data); + static void onScrollUpHeld(void* user_data); + static void onScrollLeft(void* user_data); + static void onScrollLeftHeld(void* user_data); + static void onScrollRight(void* user_data); + static void onScrollRightHeld(void* user_data); + static void onScrollDown(void* user_data); + static void onScrollDownHeld(void* user_data); + static void onScrollStop(void* user_data); + + bool mMediaFocus; + LLMatrix4 mLastCameraMat; + EZoomLevel mCurrentZoom; + EScrollDir mScrollState; + LLCoordWindow mLastCursorPos; + LLFrameTimer mMouseMoveTimer; + LLFrameTimer mFadeTimer; + F32 mMouseInactiveTime; + F32 mControlFadeTime; + viewer_media_t mMediaImpl; + LLRootHandle<LLPanelMediaHUD> mPanelHandle; +}; + +#endif // LL_PANELMEDIAHUD_H diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp index fc0574425..6b318e08a 100644 --- a/linden/indra/newview/llpanelpermissions.cpp +++ b/linden/indra/newview/llpanelpermissions.cpp @@ -277,7 +277,7 @@ void LLPanelPermissions::refresh() BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsModify()) || LLSelectMgr::getInstance()->selectGetModify(); - const LLView* keyboard_focus_view = gFocusMgr.getKeyboardFocus(); + const LLFocusableElement* keyboard_focus_view = gFocusMgr.getKeyboardFocus(); S32 string_index = 0; std::string MODIFY_INFO_STRINGS[] = { diff --git a/linden/indra/newview/llpanelweb.cpp b/linden/indra/newview/llpanelweb.cpp index 38bb2d7b0..e2933f089 100644 --- a/linden/indra/newview/llpanelweb.cpp +++ b/linden/indra/newview/llpanelweb.cpp @@ -38,50 +38,23 @@ // project includes #include "llcheckboxctrl.h" #include "hippoGridManager.h" -#include "llmediamanager.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" +#include "llviewermedia.h" #include "llviewerwindow.h" +#include "llpluginclassmedia.h" // helper functions for getting/freeing the web browser media // if creating/destroying these is too slow, we'll need to create // a static member and update all our static callbacks -LLMediaBase *get_web_media() +viewer_media_t get_web_media() { - LLMediaBase *media_source; - LLMediaManager *mgr = LLMediaManager::getInstance(); - - if (!mgr) - { - llwarns << "cannot get media manager" << llendl; - return NULL; - } - media_source = mgr->createSourceFromMimeType("http", "text/html" ); - if ( !media_source ) - { - llwarns << "media source create failed " << llendl; - return NULL; - } + viewer_media_t media_source = LLViewerMedia::newMediaImpl("", LLUUID::null, 0, 0, 0, 0, "text/html"); return media_source; } -void free_web_media(LLMediaBase *media_source) -{ - if (!media_source) - return; - - LLMediaManager *mgr = LLMediaManager::getInstance(); - if (!mgr) - { - llwarns << "cannot get media manager" << llendl; - return; - } - - mgr->destroySource(media_source); -} - LLPanelWeb::LLPanelWeb() { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_web.xml"); @@ -144,17 +117,16 @@ void LLPanelWeb::apply() bool value = childGetValue("use_external_browser").asString() == "external" ? true : false; gSavedSettings.setBOOL("UseExternalBrowser", value); - LLMediaBase *media_source = get_web_media(); - if (media_source) + viewer_media_t media_source = get_web_media(); + if (media_source && media_source->hasMedia()) { - media_source->enableCookies(childGetValue("cookies_enabled")); + media_source->getMediaPlugin()->enable_cookies(childGetValue("cookies_enabled")); bool proxy_enable = childGetValue("web_proxy_enabled"); std::string proxy_address = childGetValue("web_proxy_editor"); int proxy_port = childGetValue("web_proxy_port"); - media_source->enableProxy(proxy_enable, proxy_address, proxy_port); + media_source->getMediaPlugin()->proxy_setup(proxy_enable, proxy_address, proxy_port); } - free_web_media(media_source); } void LLPanelWeb::cancel() @@ -173,10 +145,9 @@ bool LLPanelWeb::callback_clear_browser_cache(const LLSD& notification, const LL S32 option = LLNotification::getSelectedOption(notification, response); if ( option == 0 ) // YES { - LLMediaBase *media_source = get_web_media(); - if (media_source) - media_source->clearCache(); - free_web_media(media_source); + viewer_media_t media_source = get_web_media(); + if (media_source && media_source->hasMedia()) + media_source->getMediaPlugin()->clear_cache(); } return false; } @@ -193,10 +164,9 @@ bool LLPanelWeb::callback_clear_cookies(const LLSD& notification, const LLSD& re S32 option = LLNotification::getSelectedOption(notification, response); if ( option == 0 ) // YES { - LLMediaBase *media_source = get_web_media(); - if (media_source) - media_source->clearCookies(); - free_web_media(media_source); + viewer_media_t media_source = get_web_media(); + if (media_source && media_source->hasMedia()) + media_source->getMediaPlugin()->clear_cookies(); } return false; } @@ -209,10 +179,9 @@ void LLPanelWeb::onCommitCookies(LLUICtrl* ctrl, void* data) if (!self || !check) return; - LLMediaBase *media_source = get_web_media(); - if (media_source) - media_source->enableCookies(check->get()); - free_web_media(media_source); + viewer_media_t media_source = get_web_media(); + if (media_source && media_source->hasMedia()) + media_source->getMediaPlugin()->enable_cookies(check->get()); } // static void LLPanelWeb::onCommitWebProxyEnabled(LLUICtrl* ctrl, void* data) diff --git a/linden/indra/newview/llprefsvoice.cpp b/linden/indra/newview/llprefsvoice.cpp index fe5446ba2..609d30a13 100644 --- a/linden/indra/newview/llprefsvoice.cpp +++ b/linden/indra/newview/llprefsvoice.cpp @@ -153,8 +153,8 @@ void LLPrefsVoice::apply() if (enable_voice && !gSavedSettings.getBOOL("VivoxLicenseAccepted")) { // This window enables voice chat if license is accepted - FloaterVoiceLicense::getInstance()->open(); - FloaterVoiceLicense::getInstance()->center(); +//imprudence fixme FloaterVoiceLicense::getInstance()->open(); +//imprudence fixme FloaterVoiceLicense::getInstance()->center(); } else { diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp index d8c3aa914..737d71228 100644 --- a/linden/indra/newview/llpreviewscript.cpp +++ b/linden/indra/newview/llpreviewscript.cpp @@ -81,7 +81,7 @@ #include "llviewertexteditor.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" -#include "llwebbrowserctrl.h" +#include "llmediactrl.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" @@ -360,7 +360,7 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) // update back and forward buttons LLButton* fwd_button = help_floater->getChild<LLButton>("fwd_btn"); LLButton* back_button = help_floater->getChild<LLButton>("back_btn"); - LLWebBrowserCtrl* browser = help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html"); + LLMediaCtrl* browser = help_floater->getChild<LLMediaCtrl>("lsl_guide_html"); back_button->setEnabled(browser->canNavigateBack()); fwd_button->setEnabled(browser->canNavigateForward()); @@ -419,7 +419,7 @@ void LLScriptEdCore::setHelpPage(const std::string& help_string) LLFloater* help_floater = mLiveHelpHandle.get(); if (!help_floater) return; - LLWebBrowserCtrl* web_browser = help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html"); + LLMediaCtrl* web_browser = help_floater->getChild<LLMediaCtrl>("lsl_guide_html"); if (!web_browser) return; LLComboBox* history_combo = help_floater->getChild<LLComboBox>("history_combo"); @@ -592,7 +592,7 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) live_help_floater->childSetAction("back_btn", onClickBack, userdata); live_help_floater->childSetAction("fwd_btn", onClickForward, userdata); - LLWebBrowserCtrl* browser = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html"); + LLMediaCtrl* browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html"); browser->setAlwaysRefresh(TRUE); LLComboBox* help_combo = live_help_floater->getChild<LLComboBox>("history_combo"); @@ -621,7 +621,7 @@ void LLScriptEdCore::onClickBack(void* userdata) LLFloater* live_help_floater = corep->mLiveHelpHandle.get(); if (live_help_floater) { - LLWebBrowserCtrl* browserp = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html"); + LLMediaCtrl* browserp = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html"); if (browserp) { browserp->navigateBack(); @@ -636,7 +636,7 @@ void LLScriptEdCore::onClickForward(void* userdata) LLFloater* live_help_floater = corep->mLiveHelpHandle.get(); if (live_help_floater) { - LLWebBrowserCtrl* browserp = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html"); + LLMediaCtrl* browserp = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html"); if (browserp) { browserp->navigateForward(); @@ -678,7 +678,7 @@ void LLScriptEdCore::onHelpComboCommit(LLUICtrl* ctrl, void* userdata) corep->addHelpItemToHistory(help_string); - LLWebBrowserCtrl* web_browser = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html"); + LLMediaCtrl* web_browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html"); LLUIString url_string = gSavedSettings.getString("LSLHelpURL"); url_string.setArg("[APP_DIRECTORY]", gDirUtilp->getWorkingDir()); url_string.setArg("[LSL_STRING]", help_string); diff --git a/linden/indra/newview/llpreviewsound.cpp b/linden/indra/newview/llpreviewsound.cpp index 26d8da5a6..0dd65ab0e 100644 --- a/linden/indra/newview/llpreviewsound.cpp +++ b/linden/indra/newview/llpreviewsound.cpp @@ -32,7 +32,7 @@ #include "llviewerprecompiledheaders.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "llagent.h" // gAgent #include "llbutton.h" #include "llinventory.h" diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index 83abcf439..558d27835 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -59,6 +59,7 @@ #include "llfloaterreporter.h" #include "llfloatertools.h" #include "llframetimer.h" +#include "llfocusmgr.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llinventorymodel.h" @@ -74,6 +75,8 @@ #include "llviewercamera.h" #include "llviewercontrol.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" +#include "llviewermediafocus.h" #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -4875,7 +4878,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) if (mSelectedObjects->getNumNodes()) { LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID(); - + LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getSelectedUUID(); for (S32 pass = 0; pass < 2; pass++) { for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); @@ -4889,7 +4892,11 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) { continue; } - if(objectp->getID() == inspect_item_id) + if (objectp->getID() == focus_item_id) + { + node->renderOneSilhouette(gFocusMgr.getFocusColor()); + } + else if(objectp->getID() == inspect_item_id) { node->renderOneSilhouette(sHighlightInspectColor); } diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 4fd4daa1f..87d48c840 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -40,14 +40,15 @@ # include <sys/stat.h> // mkdir() #endif -#include "audioengine.h" +#include "llviewermedia_streamingaudio.h" +#include "llaudioengine.h" #ifdef LL_FMOD -# include "audioengine_fmod.h" +# include "llaudioengine_fmod.h" #endif #ifdef LL_OPENAL -#include "audioengine_openal.h" +#include "llaudioengine_openal.h" #endif #include "llares.h" @@ -100,6 +101,7 @@ #include "llfloatergesture.h" #include "llfloaterhud.h" #include "llfloaterland.h" +#include "llfloaterteleporthistory.h" #include "llfloatertopobjects.h" #include "llfloatertos.h" #include "llfloaterworldmap.h" @@ -191,12 +193,6 @@ #include "jcfloater_animation_list.h" #include "jcfloaterareasearch.h" -#include "llfloaterteleporthistory.h" - -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED - #if LL_WINDOWS #include "llwindebug.h" #include "lldxhardware.h" @@ -675,6 +671,16 @@ bool idle_startup() delete gAudiop; gAudiop = NULL; } + + if (gAudiop) + { + // if the audio engine hasn't set up its own preferred handler for streaming audio then set up the generic streaming audio implementation which uses media plugins + if (NULL == gAudiop->getStreamingAudioImpl()) + { + LL_INFOS("AppInit") << "Using media plugins to render streaming audio" << LL_ENDL; + gAudiop->setStreamingAudioImpl(new LLStreamingAudio_MediaPlugins()); + } + } } } @@ -760,7 +766,7 @@ bool idle_startup() std::string msg = LLTrans::getString("LoginInitializingBrowser"); set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str()); display_startup(); - LLViewerMedia::initBrowser(); + // LLViewerMedia::initBrowser(); LLStartUp::setStartupState( STATE_LOGIN_SHOW ); return FALSE; @@ -2234,6 +2240,8 @@ bool idle_startup() LLStringUtil::truncate(gWindowTitle, 255); gViewerWindow->getWindow()->setWindowTitle(gWindowTitle); } + // Inform simulator of our language preference + LLAgentLanguage::update(); // unpack thin inventory LLUserAuth::options_t options; @@ -2553,9 +2561,6 @@ bool idle_startup() // JC - 7/20/2002 gViewerWindow->sendShapeToSim(); - // Inform simulator of our language preference - LLAgentLanguage::update(); - // Ignore stipend information for now. Money history is on the web site. // if needed, show the L$ history window @@ -3824,7 +3829,7 @@ void LLStartUp::multimediaInit() set_startup_status(0.42f, msg.c_str(), gAgent.mMOTD.c_str()); display_startup(); - LLViewerMedia::initClass(); + //LLViewerMedia::initClass(); LLViewerParcelMedia::initClass(); } @@ -3833,7 +3838,7 @@ bool LLStartUp::dispatchURL() // ok, if we've gotten this far and have a startup URL if (!sSLURLCommand.empty()) { - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; const bool trusted_browser = false; LLURLDispatcher::dispatch(sSLURLCommand, web, trusted_browser); } @@ -3851,7 +3856,7 @@ bool LLStartUp::dispatchURL() || (dy*dy > SLOP*SLOP) ) { std::string url = LLURLSimString::getURL(); - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; const bool trusted_browser = false; LLURLDispatcher::dispatch(url, web, trusted_browser); } diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp index 366363b0a..d08d3daa4 100644 --- a/linden/indra/newview/llstatusbar.cpp +++ b/linden/indra/newview/llstatusbar.cpp @@ -857,7 +857,7 @@ class LLBalanceHandler : public LLCommandHandler public: // Requires "trusted" browser/URL source LLBalanceHandler() : LLCommandHandler("balance", true) { } - bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web) + bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { if (tokens.size() == 1 && tokens[0].asString() == "request") diff --git a/linden/indra/newview/lltoolcomp.cpp b/linden/indra/newview/lltoolcomp.cpp index b6090bc98..16e0136b8 100644 --- a/linden/indra/newview/lltoolcomp.cpp +++ b/linden/indra/newview/lltoolcomp.cpp @@ -766,10 +766,6 @@ void LLToolCompGun::onMouseCaptureLost() return; } mCur->onMouseCaptureLost(); - - // JC - I don't know if this is necessary. Maybe we could lose capture - // if someone ALT-Tab's out when in mouselook. - setCurrentTool( (LLTool*) mGun ); } void LLToolCompGun::handleSelect() diff --git a/linden/indra/newview/lltoolcomp.h b/linden/indra/newview/lltoolcomp.h index b24ba25d5..81ed0ba8e 100644 --- a/linden/indra/newview/lltoolcomp.h +++ b/linden/indra/newview/lltoolcomp.h @@ -229,6 +229,7 @@ class LLToolCompGun : public LLToolComposite, public LLSingleton<LLToolCompGun> virtual void onMouseCaptureLost(); virtual void handleSelect(); virtual void handleDeselect(); + virtual LLTool* getOverrideTool(MASK mask) { return NULL; } protected: LLToolGun* mGun; diff --git a/linden/indra/newview/lltoolgun.cpp b/linden/indra/newview/lltoolgun.cpp index d21fd4964..f7af01870 100644 --- a/linden/indra/newview/lltoolgun.cpp +++ b/linden/indra/newview/lltoolgun.cpp @@ -49,7 +49,8 @@ #include "lltoolgrab.h" LLToolGun::LLToolGun( LLToolComposite* composite ) -: LLTool( std::string("gun"), composite ) +: LLTool( std::string("gun"), composite ), + mIsSelected(FALSE) { } @@ -58,6 +59,7 @@ void LLToolGun::handleSelect() gViewerWindow->hideCursor(); gViewerWindow->moveCursorToCenter(); gViewerWindow->mWindow->setMouseClipping(TRUE); + mIsSelected = TRUE; } void LLToolGun::handleDeselect() @@ -65,6 +67,7 @@ void LLToolGun::handleDeselect() gViewerWindow->moveCursorToCenter(); gViewerWindow->showCursor(); gViewerWindow->mWindow->setMouseClipping(FALSE); + mIsSelected = FALSE; } BOOL LLToolGun::handleMouseDown(S32 x, S32 y, MASK mask) @@ -77,7 +80,7 @@ BOOL LLToolGun::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) { - if( gAgent.cameraMouselook() ) + if( gAgent.cameraMouselook() && mIsSelected ) { const F32 NOMINAL_MOUSE_SENSITIVITY = 0.0025f; diff --git a/linden/indra/newview/lltoolgun.h b/linden/indra/newview/lltoolgun.h index 4e945d796..4644e686b 100644 --- a/linden/indra/newview/lltoolgun.h +++ b/linden/indra/newview/lltoolgun.h @@ -52,6 +52,8 @@ class LLToolGun : public LLTool virtual LLTool* getOverrideTool(MASK mask) { return NULL; } virtual BOOL clipMouseWhenDown() { return FALSE; } +private: + BOOL mIsSelected; }; #endif diff --git a/linden/indra/newview/lltoolmgr.cpp b/linden/indra/newview/lltoolmgr.cpp index 3a776d12b..82043746e 100644 --- a/linden/indra/newview/lltoolmgr.cpp +++ b/linden/indra/newview/lltoolmgr.cpp @@ -281,22 +281,20 @@ void LLToolMgr::clearTransientTool() } -// The "gun tool", used for handling mouselook, captures the mouse and -// locks it within the window. When the app loses focus we need to -// release this locking. void LLToolMgr::onAppFocusLost() { - mSavedTool = mBaseTool; - mBaseTool = gToolNull; + if (mSelectedTool) + { + mSelectedTool->handleDeselect(); + } updateToolStatus(); } void LLToolMgr::onAppFocusGained() { - if (mSavedTool) + if (mSelectedTool) { - mBaseTool = mSavedTool; - mSavedTool = NULL; + mSelectedTool->handleSelect(); } updateToolStatus(); } diff --git a/linden/indra/newview/lltoolmorph.cpp b/linden/indra/newview/lltoolmorph.cpp index 75e19645a..6e09efa7d 100644 --- a/linden/indra/newview/lltoolmorph.cpp +++ b/linden/indra/newview/lltoolmorph.cpp @@ -37,7 +37,7 @@ #include "llrender.h" // Library includes -#include "audioengine.h" +#include "llaudioengine.h" #include "llviewercontrol.h" #include "llfontgl.h" #include "sound_ids.h" diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp index 2b63a2431..b121b1af7 100644 --- a/linden/indra/newview/lltoolpie.cpp +++ b/linden/indra/newview/lltoolpie.cpp @@ -36,11 +36,11 @@ #include "indra_constants.h" #include "llclickaction.h" -#include "llmediabase.h" // for status codes #include "llparcel.h" #include "llagent.h" #include "llviewercontrol.h" +#include "llfocusmgr.h" #include "llfirstuse.h" #include "llfloateravatarinfo.h" #include "llfloaterland.h" @@ -63,6 +63,7 @@ #include "llviewerparcelmgr.h" #include "llviewerwindow.h" #include "llviewermedia.h" +#include "llviewermediafocus.h" #include "llvoavatar.h" #include "llworld.h" #include "llui.h" @@ -72,13 +73,15 @@ extern void handle_buy(void*); extern BOOL gDebugClicks; +static bool handle_media_click(const LLPickInfo& info); +static bool handle_media_hover(const LLPickInfo& info); static void handle_click_action_play(); static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp); static ECursorType cursor_from_parcel_media(U8 click_action); LLToolPie::LLToolPie() -: LLTool(std::string("Select")), +: LLTool(std::string("Pie")), mPieMouseButtonDown( FALSE ), mGrabMouseButtonDown( FALSE ), mMouseOutsideSlop( FALSE ), @@ -110,6 +113,10 @@ BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask) return FALSE; } +BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); +} // static void LLToolPie::rightMouseCallback(const LLPickInfo& pick_info) { @@ -143,6 +150,7 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) } } + gFocusMgr.setKeyboardFocus(NULL); return LLTool::handleMouseDown(x, y, mask); } @@ -161,9 +169,11 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) parent = object->getRootEdit(); } + BOOL touchable = (object && object->flagHandleTouch()) || (parent && parent->flagHandleTouch()); + // If it's a left-click, and we have a special action, do it. if (useClickAction(always_show, mask, object, parent)) { @@ -195,6 +205,8 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting) && !gSavedSettings.getBOOL("BlockClickSit")) // agent not already sitting { handle_sit_or_stand(); + // put focus in world when sitting on an object + gFocusMgr.setKeyboardFocus(NULL); return TRUE; } // else nothing (fall through to touch) @@ -247,6 +259,14 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) } } + if (!always_show && handle_media_click(mPick)) + { + return FALSE; + } + + // put focus back "in world" + gFocusMgr.setKeyboardFocus(NULL); + // Switch to grab tool if physical or triggerable if (object && !object->isAvatar() && @@ -614,41 +634,46 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) mMouseOutsideSlop = TRUE; } */ + + gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); + LLViewerObject *object = NULL; LLViewerObject *parent = NULL; - if (gHoverView) - { - object = gViewerWindow->getHoverPick().getObject(); - } + object = gViewerWindow->getHoverPick().getObject(); if (object) { parent = object->getRootEdit(); - } - if (object && useClickAction(FALSE, mask, object, parent)) - { - ECursorType cursor = cursor_from_object(object); - gViewerWindow->getWindow()->setCursor(cursor); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; - } - else if ((object && !object->isAvatar() && object->usePhysics()) - || (parent && !parent->isAvatar() && parent->usePhysics())) - { - gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLGRAB); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; - } - else if ( (object && object->flagHandleTouch()) - || (parent && parent->flagHandleTouch())) - { - gViewerWindow->getWindow()->setCursor(UI_CURSOR_HAND); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; + if (object && useClickAction(FALSE, mask, object, parent)) + { + ECursorType cursor = cursor_from_object(object); + gViewerWindow->getWindow()->setCursor(cursor); + } + else if (handle_media_hover(gViewerWindow->getHoverPick())) + { + // cursor set by media object + } + else if ((object && !object->isAvatar() && object->usePhysics()) + || (parent && !parent->isAvatar() && parent->usePhysics())) + { + gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLGRAB); + } + else if ( (object && object->flagHandleTouch()) + || (parent && parent->flagHandleTouch())) + { + gViewerWindow->getWindow()->setCursor(UI_CURSOR_HAND); + } } else { - gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); - lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; + // We need to clear media hover flag + if (LLViewerMediaFocus::getInstance()->getMouseOverFlag()) + { + LLViewerMediaFocus::getInstance()->setMouseOverFlag(false); + } + } return TRUE; @@ -830,14 +855,14 @@ static void handle_click_action_play() LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return; - LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getStatus(); switch(status) { - case LLMediaBase::STATUS_STARTED: + case LLViewerMediaImpl::MEDIA_PLAYING: LLViewerParcelMedia::pause(); break; - case LLMediaBase::STATUS_PAUSED: + case LLViewerMediaImpl::MEDIA_PAUSED: LLViewerParcelMedia::start(); break; @@ -847,6 +872,111 @@ static void handle_click_action_play() } } +static bool handle_media_click(const LLPickInfo& pick) +{ + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + LLPointer<LLViewerObject> objectp = pick.getObject(); + + + if (!parcel || + objectp.isNull() || + pick.mObjectFace < 0 || + pick.mObjectFace >= objectp->getNumTEs()) + { + LLSelectMgr::getInstance()->deselect(); + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; + } + + + + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + + // is media playing on this face? + const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); + + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID()); + if (tep + && media_impl.notNull() + && media_impl->hasMedia() + && gSavedSettings.getBOOL("MediaOnAPrimUI")) + { + LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection(); + if (! selection->contains(pick.getObject(), pick.mObjectFace)) + { + LLViewerMediaFocus::getInstance()->setFocusFace(TRUE, pick.getObject(), pick.mObjectFace, media_impl); + } + else + { + media_impl->mouseDown(pick.mXYCoords.mX, pick.mXYCoords.mY); + media_impl->mouseCapture(); // the mouse-up will happen when capture is lost + } + + return true; + } + + LLSelectMgr::getInstance()->deselect(); + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; +} + +static bool handle_media_hover(const LLPickInfo& pick) +{ + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!parcel) return false; + + LLPointer<LLViewerObject> objectp = pick.getObject(); + + // Early out cases. Must clear mouse over media focus flag + // did not hit an object or did not hit a valid face + if ( objectp.isNull() || + pick.mObjectFace < 0 || + pick.mObjectFace >= objectp->getNumTEs() ) + { + LLViewerMediaFocus::getInstance()->setMouseOverFlag(false); + return false; + } + + + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + + // is media playing on this face? + const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID()); + if (tep + && media_impl.notNull() + && media_impl->hasMedia() + && gSavedSettings.getBOOL("MediaOnAPrimUI")) + { + if(LLViewerMediaFocus::getInstance()->getFocus()) + { + media_impl->mouseMove(pick.mXYCoords.mX, pick.mXYCoords.mY); + } + + // Set mouse over flag if unset + if (! LLViewerMediaFocus::getInstance()->getMouseOverFlag()) + { + LLSelectMgr::getInstance()->setHoverObject(objectp, pick.mObjectFace); + LLViewerMediaFocus::getInstance()->setMouseOverFlag(true, media_impl); + LLViewerMediaFocus::getInstance()->setPickInfo(pick); + } + + return true; + } + LLViewerMediaFocus::getInstance()->setMouseOverFlag(false); + + return false; +} + + static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp) { //FIXME: how do we handle object in different parcel than us? @@ -861,7 +991,7 @@ static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp) if( face < 0 || face >= objectp->getNumTEs() ) return; // is media playing on this face? - if (!LLViewerMedia::isActiveMediaTexture(objectp->getTE(face)->getID())) + if (LLViewerMedia::getMediaImplFromTextureID(objectp->getTE(face)->getID()) != NULL) { handle_click_action_play(); return; @@ -879,10 +1009,7 @@ static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp) // This can be removed when we have a truly generic media browser that only // builds an impl based on the type of url it is passed. - if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) - { - LLWeb::loadURL(media_url); - } + LLWeb::loadURL(media_url); } static ECursorType cursor_from_parcel_media(U8 click_action) @@ -900,19 +1027,12 @@ static ECursorType cursor_from_parcel_media(U8 click_action) std::string media_type = std::string ( parcel->getMediaType() ); LLStringUtil::trim(media_url); - // Get the scheme, see if that is handled as well. - LLURI uri(media_url); - std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http"; - - if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) - { - open_cursor = UI_CURSOR_TOOLMEDIAOPEN; - } + open_cursor = UI_CURSOR_TOOLMEDIAOPEN; - LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getStatus(); switch(status) { - case LLMediaBase::STATUS_STARTED: + case LLViewerMediaImpl::MEDIA_PLAYING: return click_action == CLICK_ACTION_PLAY ? UI_CURSOR_TOOLPAUSE : open_cursor; default: return UI_CURSOR_TOOLPLAY; diff --git a/linden/indra/newview/lltoolpie.h b/linden/indra/newview/lltoolpie.h index 113fba771..001886f72 100644 --- a/linden/indra/newview/lltoolpie.h +++ b/linden/indra/newview/lltoolpie.h @@ -51,6 +51,7 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie> virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual void render(); diff --git a/linden/indra/newview/lltoolplacer.cpp b/linden/indra/newview/lltoolplacer.cpp index d5c4de1e7..c031a1831 100644 --- a/linden/indra/newview/lltoolplacer.cpp +++ b/linden/indra/newview/lltoolplacer.cpp @@ -59,7 +59,7 @@ #include "llvolumemessage.h" #include "llhudmanager.h" #include "llagent.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "llhudeffecttrail.h" #include "llviewerobjectlist.h" #include "llviewercamera.h" diff --git a/linden/indra/newview/llurldispatcher.cpp b/linden/indra/newview/llurldispatcher.cpp index f9b6b39a1..1144c5827 100644 --- a/linden/indra/newview/llurldispatcher.cpp +++ b/linden/indra/newview/llurldispatcher.cpp @@ -39,7 +39,7 @@ #include "llfloaterurldisplay.h" #include "llfloaterdirectory.h" #include "llfloaterworldmap.h" -#include "llfloaterhtmlhelp.h" +#include "llfloatermediabrowser.h" #include "llpanellogin.h" #include "llstartup.h" // gStartupState #include "llurlsimstring.h" @@ -65,7 +65,7 @@ class LLURLDispatcherImpl static bool isSLURLCommand(const std::string& url); static bool dispatch(const std::string& url, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser); // returns true if handled or explicitly blocked. @@ -74,7 +74,7 @@ class LLURLDispatcherImpl private: static bool dispatchCore(const std::string& url, bool right_mouse, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser); // handles both left and right click @@ -84,7 +84,7 @@ class LLURLDispatcherImpl static bool dispatchApp(const std::string& url, bool right_mouse, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser); // Handles secondlife:///app/agent/<agent_id>/about and similar // by showing panel in Search floater. @@ -138,7 +138,7 @@ bool LLURLDispatcherImpl::isSLURLCommand(const std::string& url) // static bool LLURLDispatcherImpl::dispatchCore(const std::string& url, bool right_mouse, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser) { if (url.empty()) return false; @@ -158,7 +158,7 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url, // static bool LLURLDispatcherImpl::dispatch(const std::string& url, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser) { llinfos << "url: " << url << llendl; @@ -171,7 +171,7 @@ bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url) { llinfos << "url: " << url << llendl; const bool right_click = true; - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; const bool trusted_browser = false; return dispatchCore(url, right_click, web, trusted_browser); } @@ -192,7 +192,7 @@ bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, bool right_mouse) // static bool LLURLDispatcherImpl::dispatchApp(const std::string& url, bool right_mouse, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser) { if (!isSLURL(url)) @@ -386,7 +386,7 @@ class LLTeleportHandler : public LLCommandHandler LLTeleportHandler() : LLCommandHandler("teleport", true) { } bool handle(const LLSD& tokens, const LLSD& query_map, - LLWebBrowserCtrl* web) + LLMediaCtrl* web) { // construct a "normal" SLURL, resolve the region to // a global position, and teleport to it @@ -426,7 +426,7 @@ bool LLURLDispatcher::isSLURLCommand(const std::string& url) // static bool LLURLDispatcher::dispatch(const std::string& url, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser) { return LLURLDispatcherImpl::dispatch(url, web, trusted_browser); @@ -448,7 +448,7 @@ bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url) // click on it. // *TODO: Make this trust model more refined. JC const bool trusted_browser = true; - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; return LLURLDispatcherImpl::dispatch(url, web, trusted_browser); } diff --git a/linden/indra/newview/llurldispatcher.h b/linden/indra/newview/llurldispatcher.h index a4f6866a0..c947e5e37 100644 --- a/linden/indra/newview/llurldispatcher.h +++ b/linden/indra/newview/llurldispatcher.h @@ -32,7 +32,7 @@ #ifndef LLURLDISPATCHER_H #define LLURLDISPATCHER_H -class LLWebBrowserCtrl; +class LLMediaCtrl; class LLURLDispatcher @@ -45,7 +45,7 @@ class LLURLDispatcher // Is this a special secondlife://app/ URL? static bool dispatch(const std::string& url, - LLWebBrowserCtrl* web, + LLMediaCtrl* web, bool trusted_browser); // At startup time and on clicks in internal web browsers, // teleport, open map, or run requested command. @@ -54,7 +54,7 @@ class LLURLDispatcher // secondlife:///app/agent/3d6181b0-6a4b-97ef-18d8-722652995cf1/show // sl://app/foo/bar // @param web - // Pointer to LLWebBrowserCtrl sending URL, can be NULL + // Pointer to LLMediaCtrl sending URL, can be NULL // @param trusted_browser // True if coming inside the app AND from a brower instance // that navigates to trusted (Linden Lab) pages. diff --git a/linden/indra/newview/llvieweraudio.cpp b/linden/indra/newview/llvieweraudio.cpp index f043fb5ba..74b8e8f57 100644 --- a/linden/indra/newview/llvieweraudio.cpp +++ b/linden/indra/newview/llvieweraudio.cpp @@ -32,7 +32,7 @@ #include "llviewerprecompiledheaders.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "llagent.h" #include "llappviewer.h" #include "llvieweraudio.h" @@ -130,7 +130,6 @@ void audio_update_volume(bool force_update) gAudiop->setMasterGain ( master_volume ); gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler")); - gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance")); gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); if(wind_muted == false) diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 50224adc6..1531e6c03 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -38,7 +38,7 @@ #include "indra_constants.h" // For Listeners -#include "audioengine.h" +#include "llaudioengine.h" #include "llagent.h" #include "llconsole.h" #include "lldrawpoolterrain.h" @@ -69,7 +69,6 @@ #include "llvosurfacepatch.h" #include "llvowlsky.h" #include "llrender.h" -#include "llmediamanager.h" #include "llslider.h" #include "llfloaterchat.h" @@ -498,21 +497,6 @@ bool handleTranslateChatPrefsChanged(const LLSD& newvalue) return true; } -bool handleMediaDebugLevelChanged(const LLSD& newvalue) -{ - LLMediaManager *mgr = LLMediaManager::getInstance(); - if (mgr) - { - LLMediaBase *impl = - mgr->createSourceFromMimeType("http", "audio/mpeg"); - - if (impl) - { - impl->setDebugLevel( (LLMediaBase::EDebugLevel)newvalue.asInteger() ); - } - } - return true; -} bool handleSliderScrollWheelMultiplierChanged(const LLSD& newvalue) { @@ -674,7 +658,6 @@ void settings_setup_listeners() gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); - gSavedSettings.getControl("MediaDebugLevel")->getSignal()->connect(boost::bind(&handleMediaDebugLevelChanged, _1)); gSavedSettings.getControl("SliderScrollWheelMultiplier")->getSignal()->connect(boost::bind(&handleSliderScrollWheelMultiplierChanged, _1)); gSavedSettings.getControl("TranslateChat")->getSignal()->connect(boost::bind(&handleTranslateChatPrefsChanged, _1)); diff --git a/linden/indra/newview/llviewergesture.cpp b/linden/indra/newview/llviewergesture.cpp index 01b3c5814..7799c9947 100644 --- a/linden/indra/newview/llviewergesture.cpp +++ b/linden/indra/newview/llviewergesture.cpp @@ -34,7 +34,7 @@ #include "llviewergesture.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "lldir.h" #include "llviewerinventory.h" #include "sound_ids.h" // for testing diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp index 703d233ce..29c630b4a 100644 --- a/linden/indra/newview/llviewerimagelist.cpp +++ b/linden/indra/newview/llviewerimagelist.cpp @@ -593,7 +593,7 @@ void LLViewerImageList::updateImages(F32 max_time) llpushcallstacks ; if (!gNoRender && !gGLManager.mIsDisabled) { - LLViewerMedia::updateImagesMediaStreams(); + LLViewerMedia::updateMedia(); } llpushcallstacks ; updateImagesUpdateStats(); diff --git a/linden/indra/newview/llviewerkeyboard.cpp b/linden/indra/newview/llviewerkeyboard.cpp index 15c814829..6dd7fb506 100644 --- a/linden/indra/newview/llviewerkeyboard.cpp +++ b/linden/indra/newview/llviewerkeyboard.cpp @@ -506,7 +506,7 @@ void start_chat( EKeystate s ) void start_gesture( EKeystate s ) { if (KEYSTATE_UP == s && - !(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput())) + !(gFocusMgr.getKeyboardFocus() && dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus())->acceptsTextInput())) { if (gChatBar->getCurrentChat().empty()) { diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 6bcf8cea6..92ccf2597 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -33,687 +33,1137 @@ #include "llviewerprecompiledheaders.h" #include "llviewermedia.h" - +#include "llviewermediafocus.h" +#include "llhoverview.h" #include "llmimetypes.h" #include "llviewercontrol.h" #include "llviewerimage.h" #include "llviewerwindow.h" #include "llviewerimagelist.h" -#include "viewerversion.h" + +#include "llpluginclassmedia.h" #include "llevent.h" // LLSimpleListener -#include "llmediamanager.h" #include "lluuid.h" +#include "llkeyboard.h" -#include <boost/bind.hpp> // for SkinFolder listener -#include <boost/signal.hpp> +// Merov: Temporary definitions while porting the new viewer media code to Snowglobe +const int LEFT_BUTTON = 0; +const int RIGHT_BUTTON = 1; -// Implementation functions not exported into header file -class LLViewerMediaImpl - : public LLMediaObserver +// Move this to its own file. + +LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter() { - public: - LLViewerMediaImpl() - : mMediaSource( NULL ), - mMovieImageID(), - mMovieImageHasMips(false) - { } - - void destroyMediaSource(); - - void play(const std::string& media_url, - const std::string& mime_type, - const LLUUID& placeholder_texture_id, - S32 media_width, S32 media_height, U8 media_auto_scale, - U8 media_loop); - - void stop(); - void pause(); - void start(); - void seek(F32 time); - void setVolume(F32 volume); - LLMediaBase::EStatus getStatus(); - - /*virtual*/ void onMediaSizeChange(const EventType& event_in); - /*virtual*/ void onMediaContentsChange(const EventType& event_in); - - void updateMovieImage(const LLUUID& image_id, BOOL active); - void updateImagesMediaStreams(); - LLUUID getMediaTextureID(); - - // Internally set our desired browser user agent string, including - // the Second Life version and skin name. Used because we can - // switch skins without restarting the app. - static void updateBrowserUserAgent(); - - // Callback for when the SkinCurrent control is changed to - // switch the user agent string to indicate the new skin. - static bool handleSkinCurrentChanged(const LLSD& newvalue); + observerListType::iterator iter = mObservers.begin(); - public: + while( iter != mObservers.end() ) + { + LLViewerMediaObserver *self = *iter; + iter++; + remObserver(self); + } +} - // a single media url with some data and an impl. - LLMediaBase* mMediaSource; - LLUUID mMovieImageID; - bool mMovieImageHasMips; - std::string mMediaURL; - std::string mMimeType; - private: - void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source); -}; +/////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaEventEmitter::addObserver( LLViewerMediaObserver* observer ) +{ + if ( ! observer ) + return false; -static LLViewerMediaImpl sViewerMediaImpl; + if ( std::find( mObservers.begin(), mObservers.end(), observer ) != mObservers.end() ) + return false; -////////////////////////////////////////////////////////////////////////////////////////// + mObservers.push_back( observer ); + observer->mEmitters.push_back( this ); -void LLViewerMediaImpl::destroyMediaSource() + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaEventEmitter::remObserver( LLViewerMediaObserver* observer ) +{ + if ( ! observer ) + return false; + + mObservers.remove( observer ); + observer->mEmitters.remove(this); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// +void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLPluginClassMediaOwner::EMediaEvent event ) { - LLMediaManager* mgr = LLMediaManager::getInstance(); - if ( mMediaSource ) + observerListType::iterator iter = mObservers.begin(); + + while( iter != mObservers.end() ) { - bool was_playing = LLViewerMedia::isMediaPlaying(); - mMediaSource->remObserver(this); - mgr->destroySource( mMediaSource ); + LLViewerMediaObserver *self = *iter; + ++iter; + self->handleMediaEvent( media, event ); + } +} - // Restore the texture - updateMovieImage(LLUUID::null, was_playing); +// Move this to its own file. +LLViewerMediaObserver::~LLViewerMediaObserver() +{ + std::list<LLViewerMediaEventEmitter *>::iterator iter = mEmitters.begin(); + while( iter != mEmitters.end() ) + { + LLViewerMediaEventEmitter *self = *iter; + iter++; + self->remObserver( this ); } - mMediaSource = NULL; } -void LLViewerMediaImpl::play(const std::string& media_url, - const std::string& mime_type, - const LLUUID& placeholder_texture_id, - S32 media_width, S32 media_height, U8 media_auto_scale, - U8 media_loop) + +// Move this to its own file. +// helper class that tries to download a URL from a web site and calls a method +// on the Panel Land Media and to discover the MIME type +class LLMimeDiscoveryResponder : public LLHTTPClient::Responder { - // first stop any previously playing media - stop(); +LOG_CLASS(LLMimeDiscoveryResponder); +public: + LLMimeDiscoveryResponder( viewer_media_t media_impl) + : mMediaImpl(media_impl), + mInitialized(false) + {} + - // Save this first, as init/load below may fire events - mMovieImageID = placeholder_texture_id; - // If the mime_type passed in is different than the cached one, and - // Auto-discovery is turned OFF, replace the cached mime_type with the new one. - if(mime_type != mMimeType && - ! gSavedSettings.getBOOL("AutoMimeDiscovery")) + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) { - mMimeType = mime_type; + std::string media_type = content["content-type"].asString(); + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); } - LLURI url(media_url); - std::string scheme = url.scheme() != "" ? url.scheme() : "http"; - LLMediaManager* mgr = LLMediaManager::getInstance(); - mMediaSource = mgr->createSourceFromMimeType(scheme, mMimeType ); - if ( !mMediaSource ) + virtual void error( U32 status, const std::string& reason ) { - if (mMimeType != "none/none") + // completeAny(status, "none/none"); + } + + void completeAny(U32 status, const std::string& mime_type) + { + if(!mInitialized && ! mime_type.empty()) { - llwarns << "media source create failed " << media_url - << " type " << mMimeType - << llendl; + if (mMediaImpl->initializeMedia(mime_type)) + { + mInitialized = true; + mMediaImpl->play(); + } } - return; } - // Store the URL and Mime Type - mMediaURL = media_url; + public: + viewer_media_t mMediaImpl; + bool mInitialized; +}; +typedef std::list<LLViewerMediaImpl*> impl_list; +static impl_list sViewerMediaImplList; + +////////////////////////////////////////////////////////////////////////////////////////// +// LLViewerMedia - if ((media_width != 0) && (media_height != 0)) +////////////////////////////////////////////////////////////////////////////////////////// +// static +viewer_media_t LLViewerMedia::newMediaImpl(const std::string& media_url, + const LLUUID& texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop, + std::string mime_type) +{ + LLViewerMediaImpl* media_impl = getMediaImplFromTextureID(texture_id); + if(media_impl == NULL || texture_id.isNull()) { - mMediaSource->setRequestedMediaSize(media_width, media_height); + // Create the media impl + media_impl = new LLViewerMediaImpl(media_url, texture_id, media_width, media_height, media_auto_scale, media_loop, mime_type); + sViewerMediaImplList.push_back(media_impl); } - - mMediaSource->setLooping(media_loop); - mMediaSource->setAutoScaled(media_auto_scale); - mMediaSource->addObserver( this ); - mMediaSource->navigateTo( media_url ); - mMediaSource->addCommand(LLMediaBase::COMMAND_START); + else + { + media_impl->stop(); + media_impl->mTextureId = texture_id; + media_impl->mMediaURL = media_url; + media_impl->mMediaWidth = media_width; + media_impl->mMediaHeight = media_height; + media_impl->mMediaAutoScale = media_auto_scale; + media_impl->mMediaLoop = media_loop; + if(! media_url.empty()) + media_impl->navigateTo(media_url, mime_type, true); + } + return media_impl; } -void LLViewerMediaImpl::stop() +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::removeMedia(LLViewerMediaImpl* media) { - destroyMediaSource(); + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for(; iter != end; iter++) + { + if(media == *iter) + { + sViewerMediaImplList.erase(iter); + return; + } + } } -void LLViewerMediaImpl::pause() +////////////////////////////////////////////////////////////////////////////////////////// +// static +LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& texture_id) { - if(mMediaSource) + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for(; iter != end; iter++) { - mMediaSource->addCommand(LLMediaBase::COMMAND_PAUSE); + LLViewerMediaImpl* media_impl = *iter; + if(media_impl->getMediaTextureID() == texture_id) + { + return media_impl; + } } + return NULL; } -void LLViewerMediaImpl::start() +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getCurrentUserAgent() { - if(mMediaSource) - { - mMediaSource->addCommand(LLMediaBase::COMMAND_START); - } + // Don't use user-visible string to avoid + // punctuation and strange characters. + std::string skin_name = gSavedSettings.getString("SkinCurrent"); + + // Just in case we need to check browser differences in A/B test + // builds. + std::string channel = gSavedSettings.getString("VersionChannelName"); + + // append our magic version number string to the browser user agent id + // See the HTTP 1.0 and 1.1 specifications for allowed formats: + // http://www.ietf.org/rfc/rfc1945.txt section 10.15 + // http://www.ietf.org/rfc/rfc2068.txt section 3.8 + // This was also helpful: + // http://www.mozilla.org/build/revised-user-agent-strings.html + std::ostringstream codec; + codec << "SecondLife/"; + codec << "C64 Basic V2"; //imprudence fixme : this isn't anybodys business anyway +// codec << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; +// codec << " (" << channel << "; " << skin_name << " skin)"; +// llinfos << codec.str() << llendl; + + return codec.str(); } -void LLViewerMediaImpl::seek(F32 time) +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::updateBrowserUserAgent() { - if(mMediaSource) + std::string user_agent = getCurrentUserAgent(); + + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for(; iter != end; iter++) { - mMediaSource->seek(time); + LLViewerMediaImpl* pimpl = *iter; + if(pimpl->mMediaSource && pimpl->mMediaSource->pluginSupportsMediaBrowser()) + { + pimpl->mMediaSource->setBrowserUserAgent(user_agent); + } } + } -void LLViewerMediaImpl::setVolume(F32 volume) +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::handleSkinCurrentChanged(const LLSD& /*newvalue*/) { - if(mMediaSource) + // gSavedSettings is already updated when this function is called. + updateBrowserUserAgent(); + return true; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::textureHasMedia(const LLUUID& texture_id) +{ + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for(; iter != end; iter++) { - mMediaSource->setVolume( volume); + LLViewerMediaImpl* pimpl = *iter; + if(pimpl->getMediaTextureID() == texture_id) + { + return true; + } } + return false; } -LLMediaBase::EStatus LLViewerMediaImpl::getStatus() +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setVolume(F32 volume) { - if (mMediaSource) + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for(; iter != end; iter++) { - return mMediaSource->getStatus(); + LLViewerMediaImpl* pimpl = *iter; + pimpl->setVolume(volume); } - else +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::updateMedia() +{ + impl_list::iterator iter = sViewerMediaImplList.begin(); + impl_list::iterator end = sViewerMediaImplList.end(); + + for(; iter != end; iter++) { - return LLMediaBase::STATUS_UNKNOWN; + LLViewerMediaImpl* pimpl = *iter; + pimpl->update(); } } ////////////////////////////////////////////////////////////////////////////////////////// // static -void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active) +void LLViewerMedia::cleanupClass() { - // IF the media image hasn't changed, do nothing - if (mMovieImageID == uuid) + // This is no longer necessary, since the list is no longer smart pointers. +#if 0 + while(!sViewerMediaImplList.empty()) { - return; + sViewerMediaImplList.pop_back(); } - // If we have changed media uuid, restore the old one - if (!mMovieImageID.isNull()) +#endif +} + +////////////////////////////////////////////////////////////////////////////////////////// +// LLViewerMediaImpl +////////////////////////////////////////////////////////////////////////////////////////// +LLViewerMediaImpl::LLViewerMediaImpl(const std::string& media_url, + const LLUUID& texture_id, + S32 media_width, + S32 media_height, + U8 media_auto_scale, + U8 media_loop, + const std::string& mime_type) +: + mMediaSource( NULL ), + mMovieImageHasMips(false), + mTextureId(texture_id), + mMediaWidth(media_width), + mMediaHeight(media_height), + mMediaAutoScale(media_auto_scale), + mMediaLoop(media_loop), + mMediaURL(media_url), + mMimeType(mime_type), + mNeedsNewTexture(true), + mSuspendUpdates(false), + mVisible(true) +{ + createMediaSource(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +LLViewerMediaImpl::~LLViewerMediaImpl() +{ + if( gEditMenuHandler == this ) { - LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID ); - if (oldImage) - { - oldImage->reinit(mMovieImageHasMips); - oldImage->mIsMediaTexture = FALSE; - } - mMovieImageID.setNull(); + gEditMenuHandler = NULL; } - // If the movie is playing, set the new media image - if (active && !uuid.isNull()) + + destroyMediaSource(); + LLViewerMedia::removeMedia(this); +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type) +{ + if((mMediaSource == NULL) || (mMimeType != mime_type)) { - LLViewerImage* viewerImage = LLViewerImage::getImage( uuid ); - if( viewerImage ) + if(! initializePlugin(mime_type)) { - mMovieImageID = uuid; - // Can't use mipmaps for movies because they don't update the full image - mMovieImageHasMips = viewerImage->getUseMipMaps(); - viewerImage->reinit(FALSE); - viewerImage->mIsMediaTexture = TRUE; + LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << mime_type << LL_ENDL; + LLSD args; + args["MIME_TYPE"] = mime_type; + LLNotifications::instance().add("NoPlugin", args); + + return false; } } -} + // play(); + return (mMediaSource != NULL); +} ////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMediaImpl::updateImagesMediaStreams() +void LLViewerMediaImpl::createMediaSource() { - LLMediaManager::updateClass(); + if(! mMediaURL.empty()) + { + navigateTo(mMediaURL, mMimeType, true); + } + else if(! mMimeType.empty()) + { + initializeMedia(mMimeType); + } + } -void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source) +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::destroyMediaSource() { - int media_width = media_source->getMediaWidth(); - int media_height = media_source->getMediaHeight(); - //int media_rowspan = media_source->getMediaRowSpan(); - - // if width & height are invalid, don't bother doing anything - if ( media_width < 1 || media_height < 1 ) + mNeedsNewTexture = true; + if(! mMediaSource) + { return; + } + // Restore the texture + updateMovieImage(LLUUID::null, false); + delete mMediaSource; + mMediaSource = NULL; +} - llinfos << "initializing media placeholder" << llendl; - llinfos << "movie image id " << mMovieImageID << llendl; - - int texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); - int texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); - int texture_depth = media_source->getMediaDepth(); - - // MEDIAOPT: check to see if size actually changed before doing work - placeholder_image->destroyGLTexture(); - // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? - placeholder_image->reinit(FALSE); // probably not needed +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::setMediaType(const std::string& media_type) +{ + mMimeType = media_type; +} - // MEDIAOPT: seems insane that we actually have to make an imageraw then - // immediately discard it - LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth); - raw->clear(0x0f, 0x0f, 0x0f, 0xff); - int discard_level = 0; +////////////////////////////////////////////////////////////////////////////////////////// +/*static*/ +LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height) +{ + std::string plugin_basename = LLMIMETypes::implType(media_type); - // ask media source for correct GL image format constants - placeholder_image->setExplicitFormat(media_source->getTextureFormatInternal(), - media_source->getTextureFormatPrimary(), - media_source->getTextureFormatType()); + if(plugin_basename.empty()) + { + LL_WARNS("Media") << "Couldn't find plugin for media type " << media_type << LL_ENDL; + } + else + { + std::string launcher_name = gDirUtilp->getLLPluginLauncher(); + std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename); + std::string user_data_path = gDirUtilp->getOSUserAppDir(); + user_data_path += gDirUtilp->getDirDelimiter(); + + // See if the plugin executable exists + llstat s; + if(LLFile::stat(launcher_name, &s)) + { + LL_WARNS("Media") << "Couldn't find launcher at " << launcher_name << LL_ENDL; + } + else if(LLFile::stat(plugin_name, &s)) + { + LL_WARNS("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL; + } + else + { + LLPluginClassMedia* media_source = new LLPluginClassMedia(owner); + media_source->setSize(default_width, default_height); + if (media_source->init(launcher_name, plugin_name, false, user_data_path)) + { + return media_source; + } + else + { + LL_WARNS("Media") << "Failed to init plugin. Destroying." << LL_ENDL; + delete media_source; + } + } + } + + return NULL; +} - placeholder_image->createGLTexture(discard_level, raw); +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) +{ + if(mMediaSource) + { + // Save the previous media source's last set size before destroying it. + mMediaWidth = mMediaSource->getSetWidth(); + mMediaHeight = mMediaSource->getSetHeight(); + } + + // Always delete the old media impl first. + destroyMediaSource(); + + // and unconditionally set the mime type + mMimeType = media_type; - // placeholder_image->setExplicitFormat() - placeholder_image->setUseMipMaps(FALSE); + LLPluginClassMedia* media_source = newSourceFromMediaType(media_type, this, mMediaWidth, mMediaHeight); + + if (media_source) + { + media_source->setDisableTimeout(gSavedSettings.getBOOL("DebugPluginDisableTimeout")); + media_source->setLoop(mMediaLoop); + media_source->setAutoScale(mMediaAutoScale); + media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent()); + + mMediaSource = media_source; + return true; + } - // MEDIAOPT: set this dynamically on play/stop - placeholder_image->mIsMediaTexture = true; + return false; } +void LLViewerMediaImpl::setSize(int width, int height) +{ + mMediaWidth = width; + mMediaHeight = height; + if(mMediaSource) + { + mMediaSource->setSize(width, height); + } +} - -// virtual -void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::play() { - LLMediaBase* media_source = event_in.getSubject(); - LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); - if ((placeholder_image) && (placeholder_image->getHasGLTexture())) + // first stop any previously playing media + // stop(); + + // mMediaSource->addObserver( this ); + if(mMediaSource == NULL) { - if (placeholder_image->getUseMipMaps()) + if(!initializePlugin(mMimeType)) { - // bad image! NO MIPMAPS! - initializePlaceholderImage(placeholder_image, media_source); + // Plugin failed initialization... should assert or something + return; } + } + + // updateMovieImage(mTextureId, true); - U8* data = media_source->getMediaData(); - S32 x_pos = 0; - S32 y_pos = 0; - S32 width = media_source->getMediaWidth(); - S32 height = media_source->getMediaHeight(); - S32 data_width = media_source->getMediaDataWidth(); - S32 data_height = media_source->getMediaDataHeight(); - placeholder_image->setSubImage(data, data_width, data_height, - x_pos, y_pos, width, height); + mMediaSource->loadURI( mMediaURL ); + if(/*mMediaSource->pluginSupportsMediaTime()*/ true) + { + start(); } } +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::stop() +{ + if(mMediaSource) + { + mMediaSource->stop(); + // destroyMediaSource(); + } +} -// virtual -void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::pause() { - LLMediaBase* media_source = event_in.getSubject(); - LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); - if (placeholder_image) + if(mMediaSource) { - initializePlaceholderImage(placeholder_image, media_source); + mMediaSource->pause(); } - else +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::start() +{ + if(mMediaSource) { - llinfos << "no placeholder image" << llendl; + mMediaSource->start(); } } +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::seek(F32 time) +{ + if(mMediaSource) + { + mMediaSource->seek(time); + } +} - // Get the image we're using +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::setVolume(F32 volume) +{ + if(mMediaSource) + { + mMediaSource->setVolume(volume); + } +} - /* - // update media stream if required - LLMediaEngine* media_engine = LLMediaEngine::getInstance(); - if (media_engine) +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::focus(bool focus) +{ + if (mMediaSource) { - if ( media_engine->update() ) - { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, TRUE); - if (!media_uuid.isNull()) - { - LLViewerImage* viewerImage = getImage( media_uuid ); - if( viewerImage ) - { - LLMediaBase* renderer = media_engine->getMediaRenderer(); - if ((renderer->getTextureWidth() != viewerImage->getWidth()) || - (renderer->getTextureHeight() != viewerImage->getHeight()) || - (renderer->getTextureDepth() != viewerImage->getComponents()) || - (viewerImage->getHasGLTexture() == FALSE)) - { - // destroy existing GL image - viewerImage->destroyGLTexture(); - - // set new size - viewerImage->setSize( renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth() ); - - LLPointer<LLImageRaw> raw = new LLImageRaw(renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth()); - raw->clear(0x7f,0x7f,0x7f,0xff); - viewerImage->createGLTexture(0, raw); - } - - // Set the explicit format the instance wants - viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(), - renderer->getTextureFormatPrimary(), - renderer->getTextureFormatType(), - renderer->getTextureFormatSwapBytes()); - // This should be redundant, but just in case: - viewerImage->setUseMipMaps(FALSE); - - LLImageRaw* rawImage = media_engine->getImageRaw(); - if ( rawImage ) - { - viewerImage->setSubImage(rawImage, 0, 0, - renderer->getMediaWidth(), - renderer->getMediaHeight()); - } - } - else - { - llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl; - } - } - } - else + // call focus just for the hell of it, even though this apopears to be a nop + mMediaSource->focus(focus); + if (focus) { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, FALSE); + // spoof a mouse click to *actually* pass focus + // Don't do this anymore -- it actually clicks through now. +// mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, 1, 1, 0); +// mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 1, 1, 0); } } - */ - +} -LLUUID LLViewerMediaImpl::getMediaTextureID() +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseDown(S32 x, S32 y) { - return mMovieImageID; + scaleMouse(&x, &y); + mLastMouseX = x; + mLastMouseY = y; + if (mMediaSource) + { + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, LEFT_BUTTON, x, y, 0); + } } -// static -void LLViewerMediaImpl::updateBrowserUserAgent() +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseUp(S32 x, S32 y) { - // Don't use user-visible string to avoid - // punctuation and strange characters. - std::string skin_name = gSavedSettings.getString("SkinCurrent"); - - // Just in case we need to check browser differences in A/B test - // builds. - std::string channel = gSavedSettings.getString("VersionChannelName"); - - // append our magic version number string to the browser user agent id - // See the HTTP 1.0 and 1.1 specifications for allowed formats: - // http://www.ietf.org/rfc/rfc1945.txt section 10.15 - // http://www.ietf.org/rfc/rfc2068.txt section 3.8 - // This was also helpful: - // http://www.mozilla.org/build/revised-user-agent-strings.html - std::ostringstream codec; - codec << "SecondLife/"; - codec << ViewerVersion::getLLMajorVersion() << "." << ViewerVersion::getLLMinorVersion() << "." << ViewerVersion::getLLPatchVersion() << "." << ViewerVersion::getLLBuildVersion(); - codec << " (" << channel << "; " << skin_name << " skin)"; - llinfos << codec.str() << llendl; - LLMediaManager::setBrowserUserAgent( codec.str() ); + scaleMouse(&x, &y); + mLastMouseX = x; + mLastMouseY = y; + if (mMediaSource) + { + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, LEFT_BUTTON, x, y, 0); + } } -// static -bool LLViewerMediaImpl::handleSkinCurrentChanged(const LLSD& /*newvalue*/) +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseMove(S32 x, S32 y) { - // gSavedSettings is already updated when this function is called. - updateBrowserUserAgent(); - return true; + scaleMouse(&x, &y); + mLastMouseX = x; + mLastMouseY = y; + if (mMediaSource) + { + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, LEFT_BUTTON, x, y, 0); + } } ////////////////////////////////////////////////////////////////////////////////////////// -// Wrapper class +void LLViewerMediaImpl::mouseLeftDoubleClick(S32 x, S32 y) +{ + scaleMouse(&x, &y); + mLastMouseX = x; + mLastMouseY = y; + if (mMediaSource) + { + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOUBLE_CLICK, LEFT_BUTTON, x, y, 0); + } +} + ////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::onMouseCaptureLost() +{ + if (mMediaSource) + { + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, LEFT_BUTTON, mLastMouseX, mLastMouseY, 0); + } +} +////////////////////////////////////////////////////////////////////////////////////////// +BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask) +{ + // NOTE: this is called when the mouse is released when we have capture. + // Due to the way mouse coordinates are mapped to the object, we can't use the x and y coordinates that come in with the event. + + if(hasMouseCapture()) + { + // Release the mouse -- this will also send a mouseup to the media + gFocusMgr.setMouseCapture( FALSE ); + } + return TRUE; +} ////////////////////////////////////////////////////////////////////////////////////////// -// The viewer takes a long time to load the start screen. Part of the problem -// is media initialization -- in particular, QuickTime loads many DLLs and -// hits the disk heavily. So we initialize only the browser component before -// the login screen, then do the rest later when we have a progress bar. JC -// static -void LLViewerMedia::initBrowser() +void LLViewerMediaImpl::navigateHome() { - LLMediaManagerData* init_data = new LLMediaManagerData; - buildMediaManagerData( init_data ); - LLMediaManager::initBrowser( init_data ); - delete init_data; - - // We use a custom user agent with viewer version and skin name. - LLViewerMediaImpl::updateBrowserUserAgent(); + if(mMediaSource) + { + mMediaSource->loadURI( mHomeURL ); + } } ////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::initClass() +void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type, bool rediscover_type) { - // *TODO: This looks like a memory leak to me. JC - LLMediaManagerData* init_data = new LLMediaManagerData; - buildMediaManagerData( init_data ); - LLMediaManager::initClass( init_data ); - delete init_data; + if(rediscover_type) + { + + LLURI uri(url); + std::string scheme = uri.scheme(); - LLMediaManager* mm = LLMediaManager::getInstance(); - LLMIMETypes::mime_info_map_t::const_iterator it; - for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it) + if(scheme.empty() || "http" == scheme || "https" == scheme) + { + LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this)); + } + else if("data" == scheme || "file" == scheme || "about" == scheme) + { + // FIXME: figure out how to really discover the type for these schemes + // We use "data" internally for a text/html url for loading the login screen + if(initializeMedia("text/html")) + { + mMediaSource->loadURI( url ); + } + } + else + { + // This catches 'rtsp://' urls + if(initializeMedia(scheme)) + { + mMediaSource->loadURI( url ); + } + } + } + else if (mMediaSource) { - const std::string& mime_type = it->first; - const LLMIMETypes::LLMIMEInfo& info = it->second; - mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); + mMediaSource->loadURI( url ); } - - LLMediaBase *impl = mm->createSourceFromMimeType("http", "audio/mpeg"); - if (impl) + else if(initializeMedia(mime_type) && mMediaSource) + { + mMediaSource->loadURI( url ); + } + else { - U32 level = gSavedSettings.getU32("MediaDebugLevel"); - impl->setDebugLevel( (LLMediaBase::EDebugLevel)level ); + LL_WARNS("Media") << "Couldn't navigate to: " << url << " as there is no media type for: " << mime_type << LL_ENDL; + return; } + mMediaURL = url; + } ////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::buildMediaManagerData( LLMediaManagerData* init_data ) -{ -// std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") ); -// std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") ); -// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); -// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); -// component_dir += "\\newview\\app_settings\\mozilla"; - - -#if LL_DARWIN - // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in - // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac. - std::string component_dir(gDirUtilp->getExecutableDir()); -#elif LL_WINDOWS - std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - component_dir += gDirUtilp->getDirDelimiter(); - #ifdef LL_DEBUG - component_dir += "mozilla_debug"; - #else // LL_DEBUG - component_dir += "mozilla"; - #endif // LL_DEBUG -#elif LL_LINUX - std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - component_dir += gDirUtilp->getDirDelimiter(); - - #if LINUX64 - component_dir += "mozilla-runtime-linux-x86_64"; - #else - component_dir += "mozilla-runtime-linux-i686"; - #endif - -#elif LL_SOLARIS - std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - component_dir += gDirUtilp->getDirDelimiter(); - #ifdef __sparc - component_dir += "mozilla-solaris-sparc"; - #else - component_dir += "mozilla-solaris-i686"; - #endif -#else - std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - component_dir += gDirUtilp->getDirDelimiter(); - component_dir += "mozilla"; -#endif - - std::string application_dir = gDirUtilp->getExecutableDir(); +void LLViewerMediaImpl::navigateStop() +{ + if(mMediaSource) + { + mMediaSource->browse_stop(); + } - init_data->setBrowserApplicationDir( application_dir ); - std::string profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ); - init_data->setBrowserProfileDir( profile_dir ); - init_data->setBrowserComponentDir( component_dir ); - std::string profile_name("Second Life"); - init_data->setBrowserProfileName( profile_name ); - init_data->setBrowserParentWindow( gViewerWindow->getMediaWindow() ); +} - // Users can change skins while client is running, so make sure - // we pick up on changes. - gSavedSettings.getControl("SkinCurrent")->getSignal()->connect( - boost::bind( LLViewerMediaImpl::handleSkinCurrentChanged, _1 ) ); +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask) +{ + bool result = false; + + if (mMediaSource) + { + result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask); + } + + return result; +} +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char) +{ + bool result = false; + + if (mMediaSource) + { + // only accept 'printable' characters, sigh... + if (uni_char >= 32 // discard 'control' characters + && uni_char != 127) // SDL thinks this is 'delete' - yuck. + { + mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE)); + } + } + + return result; } ////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::cleanupClass() +bool LLViewerMediaImpl::canNavigateForward() { - stop() ; - LLMediaManager::cleanupClass(); + BOOL result = FALSE; + if (mMediaSource) + { + result = mMediaSource->getHistoryForwardAvailable(); + } + return result; } -// static -void LLViewerMedia::play(const std::string& media_url, - const std::string& mime_type, - const LLUUID& placeholder_texture_id, - S32 media_width, S32 media_height, U8 media_auto_scale, - U8 media_loop) +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::canNavigateBack() { - sViewerMediaImpl.play(media_url, mime_type, placeholder_texture_id, - media_width, media_height, media_auto_scale, media_loop); + BOOL result = FALSE; + if (mMediaSource) + { + result = mMediaSource->getHistoryBackAvailable(); + } + return result; } -// static -void LLViewerMedia::stop() + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active) { - sViewerMediaImpl.stop(); + // IF the media image hasn't changed, do nothing + if (mTextureId == uuid) + { + return; + } + // If we have changed media uuid, restore the old one + if (!mTextureId.isNull()) + { + LLViewerImage* oldImage = LLViewerImage::getImage( mTextureId ); + if (oldImage) + { + oldImage->reinit(mMovieImageHasMips); + oldImage->mIsMediaTexture = FALSE; + } + } + // If the movie is playing, set the new media image + if (active && !uuid.isNull()) + { + LLViewerImage* viewerImage = LLViewerImage::getImage( uuid ); + if( viewerImage ) + { + mTextureId = uuid; + // Can't use mipmaps for movies because they don't update the full image + mMovieImageHasMips = viewerImage->getUseMipMaps(); + viewerImage->reinit(FALSE); + viewerImage->mIsMediaTexture = TRUE; + } + } } -// static -void LLViewerMedia::pause() +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::update() { - sViewerMediaImpl.pause(); + if(mMediaSource == NULL) + { + return; + } + + mMediaSource->idle(); + + if(mMediaSource->isPluginExited()) + { + destroyMediaSource(); + return; + } + + if(!mMediaSource->textureValid()) + { + return; + } + + if(mSuspendUpdates || !mVisible) + { + return; + } + + LLViewerImage* placeholder_image = updatePlaceholderImage(); + + if(placeholder_image) + { + LLRect dirty_rect; + if(mMediaSource->getDirty(&dirty_rect)) + { + // Constrain the dirty rect to be inside the texture + S32 x_pos = llmax(dirty_rect.mLeft, 0); + S32 y_pos = llmax(dirty_rect.mBottom, 0); + S32 width = llmin(dirty_rect.mRight, placeholder_image->getWidth()) - x_pos; + S32 height = llmin(dirty_rect.mTop, placeholder_image->getHeight()) - y_pos; + + if(width > 0 && height > 0) + { + + U8* data = mMediaSource->getBitsData(); + + // Offset the pixels pointer to match x_pos and y_pos + data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() ); + data += ( y_pos * mMediaSource->getTextureDepth() ); + + placeholder_image->setSubImage( + data, + mMediaSource->getBitsWidth(), + mMediaSource->getBitsHeight(), + x_pos, + y_pos, + width, + height, + TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) + + } + + mMediaSource->resetDirty(); + } + } } -// static -void LLViewerMedia::start() + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::updateImagesMediaStreams() { - sViewerMediaImpl.start(); } -// static -void LLViewerMedia::seek(F32 time) + +////////////////////////////////////////////////////////////////////////////////////////// +LLViewerImage* LLViewerMediaImpl::updatePlaceholderImage() { - sViewerMediaImpl.seek(time); + if(mTextureId.isNull()) + { + // The code that created this instance will read from the plugin's bits. + return NULL; + } + + LLViewerImage* placeholder_image = gImageList.getImage( mTextureId ); + + if (mNeedsNewTexture + || placeholder_image->getUseMipMaps() + || ! placeholder_image->mIsMediaTexture + || placeholder_image->getWidth() != mMediaSource->getTextureWidth() + || placeholder_image->getHeight() != mMediaSource->getTextureHeight()) + { + llinfos << "initializing media placeholder" << llendl; + llinfos << "movie image id " << mTextureId << llendl; + + int texture_width = mMediaSource->getTextureWidth(); + int texture_height = mMediaSource->getTextureHeight(); + int texture_depth = mMediaSource->getTextureDepth(); + + // MEDIAOPT: check to see if size actually changed before doing work + placeholder_image->destroyGLTexture(); + // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? + placeholder_image->reinit(FALSE); // probably not needed + + // MEDIAOPT: seems insane that we actually have to make an imageraw then + // immediately discard it + LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth); + raw->clear(0x0f, 0x0f, 0x0f, 0xff); + int discard_level = 0; + + // ask media source for correct GL image format constants + placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(), + mMediaSource->getTextureFormatPrimary(), + mMediaSource->getTextureFormatType(), + mMediaSource->getTextureFormatSwapBytes()); + + placeholder_image->createGLTexture(discard_level, raw); + + // placeholder_image->setExplicitFormat() + placeholder_image->setUseMipMaps(FALSE); + + // MEDIAOPT: set this dynamically on play/stop + placeholder_image->mIsMediaTexture = true; + mNeedsNewTexture = false; + } + + return placeholder_image; } -// static -void LLViewerMedia::setVolume(F32 volume) + +////////////////////////////////////////////////////////////////////////////////////////// +LLUUID LLViewerMediaImpl::getMediaTextureID() { - sViewerMediaImpl.setVolume(volume); + return mTextureId; } -// static -LLMediaBase::EStatus LLViewerMedia::getStatus() +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::setVisible(bool visible) { - return sViewerMediaImpl.getStatus(); + mVisible = visible; + + if(mVisible) + { + if(mMediaSource && mMediaSource->isPluginExited()) + { + destroyMediaSource(); + } + + if(!mMediaSource) + { + createMediaSource(); + } + } + + if(mMediaSource) + { + mMediaSource->setPriority(mVisible?LLPluginClassMedia::PRIORITY_NORMAL:LLPluginClassMedia::PRIORITY_HIDDEN); + } } ////////////////////////////////////////////////////////////////////////////////////////// -// static -LLUUID LLViewerMedia::getMediaTextureID() +void LLViewerMediaImpl::mouseCapture() { - return sViewerMediaImpl.getMediaTextureID(); + gFocusMgr.setMouseCapture(this); } ////////////////////////////////////////////////////////////////////////////////////////// -// static -bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height) +void LLViewerMediaImpl::getTextureSize(S32 *texture_width, S32 *texture_height) { - // make sure we're valid + if(mMediaSource && mMediaSource->textureValid()) + { + S32 real_texture_width = mMediaSource->getBitsWidth(); + S32 real_texture_height = mMediaSource->getBitsHeight(); - if ( sViewerMediaImpl.mMediaSource != NULL ) + { + // The "texture width" coming back from the plugin may not be a power of two (thanks to webkit). + // It will be the correct "data width" to pass to setSubImage + int i; + + for(i = 1; i < real_texture_width; i <<= 1) + ; + *texture_width = i; + + for(i = 1; i < real_texture_height; i <<= 1) + ; + *texture_height = i; + } + + } + else { - *media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); - *media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); - return true; + *texture_width = 0; + *texture_height = 0; } - return false; +} +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y) +{ +#if 0 + S32 media_width, media_height; + S32 texture_width, texture_height; + getMediaSize( &media_width, &media_height ); + getTextureSize( &texture_width, &texture_height ); + S32 y_delta = texture_height - media_height; + + *mouse_y -= y_delta; +#endif } ////////////////////////////////////////////////////////////////////////////////////////// -// static -bool LLViewerMedia::getTextureSize(S32 *texture_width, S32 *texture_height) +bool LLViewerMediaImpl::isMediaPlaying() { - if ( sViewerMediaImpl.mMediaSource != NULL ) + bool result = false; + + if(mMediaSource) { - S32 media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); - S32 media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); - *texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); - *texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); - return true; + EMediaStatus status = mMediaSource->getStatus(); + if(status == MEDIA_PLAYING || status == MEDIA_LOADING) + result = true; } - return false; + + return result; } +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::isMediaPaused() +{ + bool result = false; + if(mMediaSource) + { + if(mMediaSource->getStatus() == MEDIA_PAUSED) + result = true; + } + + return result; +} ////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::updateImagesMediaStreams() +// +bool LLViewerMediaImpl::hasMedia() { - sViewerMediaImpl.updateImagesMediaStreams(); + return mMediaSource != NULL; } + ////////////////////////////////////////////////////////////////////////////////////////// -// static -bool LLViewerMedia::isMediaPlaying() +void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event) { - LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); - return (status == LLMediaBase::STATUS_STARTED ); + switch(event) + { + case MEDIA_EVENT_PLUGIN_FAILED: + { + LLSD args; + args["PLUGIN"] = LLMIMETypes::implType(mMimeType); + LLNotifications::instance().add("MediaPluginFailed", args); + } + break; + default: + break; + } + // Just chain the event to observers. + emitEvent(self, event); } -////////////////////////////////////////////////////////////////////////////////////////// -// static -bool LLViewerMedia::isMediaPaused() + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void +LLViewerMediaImpl::cut() { - LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); - return (status == LLMediaBase::STATUS_PAUSED); + if (mMediaSource) + mMediaSource->cut(); } -////////////////////////////////////////////////////////////////////////////////////////// -// static -bool LLViewerMedia::hasMedia() + +//////////////////////////////////////////////////////////////////////////////// +// virtual +BOOL +LLViewerMediaImpl::canCut() const { - return sViewerMediaImpl.mMediaSource != NULL; + if (mMediaSource) + return mMediaSource->canCut(); + else + return FALSE; } -////////////////////////////////////////////////////////////////////////////////////////// -//static -bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id) +//////////////////////////////////////////////////////////////////////////////// +// virtual +void +LLViewerMediaImpl::copy() { - return (id.notNull() - && id == getMediaTextureID() - && isMediaPlaying()); + if (mMediaSource) + mMediaSource->copy(); } -////////////////////////////////////////////////////////////////////////////////////////// -// static -std::string LLViewerMedia::getMediaURL() +//////////////////////////////////////////////////////////////////////////////// +// virtual +BOOL +LLViewerMediaImpl::canCopy() const { - return sViewerMediaImpl.mMediaURL; + if (mMediaSource) + return mMediaSource->canCopy(); + else + return FALSE; } -////////////////////////////////////////////////////////////////////////////////////////// -// static -std::string LLViewerMedia::getMimeType() + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void +LLViewerMediaImpl::paste() { - return sViewerMediaImpl.mMimeType; + if (mMediaSource) + mMediaSource->paste(); } -////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::setMimeType(std::string mime_type) + +//////////////////////////////////////////////////////////////////////////////// +// virtual +BOOL +LLViewerMediaImpl::canPaste() const { - sViewerMediaImpl.mMimeType = mime_type; + if (mMediaSource) + return mMediaSource->canPaste(); + else + return FALSE; } + diff --git a/linden/indra/newview/llviewermedia.h b/linden/indra/newview/llviewermedia.h index 600d7409e..afda426af 100644 --- a/linden/indra/newview/llviewermedia.h +++ b/linden/indra/newview/llviewermedia.h @@ -33,50 +33,192 @@ #ifndef LLVIEWERMEDIA_H #define LLVIEWERMEDIA_H -#include "llmediabase.h" // for status codes +#include "llfocusmgr.h" -class LLMediaManagerData; +#include "llpanel.h" +#include "llpluginclassmediaowner.h" + +#include "llviewermediaobserver.h" + +class LLViewerMediaImpl; class LLUUID; +class LLViewerImage; + +typedef LLPointer<LLViewerMediaImpl> viewer_media_t; +/////////////////////////////////////////////////////////////////////////////// +// +class LLViewerMediaEventEmitter +{ +public: + virtual ~LLViewerMediaEventEmitter(); + + bool addObserver( LLViewerMediaObserver* subject ); + bool remObserver( LLViewerMediaObserver* subject ); + void emitEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event); + +private: + typedef std::list< LLViewerMediaObserver* > observerListType; + observerListType mObservers; +}; class LLViewerMedia { + LOG_CLASS(LLViewerMedia); public: // Special case early init for just web browser component // so we can show login screen. See .cpp file for details. JC - static void initBrowser(); - static void initClass(); - static void cleanupClass(); + static viewer_media_t newMediaImpl(const std::string& media_url, + const LLUUID& texture_id, + S32 media_width, + S32 media_height, + U8 media_auto_scale, + U8 media_loop, + std::string mime_type = "none/none"); - static void play(const std::string& media_url, - const std::string& mime_type, - const LLUUID& placeholder_texture_id, - S32 media_width, S32 media_height, U8 media_auto_scale, - U8 media_loop); - static void stop(); - static void pause(); - static void start(); - static void seek(F32 time); + static void removeMedia(LLViewerMediaImpl* media); + static LLViewerMediaImpl* getMediaImplFromTextureID(const LLUUID& texture_id); + static std::string getCurrentUserAgent(); + static void updateBrowserUserAgent(); + static bool handleSkinCurrentChanged(const LLSD& /*newvalue*/); + static bool textureHasMedia(const LLUUID& texture_id); static void setVolume(F32 volume); - static LLMediaBase::EStatus getStatus(); - static LLUUID getMediaTextureID(); - static bool getMediaSize(S32 *media_width, S32 *media_height); - static bool getTextureSize(S32 *texture_width, S32 *texture_height); - static bool isMediaPlaying(); - static bool isMediaPaused(); - static bool hasMedia(); - static bool isActiveMediaTexture(const LLUUID& id); + static void updateMedia(); + + static void cleanupClass(); + +}; + +// Implementation functions not exported into header file +class LLViewerMediaImpl + : public LLMouseHandler, public LLRefCount, public LLPluginClassMediaOwner, public LLViewerMediaEventEmitter, public LLEditMenuHandler +{ + LOG_CLASS(LLViewerMediaImpl); +public: + + LLViewerMediaImpl(const std::string& media_url, + const LLUUID& texture_id, + S32 media_width, + S32 media_height, + U8 media_auto_scale, + U8 media_loop, + const std::string& mime_type); + + ~LLViewerMediaImpl(); + void createMediaSource(); + void destroyMediaSource(); + void setMediaType(const std::string& media_type); + bool initializeMedia(const std::string& mime_type); + bool initializePlugin(const std::string& media_type); + LLPluginClassMedia* getMediaPlugin() { return mMediaSource; } + void setSize(int width, int height); + + void play(); + void stop(); + void pause(); + void start(); + void seek(F32 time); + void setVolume(F32 volume); + void focus(bool focus); + void mouseDown(S32 x, S32 y); + void mouseUp(S32 x, S32 y); + void mouseMove(S32 x, S32 y); + void mouseLeftDoubleClick(S32 x,S32 y ); + void mouseCapture(); + + void navigateHome(); + void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false); + void navigateStop(); + bool handleKeyHere(KEY key, MASK mask); + bool handleUnicodeCharHere(llwchar uni_char); + bool canNavigateForward(); + bool canNavigateBack(); + std::string getMediaURL() { return mMediaURL; } + std::string getMediaHomeURL() { return mHomeURL; } + std::string getMimeType() { return mMimeType; } + void getTextureSize(S32 *texture_width, S32 *texture_height); + void scaleMouse(S32 *mouse_x, S32 *mouse_y); + + void update(); + void updateMovieImage(const LLUUID& image_id, BOOL active); + void updateImagesMediaStreams(); + LLUUID getMediaTextureID(); + + void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; }; + void setVisible(bool visible); + + bool isMediaPlaying(); + bool isMediaPaused(); + bool hasMedia(); + + // utility function to create a ready-to-use media instance from a desired media type. + static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height); + + // Internally set our desired browser user agent string, including + // the Second Life version and skin name. Used because we can + // switch skins without restarting the app. + static void updateBrowserUserAgent(); + + // Callback for when the SkinCurrent control is changed to + // switch the user agent string to indicate the new skin. + static bool handleSkinCurrentChanged(const LLSD& newvalue); + + // need these to handle mouseup... + /*virtual*/ void onMouseCaptureLost(); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + + // Grr... the only thing I want as an LLMouseHandler are the onMouseCaptureLost and handleMouseUp calls. + // Sadly, these are all pure virtual, so I have to supply implementations here: + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }; + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; }; + /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; }; + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; }; + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }; + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; }; + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) { return FALSE; }; + /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }; + /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask) {return FALSE; }; + /*virtual*/ const std::string& getName() const { return LLStringUtil::null; }; + /*virtual*/ BOOL isView() const { return FALSE; }; + /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const {}; + /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const {}; + /*virtual*/ BOOL hasMouseCapture() { return gFocusMgr.getMouseCapture() == this; }; + + // Inherited from LLPluginClassMediaOwner + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent); + + // LLEditMenuHandler overrides + /*virtual*/ void cut(); + /*virtual*/ BOOL canCut() const; + + /*virtual*/ void copy(); + /*virtual*/ BOOL canCopy() const; - static std::string getMediaURL(); - static std::string getMimeType(); - static void setMimeType(std::string mime_type); + /*virtual*/ void paste(); + /*virtual*/ BOOL canPaste() const; + +public: + // a single media url with some data and an impl. + LLPluginClassMedia* mMediaSource; + LLUUID mTextureId; + bool mMovieImageHasMips; + std::string mMediaURL; + std::string mHomeURL; + std::string mMimeType; + S32 mLastMouseX; // save the last mouse coord we get, so when we lose capture we can simulate a mouseup at that point. + S32 mLastMouseY; + S32 mMediaWidth; + S32 mMediaHeight; + bool mMediaAutoScale; + bool mMediaLoop; + bool mNeedsNewTexture; + bool mSuspendUpdates; + bool mVisible; - static void updateImagesMediaStreams(); - private: - // Fill in initialization data for LLMediaManager::initClass() - static void buildMediaManagerData( LLMediaManagerData* init_data ); +private: + LLViewerImage *updatePlaceholderImage(); }; #endif // LLVIEWERMEDIA_H diff --git a/linden/indra/newview/llviewermedia_streamingaudio.cpp b/linden/indra/newview/llviewermedia_streamingaudio.cpp new file mode 100644 index 000000000..06946daff --- /dev/null +++ b/linden/indra/newview/llviewermedia_streamingaudio.cpp @@ -0,0 +1,169 @@ +/** + * @file llviewermedia_streamingaudio.h + * @author Tofu Linden, Sam Kolb + * @brief LLStreamingAudio_MediaPlugins implementation - an implementation of the streaming audio interface which is implemented as a client of the media plugins API. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "linden_common.h" +#include "llpluginclassmedia.h" +#include "llviewermedia.h" + +#include "llviewermedia_streamingaudio.h" + +#include "llmimetypes.h" +#include "llvfs.h" +#include "lldir.h" + + +LLStreamingAudio_MediaPlugins::LLStreamingAudio_MediaPlugins() : + mMediaPlugin(NULL), + mGain(1.0) +{ + // nothing interesting to do? + // we will lazily create a media plugin at play-time, if none exists. +} + +LLStreamingAudio_MediaPlugins::~LLStreamingAudio_MediaPlugins() +{ + delete mMediaPlugin; + mMediaPlugin = NULL; +} + +void LLStreamingAudio_MediaPlugins::start(const std::string& url) +{ + if (!mMediaPlugin) // lazy-init the underlying media plugin + { + mMediaPlugin = initializeMedia("audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. + llinfos << "mMediaPlugin is now " << mMediaPlugin << llendl; + } + + if(!mMediaPlugin) + return; + + if (!url.empty()) { + llinfos << "Starting internet stream: " << url << llendl; + mURL = url; + mMediaPlugin->loadURI ( url ); + mMediaPlugin->start(); + llinfos << "Playing....." << llendl; + } else { + llinfos << "setting stream to NULL"<< llendl; + mURL.clear(); + mMediaPlugin->stop(); + } +} + +void LLStreamingAudio_MediaPlugins::stop() +{ + if(mMediaPlugin) + { + mMediaPlugin->stop(); + } + + mURL.clear(); +} + +void LLStreamingAudio_MediaPlugins::pause(int pause) +{ + if(!mMediaPlugin) + return; + + if(pause) + { + mMediaPlugin->pause(); + } + else + { + mMediaPlugin->start(); + } +} + +void LLStreamingAudio_MediaPlugins::update() +{ + if (mMediaPlugin) + mMediaPlugin->idle(); +} + +int LLStreamingAudio_MediaPlugins::isPlaying() +{ + if (!mMediaPlugin) + return 0; + + // *TODO: can probably do better than this + if (mMediaPlugin->isPluginRunning()) + { + return 1; // Active and playing + } + + if (mMediaPlugin->isPluginExited()) + { + return 0; // stopped + } + + return 2; // paused +} + +void LLStreamingAudio_MediaPlugins::setGain(F32 vol) +{ + mGain = vol; + + if(!mMediaPlugin) + return; + + vol = llclamp(vol, 0.f, 1.f); + mMediaPlugin->setVolume(vol); +} + +F32 LLStreamingAudio_MediaPlugins::getGain() +{ + return mGain; +} + +std::string LLStreamingAudio_MediaPlugins::getURL() +{ + return mURL; +} + +LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::string& media_type) +{ + LLPluginClassMediaOwner* owner = NULL; + S32 default_size = 1; // audio-only - be minimal, doesn't matter + LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size); + + if (media_source) + { + media_source->setLoop(false); // audio streams are not expected to loop + } + + return media_source; +} + diff --git a/linden/indra/newview/llviewermedia_streamingaudio.h b/linden/indra/newview/llviewermedia_streamingaudio.h new file mode 100644 index 000000000..270bab762 --- /dev/null +++ b/linden/indra/newview/llviewermedia_streamingaudio.h @@ -0,0 +1,69 @@ +/** + * @file llviewermedia_streamingaudio.h + * @author Tofu Linden + * @brief Definition of LLStreamingAudio_MediaPlugins implementation - an implementation of the streaming audio interface which is implemented as a client of the media plugins API. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_VIEWERMEDIA_STREAMINGAUDIO_H +#define LL_VIEWERMEDIA_STREAMINGAUDIO_H + + +#include "stdtypes.h" // from llcommon + +#include "llstreamingaudio.h" + +class LLPluginClassMedia; + +class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface +{ + public: + LLStreamingAudio_MediaPlugins(); + /*virtual*/ ~LLStreamingAudio_MediaPlugins(); + + /*virtual*/ void start(const std::string& url); + /*virtual*/ void stop(); + /*virtual*/ void pause(int pause); + /*virtual*/ void update(); + /*virtual*/ int isPlaying(); + /*virtual*/ void setGain(F32 vol); + /*virtual*/ F32 getGain(); + /*virtual*/ std::string getURL(); + +private: + LLPluginClassMedia* initializeMedia(const std::string& media_type); + + LLPluginClassMedia *mMediaPlugin; + + std::string mURL; + F32 mGain; +}; + + +#endif //LL_VIEWERMEDIA_STREAMINGAUDIO_H diff --git a/linden/indra/newview/llviewermediafocus.cpp b/linden/indra/newview/llviewermediafocus.cpp new file mode 100644 index 000000000..2e372a1ca --- /dev/null +++ b/linden/indra/newview/llviewermediafocus.cpp @@ -0,0 +1,359 @@ +/** + * @file llviewermediafocus.cpp + * @brief Governs focus on Media prims + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewermediafocus.h" + +//LLViewerMediaFocus +#include "llviewerobjectlist.h" +#include "llpanelmediahud.h" +#include "llpluginclassmedia.h" +#include "llagent.h" +#include "lltoolpie.h" +#include "llviewercamera.h" +#include "llviewermedia.h" +#include "llhudview.h" +#include "lluictrlfactory.h" +#include "lldrawable.h" +#include "llparcel.h" +#include "llviewerparcelmgr.h" +#include "llweb.h" +// +// LLViewerMediaFocus +// + +LLViewerMediaFocus::LLViewerMediaFocus() +: mMouseOverFlag(false) +{ +} + +LLViewerMediaFocus::~LLViewerMediaFocus() +{ + // The destructor for LLSingletons happens at atexit() time, which is too late to do much. + // Clean up in cleanupClass() instead. +} + +void LLViewerMediaFocus::cleanupClass() +{ + LLViewerMediaFocus *self = LLViewerMediaFocus::getInstance(); + + if(self) + { + // mMediaHUD will have been deleted by this point -- don't try to delete it. + + /* Richard says: + all widgets are supposed to be destroyed at the same time + you shouldn't hold on to pointer to them outside of ui code + you can use the LLHandle approach + if you want to be type safe, you'll need to add a LLRootHandle to whatever derived class you are pointing to + look at llview::gethandle + its our version of a weak pointer + */ + if(self->mMediaHUD.get()) + { + self->mMediaHUD.get()->setMediaImpl(NULL); + } + self->mMediaImpl = NULL; + } + +} + + +void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl ) +{ + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (b && media_impl.notNull()) + { + mMediaImpl = media_impl; + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectOnly(objectp, face); + + mFocus = LLSelectMgr::getInstance()->getSelection(); + if(mMediaHUD.get() && ! parcel->getMediaPreventCameraZoom()) + { + mMediaHUD.get()->resetZoomLevel(); + mMediaHUD.get()->nextZoomLevel(); + } + if (!mFocus->isEmpty()) + { + gFocusMgr.setKeyboardFocus(this); + } + mObjectID = objectp->getID(); + // LLViewerMedia::addObserver(this, mObjectID); + + + } + else + { + gFocusMgr.setKeyboardFocus(NULL); + if(! parcel->getMediaPreventCameraZoom()) + { + if (!mFocus->isEmpty()) + { + gAgent.setFocusOnAvatar(TRUE, ANIMATE); + } + } + mFocus = NULL; + // LLViewerMedia::remObserver(this, mObjectID); + + // Null out the media hud media pointer + if(mMediaHUD.get()) + { + mMediaHUD.get()->setMediaImpl(NULL); + } + + // and null out the media impl + mMediaImpl = NULL; + } + if(mMediaHUD.get()) + { + mMediaHUD.get()->setMediaFocus(b); + } +} +bool LLViewerMediaFocus::getFocus() +{ + if (gFocusMgr.getKeyboardFocus() == this) + { + return true; + } + return false; +} + +// This function selects an ideal viewing distance given a selection bounding box, normal, and padding value +void LLViewerMediaFocus::setCameraZoom(F32 padding_factor) +{ + LLPickInfo& pick = LLToolPie::getInstance()->getPick(); + + if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + pick = mPickInfo; + setFocusFace(true, pick.getObject(), pick.mObjectFace, mMediaImpl); + } + + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + + LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + F32 height; + F32 width; + F32 depth; + F32 angle_of_view; + F32 distance; + + // We need the aspect ratio, and the 3 components of the bbox as height, width, and depth. + F32 aspect_ratio = getBBoxAspectRatio(selection_bbox, pick.mNormal, &height, &width, &depth); + F32 camera_aspect = LLViewerCamera::getInstance()->getAspect(); + + // We will normally use the side of the volume aligned with the short side of the screen (i.e. the height for + // a screen in a landscape aspect ratio), however there is an edge case where the aspect ratio of the object is + // more extreme than the screen. In this case we invert the logic, using the longer component of both the object + // and the screen. + bool invert = (camera_aspect > 1.0f && aspect_ratio > camera_aspect) || + (camera_aspect < 1.0f && aspect_ratio < camera_aspect); + + // To calculate the optimum viewing distance we will need the angle of the shorter side of the view rectangle. + // In portrait mode this is the width, and in landscape it is the height. + // We then calculate the distance based on the corresponding side of the object bbox (width for portrait, height for landscape) + // We will add half the depth of the bounding box, as the distance projection uses the center point of the bbox. + if(camera_aspect < 1.0f || invert) + { + angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect()); + distance = width * 0.5 * padding_factor / tan(angle_of_view * 0.5f ); + } + else + { + angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView()); + distance = height * 0.5 * padding_factor / tan(angle_of_view * 0.5f ); + } + + distance += depth * 0.5; + + // Finally animate the camera to this new position and focal point + gAgent.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(pick.mNormal * distance), + LLSelectMgr::getInstance()->getSelectionCenterGlobal(), LLSelectMgr::getInstance()->getSelection()->getFirstObject()->mID ); + } +} +void LLViewerMediaFocus::onFocusReceived() +{ + if(mMediaImpl.notNull()) + mMediaImpl->focus(true); + + LLFocusableElement::onFocusReceived(); +} + +void LLViewerMediaFocus::onFocusLost() +{ + if(mMediaImpl.notNull()) + mMediaImpl->focus(false); + gViewerWindow->focusClient(); + mFocus = NULL; + LLFocusableElement::onFocusLost(); +} +void LLViewerMediaFocus::setMouseOverFlag(bool b, viewer_media_t media_impl) +{ + if (b && media_impl.notNull()) + { + if(! mMediaHUD.get()) + { + LLPanelMediaHUD* media_hud = new LLPanelMediaHUD(mMediaImpl); + mMediaHUD = media_hud->getHandle(); + gHUDView->addChild(media_hud); + } + mMediaHUD.get()->setMediaImpl(media_impl); + mMediaImpl = media_impl; + } + mMouseOverFlag = b; +} +LLUUID LLViewerMediaFocus::getSelectedUUID() +{ + LLViewerObject* object = mFocus->getFirstObject(); + return object ? object->getID() : LLUUID::null; +} +#if 0 // Must re-implement when the new media api event system is ready +void LLViewerMediaFocus::onNavigateComplete( const EventType& event_in ) +{ + if (hasFocus() && mLastURL != event_in.getStringValue()) + { + LLViewerMedia::focus(true, mObjectID); + // spoof mouse event to reassert focus + LLViewerMedia::mouseDown(1,1, mObjectID); + LLViewerMedia::mouseUp(1,1, mObjectID); + } + mLastURL = event_in.getStringValue(); +} +#endif +BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent) +{ + if(mMediaImpl.notNull()) + mMediaImpl->handleKeyHere(key, mask); + return true; +} + +BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) +{ + if(mMediaImpl.notNull()) + mMediaImpl->handleUnicodeCharHere(uni_char); + return true; +} +BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + BOOL retval = FALSE; + if(mFocus.notNull() && mMediaImpl.notNull() && mMediaImpl->hasMedia()) + { + mMediaImpl->getMediaPlugin()->scrollEvent(x, y, clicks); + retval = TRUE; + } + return retval; +} + +void LLViewerMediaFocus::update() +{ + if (mMediaHUD.get()) + { + if(mFocus.notNull() || mMouseOverFlag || mMediaHUD.get()->isMouseOver()) + { + // mMediaHUD.get()->setVisible(true); + mMediaHUD.get()->updateShape(); + } + else + { + mMediaHUD.get()->setVisible(false); + } + } +} +// This function calculates the aspect ratio and the world aligned components of a selection bounding box. +F32 LLViewerMediaFocus::getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth) +{ + // Convert the selection normal and an up vector to local coordinate space of the bbox + LLVector3 local_normal = bbox.agentToLocalBasis(normal); + LLVector3 z_vec = bbox.agentToLocalBasis(LLVector3(0.0f, 0.0f, 1.0f)); + + LLVector3 comp1(0.f,0.f,0.f); + LLVector3 comp2(0.f,0.f,0.f); + LLVector3 bbox_max = bbox.getExtentLocal(); + F32 dot1 = 0.f; + F32 dot2 = 0.f; + + // The largest component of the localized normal vector is the depth component + // meaning that the other two are the legs of the rectangle. + local_normal.abs(); + if(local_normal.mV[VX] > local_normal.mV[VY]) + { + if(local_normal.mV[VX] > local_normal.mV[VZ]) + { + // Use the y and z comps + comp1.mV[VY] = bbox_max.mV[VY]; + comp2.mV[VZ] = bbox_max.mV[VZ]; + *depth = bbox_max.mV[VX]; + } + else + { + // Use the x and y comps + comp1.mV[VY] = bbox_max.mV[VY]; + comp2.mV[VZ] = bbox_max.mV[VZ]; + *depth = bbox_max.mV[VZ]; + } + } + else if(local_normal.mV[VY] > local_normal.mV[VZ]) + { + // Use the x and z comps + comp1.mV[VX] = bbox_max.mV[VX]; + comp2.mV[VZ] = bbox_max.mV[VZ]; + *depth = bbox_max.mV[VY]; + } + else + { + // Use the x and y comps + comp1.mV[VY] = bbox_max.mV[VY]; + comp2.mV[VZ] = bbox_max.mV[VZ]; + *depth = bbox_max.mV[VX]; + } + + // The height is the vector closest to vertical in the bbox coordinate space (highest dot product value) + dot1 = comp1 * z_vec; + dot2 = comp2 * z_vec; + if(fabs(dot1) > fabs(dot2)) + { + *height = comp1.length(); + *width = comp2.length(); + } + else + { + *height = comp2.length(); + *width = comp1.length(); + } + + // Return the aspect ratio. + return *width / *height; +} diff --git a/linden/indra/newview/llviewermediafocus.h b/linden/indra/newview/llviewermediafocus.h new file mode 100644 index 000000000..ed9597e61 --- /dev/null +++ b/linden/indra/newview/llviewermediafocus.h @@ -0,0 +1,91 @@ +/** + * @file llpanelmsgs.h + * @brief Message popup preferences panel + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_VIEWERMEDIAFOCUS_H +#define LL_VIEWERMEDIAFOCUS_H + +// includes for LLViewerMediaFocus +#include "llfocusmgr.h" +#include "llviewermedia.h" +#include "llviewerobject.h" +#include "llviewerwindow.h" +#include "llselectmgr.h" + +class LLViewerMediaImpl; +class LLPanelMediaHUD; + +class LLViewerMediaFocus : + public LLFocusableElement, + public LLSingleton<LLViewerMediaFocus> +{ +public: + LLViewerMediaFocus(); + ~LLViewerMediaFocus(); + + static void cleanupClass(); + + void setFocusFace(BOOL b, LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl); + void clearFocus() { setFocusFace(false, NULL, 0, NULL); } + /*virtual*/ bool getFocus(); + /*virtual*/ // void onNavigateComplete( const EventType& event_in ); + + /*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + LLUUID getSelectedUUID(); + LLObjectSelectionHandle getSelection() { return mFocus; } + + void update(); + + void setCameraZoom(F32 padding_factor); + void setMouseOverFlag(bool b, viewer_media_t media_impl = NULL); + bool getMouseOverFlag() { return mMouseOverFlag; } + void setPickInfo(LLPickInfo pick_info) { mPickInfo = pick_info; } + F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth); + +protected: + /*virtual*/ void onFocusReceived(); + /*virtual*/ void onFocusLost(); + +private: + LLObjectSelectionHandle mFocus; + std::string mLastURL; + bool mMouseOverFlag; + LLPickInfo mPickInfo; + LLHandle<LLPanelMediaHUD> mMediaHUD; + LLUUID mObjectID; + viewer_media_t mMediaImpl; +}; + + +#endif // LL_VIEWERMEDIAFOCUS_H diff --git a/linden/indra/llmedia/llmediaimplexample1.h b/linden/indra/newview/llviewermediaobserver.h similarity index 56% rename from linden/indra/llmedia/llmediaimplexample1.h rename to linden/indra/newview/llviewermediaobserver.h index 1b90e9378..6667f982b 100644 --- a/linden/indra/llmedia/llmediaimplexample1.h +++ b/linden/indra/newview/llviewermediaobserver.h @@ -1,6 +1,6 @@ /** - * @file llmediaimplexample1.h - * @brief Example 1 of a media impl concrete class + * @file llviewermediaobserver.h + * @brief Methods to override to catch events from LLViewerMedia class * * $LicenseInfo:firstyear=2007&license=viewergpl$ * @@ -30,44 +30,42 @@ * $/LicenseInfo$ */ -#ifndef LLMEDIAIMPLEXAMPLE1_H -#define LLMEDIAIMPLEXAMPLE1_H +#ifndef LLVIEWERMEDIAOBSERVER_H +#define LLVIEWERMEDIAOBSERVER_H -#include "llmediaimplcommon.h" -#include "llmediaimplfactory.h" +#include "llpluginclassmediaowner.h" -class LLMediaManagerData; +class LLViewerMediaEventEmitter; -class LLMediaImplExample1 : - public LLMediaImplCommon +class LLViewerMediaObserver : public LLPluginClassMediaOwner { - public: - LLMediaImplExample1(); +public: + virtual ~LLViewerMediaObserver(); + +private: + // Emitters will manage this list in addObserver/remObserver. + friend class LLViewerMediaEventEmitter; + std::list<LLViewerMediaEventEmitter *> mEmitters; +}; - static bool startup( LLMediaManagerData* init_data ); - static bool closedown(); - /* virtual */ bool init(); - /* virtual */ bool navigateTo( const std::string url ); - /* virtual */ bool updateMedia(); - /* virtual */ std::string getVersion(); - /* virtual */ unsigned char* getMediaData(); - /* virtual */ bool reset(); - /* virtual */ bool mouseMove( int x_pos, int y_pos ); - /* virtual */ bool setRequestedMediaSize( int width, int height ); +#if 0 + // Classes that inherit from LLViewerMediaObserver should add this to their class declaration: + + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); + + /* and will probably need to add this to their cpp file: - private: - unsigned char* mMediaPixels; -}; + #include "llpluginclassmedia.h" -class LLMediaImplExample1Maker : public LLMediaImplMaker -{ - public: - LLMediaImplExample1Maker(); - LLMediaImplExample1* create() - { - return new LLMediaImplExample1(); - } -}; + */ + + // The list of events is in llpluginclassmediaowner.h + + +#endif + + +#endif // LLVIEWERMEDIAOBSERVER_H -#endif // LLMEDIAIMPLEXAMPLE1_H diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index fd6e842e9..7266dbce9 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -40,7 +40,7 @@ #include <sstream> // linden library includes -#include "audioengine.h" +#include "llaudioengine.h" #include "indra_constants.h" #include "llassetstorage.h" #include "llchat.h" @@ -111,9 +111,8 @@ #include "llfloatergroupinfo.h" #include "llfloatergroupinvite.h" #include "llfloatergroups.h" -#include "llfloaterhtml.h" #include "llfloaterhtmlcurrency.h" -#include "llfloaterhtmlhelp.h" // gViewerHtmlHelp +#include "llfloatermediabrowser.h" // gViewerHtmlHelp #include "llfloaterhtmlsimple.h" #include "llfloaterhud.h" #include "llfloaterinspect.h" @@ -158,6 +157,7 @@ #include "lllineeditor.h" #include "llmenucommands.h" #include "llmenugl.h" +#include "llmimetypes.h" #include "llmorphview.h" #include "llmoveview.h" #include "llmutelist.h" @@ -934,6 +934,14 @@ void init_client_menu(LLMenuGL* menu) menu->appendMenu( sub ); sub->createJumpKeys(); } + { + LLMenuGL* sub = NULL; + sub = new LLMenuGL("Media"); + sub->append(new LLMenuItemCallGL("Reload MIME types", &LLMIMETypes::reload)); + sub->append(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test)); + menu->appendMenu( sub ); + sub->createJumpKeys(); + } menu->appendSeparator(); @@ -1063,6 +1071,7 @@ void init_debug_ui_menu(LLMenuGL* menu) menu->appendSeparator(); menu->append(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test)); + // commented out until work is complete: DEV-32268 // menu->append(new LLMenuItemCallGL("Buy Currency Test", &handle_buy_currency_test)); menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui)); @@ -5493,6 +5502,7 @@ class LLWorldSetAway : public view_listener_t if (gAgent.getAFK()) { gAgent.clearAFK(); + llinfos << "Spawning HTML help window" << llendl; } else { @@ -6045,10 +6055,10 @@ class LLShowFloater : public view_listener_t { JCFloaterAnimList::toggleInstance(LLSD()); } - else if (floater_name == "inworld browser") - { - LLFloaterMediaBrowser::toggleInstance(LLSD()); - } +//imprudence fixme else if (floater_name == "inworld browser") +// { +// LLFloaterMediaBrowser::toggle(); +// } else if (floater_name == "beacons") { LLFloaterBeacons::toggleInstance(LLSD()); @@ -7844,7 +7854,7 @@ void handle_grab_texture(void* data) // user know that the image is now in inventory. if(view) { - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); + LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); view->getPanel()->openSelected(); @@ -8048,13 +8058,7 @@ void handle_load_from_xml(void*) void handle_web_browser_test(void*) { - const bool open_links_externally = false; - const bool open_app_slurls = true; - LLFloaterHtml::getInstance()->show( - "http://secondlife.com/app/search/slurls.html", - "Web Browser Test", - open_links_externally, - open_app_slurls); + LLWeb::loadURL("http://secondlife.com/app/search/slurls.html"); } void handle_buy_currency_test(void*) diff --git a/linden/indra/newview/llviewermenufile.cpp b/linden/indra/newview/llviewermenufile.cpp index 364dcfd3b..d3473df9c 100644 --- a/linden/indra/newview/llviewermenufile.cpp +++ b/linden/indra/newview/llviewermenufile.cpp @@ -66,7 +66,7 @@ #include "llstring.h" #include "lltransactiontypes.h" #include "lluuid.h" -#include "vorbisencode.h" +#include "llvorbisencode.h" // system libraries #include <boost/tokenizer.hpp> diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index bfd104536..9f6ae3d0b 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -37,7 +37,7 @@ #include <deque> -#include "audioengine.h" +#include "llaudioengine.h" #include "indra_constants.h" #include "lscript_byteformat.h" #include "mean_collision_data.h" @@ -972,7 +972,7 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name) LL_DEBUGS("Messaging") << "Highlighting" << item->getUUID() << LL_ENDL; //highlight item - LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); + LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); gFocusMgr.setKeyboardFocus(focus_ctrl); } @@ -5197,11 +5197,11 @@ void mean_name_callback(const LLUUID &id, const std::string& first, const std::s return; } - static const int max_collision_list_size = 20; + static const U32 max_collision_list_size = 20; if (gMeanCollisionList.size() > max_collision_list_size) { mean_collision_list_t::iterator iter = gMeanCollisionList.begin(); - for (S32 i=0; i<max_collision_list_size; i++) iter++; + for (U32 i=0; i<max_collision_list_size; i++) iter++; for_each(iter, gMeanCollisionList.end(), DeletePointer()); gMeanCollisionList.erase(iter, gMeanCollisionList.end()); } diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index a85458397..b40d4e03a 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp @@ -34,7 +34,7 @@ #include "llviewerobject.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "imageids.h" #include "indra_constants.h" #include "llmath.h" diff --git a/linden/indra/newview/llviewerparcelmedia.cpp b/linden/indra/newview/llviewerparcelmedia.cpp index b98f418d4..c7f0c4bbe 100644 --- a/linden/indra/newview/llviewerparcelmedia.cpp +++ b/linden/indra/newview/llviewerparcelmedia.cpp @@ -41,47 +41,22 @@ #include "llviewerparcelmgr.h" #include "lluuid.h" #include "message.h" +#include "llviewermediafocus.h" #include "llviewerparcelmediaautoplay.h" #include "llviewerwindow.h" #include "llfirstuse.h" +#include "llpluginclassmedia.h" // Static Variables S32 LLViewerParcelMedia::sMediaParcelLocalID = 0; LLUUID LLViewerParcelMedia::sMediaRegionID; +viewer_media_t LLViewerParcelMedia::sMediaImpl; + // Local functions bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel); -// Move this to its own file. -// helper class that tries to download a URL from a web site and calls a method -// on the Panel Land Media and to discover the MIME type -class LLMimeDiscoveryResponder : public LLHTTPClient::Responder -{ -public: - LLMimeDiscoveryResponder( ) - {} - - - - virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) - { - std::string media_type = content["content-type"].asString(); - std::string::size_type idx1 = media_type.find_first_of(";"); - std::string mime_type = media_type.substr(0, idx1); - completeAny(status, mime_type); - } - - virtual void error( U32 status, const std::string& reason ) - { - completeAny(status, "none/none"); - } - - void completeAny(U32 status, const std::string& mime_type) - { - LLViewerMedia::setMimeType(mime_type); - } -}; // static void LLViewerParcelMedia::initClass() @@ -92,6 +67,13 @@ void LLViewerParcelMedia::initClass() LLViewerParcelMediaAutoPlay::initClass(); } +//static +void LLViewerParcelMedia::cleanupClass() +{ + // This needs to be destroyed before global destructor time. + sMediaImpl = NULL; +} + ////////////////////////////////////////////////////////////////////////////////////////// // static void LLViewerParcelMedia::update(LLParcel* parcel) @@ -105,6 +87,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel) { sMediaRegionID = LLUUID() ; stop() ; + LL_DEBUGS("Media") << "no agent region, bailing out." << LL_ENDL; return ; } @@ -115,64 +98,54 @@ void LLViewerParcelMedia::update(LLParcel* parcel) LLUUID regionid = gAgent.getRegion()->getRegionID(); if (parcelid != sMediaParcelLocalID || regionid != sMediaRegionID) { + LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL; sMediaParcelLocalID = parcelid; sMediaRegionID = regionid; new_parcel = true; } std::string mediaUrl = std::string ( parcel->getMediaURL () ); + std::string mediaCurrentUrl = std::string( parcel->getMediaCurrentURL()); + + // First use warning + if( ! mediaUrl.empty() && gSavedSettings.getWarning("FirstStreamingVideo") ) + { + LLNotifications::instance().add("ParcelCanPlayMedia", LLSD(), LLSD(), + boost::bind(callback_play_media, _1, _2, parcel)); + return; + + } + + // if we have a current (link sharing) url, use it instead + if (mediaCurrentUrl != "" && parcel->getMediaType() == "text/html") + { + mediaUrl = mediaCurrentUrl; + } + LLStringUtil::trim(mediaUrl); + + // If no parcel media is playing, nothing left to do + if(sMediaImpl.isNull()) - // has something changed? - if ( ( LLViewerMedia::getMediaURL() != mediaUrl ) - || ( LLViewerMedia::getMediaTextureID() != parcel->getMediaID () ) ) { - bool video_was_playing = FALSE; - bool same_media_id = LLViewerMedia::getMediaTextureID() == parcel->getMediaID (); + return; + } - if (LLViewerMedia::isMediaPlaying()) + // Media is playing...has something changed? + else if (( sMediaImpl->getMediaURL() != mediaUrl ) + || ( sMediaImpl->getMediaTextureID() != parcel->getMediaID() ) + || ( sMediaImpl->getMimeType() != parcel->getMediaType() )) + { + // Only play if the media types are the same. + if(sMediaImpl->getMimeType() == parcel->getMediaType()) { - video_was_playing = TRUE; + play(parcel); } - if ( !mediaUrl.empty() && same_media_id && ! new_parcel) - { - // Someone has "changed the channel", changing the URL of a video - // you were already watching. Automatically play provided the texture ID is the same - if (video_was_playing) - { - // Poke the mime type in before calling play. - // This is necessary because in this instance we are not waiting - // for the results of a header curl. In order to change the channel - // a mime type MUST be provided. - LLViewerMedia::setMimeType(parcel->getMediaType()); - play(parcel); - } - } else { stop(); } - - // Discover the MIME type - // Disabled for the time being. Get the mime type from the parcel. - if(gSavedSettings.getBOOL("AutoMimeDiscovery")) - { - LLHTTPClient::getHeaderOnly( mediaUrl, new LLMimeDiscoveryResponder()); - } - else - { - LLViewerMedia::setMimeType(parcel->getMediaType()); - } - - // First use warning - if( gSavedSettings.getWarning("FirstStreamingVideo") ) - { - LLNotifications::instance().add("ParcelCanPlayMedia", LLSD(), LLSD(), - boost::bind(callback_play_media, _1, _2, parcel)); - - } - } } else @@ -183,7 +156,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel) /* else { - // no audio player, do a first use dialog if their is media here + // no audio player, do a first use dialog if there is media here if (parcel) { std::string mediaUrl = std::string ( parcel->getMediaURL () ); @@ -212,15 +185,54 @@ void LLViewerParcelMedia::play(LLParcel* parcel) return; std::string media_url = parcel->getMediaURL(); + std::string media_current_url = parcel->getMediaCurrentURL(); std::string mime_type = parcel->getMediaType(); LLUUID placeholder_texture_id = parcel->getMediaID(); U8 media_auto_scale = parcel->getMediaAutoScale(); U8 media_loop = parcel->getMediaLoop(); S32 media_width = parcel->getMediaWidth(); S32 media_height = parcel->getMediaHeight(); - LLViewerMedia::play(media_url, mime_type, placeholder_texture_id, - media_width, media_height, media_auto_scale, - media_loop); + + if(sMediaImpl) + { + // If the url and mime type are the same, call play again + if(sMediaImpl->getMediaURL() == media_url + && sMediaImpl->getMimeType() == mime_type + && sMediaImpl->getMediaTextureID() == placeholder_texture_id) + { + LL_DEBUGS("Media") << "playing with existing url " << media_url << LL_ENDL; + + sMediaImpl->play(); + } + // Else if the texture id's are the same, navigate and rediscover type + // MBW -- This causes other state from the previous parcel (texture size, autoscale, and looping) to get re-used incorrectly. + // It's also not really necessary -- just creating a new instance is fine. +// else if(sMediaImpl->getMediaTextureID() == placeholder_texture_id) +// { +// sMediaImpl->navigateTo(media_url, mime_type, true); +// } + else + { + // Since the texture id is different, we need to generate a new impl + LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; + + // Delete the old one first so they don't fight over the texture. + sMediaImpl->stop(); + + sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id, + media_width, media_height, media_auto_scale, + media_loop); + } + } + else + { + // There is no media impl, make a new one + sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id, + media_width, media_height, media_auto_scale, + media_loop); + } + + LLFirstUse::useMedia(); LLViewerParcelMediaAutoPlay::playStarted(); @@ -229,20 +241,38 @@ void LLViewerParcelMedia::play(LLParcel* parcel) // static void LLViewerParcelMedia::stop() { + if(sMediaImpl.isNull()) + { + return; + } + + // We need to remove the media HUD if it is up. + LLViewerMediaFocus::getInstance()->clearFocus(); - LLViewerMedia::stop(); + // This will kill the media instance. + sMediaImpl->stop(); + sMediaImpl = NULL; } // static void LLViewerParcelMedia::pause() { - LLViewerMedia::pause(); + if(sMediaImpl.isNull()) + { + return; + } + sMediaImpl->pause(); } // static void LLViewerParcelMedia::start() { - LLViewerMedia::start(); + if(sMediaImpl.isNull()) + { + return; + } + sMediaImpl->start(); + LLFirstUse::useMedia(); LLViewerParcelMediaAutoPlay::playStarted(); @@ -251,16 +281,41 @@ void LLViewerParcelMedia::start() // static void LLViewerParcelMedia::seek(F32 time) { - LLViewerMedia::seek(time); + if(sMediaImpl.isNull()) + { + return; + } + sMediaImpl->seek(time); } - // static -LLMediaBase::EStatus LLViewerParcelMedia::getStatus() +void LLViewerParcelMedia::focus(bool focus) { - return LLViewerMedia::getStatus(); + sMediaImpl->focus(focus); +} + +// static +LLViewerMediaImpl::EMediaStatus LLViewerParcelMedia::getStatus() +{ + LLViewerMediaImpl::EMediaStatus result = LLViewerMediaImpl::MEDIA_NONE; + + if(sMediaImpl.notNull() && sMediaImpl->hasMedia()) + { + result = sMediaImpl->getMediaPlugin()->getStatus(); + } + + return result; } +// static +std::string LLViewerParcelMedia::getMimeType() +{ + return sMediaImpl.notNull() ? sMediaImpl->getMimeType() : "none/none"; +} +viewer_media_t LLViewerParcelMedia::getParcelMedia() +{ + return sMediaImpl; +} ////////////////////////////////////////////////////////////////////////////////////////// // static void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ) @@ -298,7 +353,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg if(( command == PARCEL_MEDIA_COMMAND_PLAY ) || ( command == PARCEL_MEDIA_COMMAND_LOOP )) { - if (LLViewerMedia::isMediaPaused()) + if (getStatus() == LLViewerMediaImpl::MEDIA_PAUSED) { start(); } @@ -318,7 +373,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg if (flags & (1<<PARCEL_MEDIA_COMMAND_TIME)) { - if(! LLViewerMedia::hasMedia()) + if(sMediaImpl.isNull()) { LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); play(parcel); @@ -382,6 +437,119 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void * } } } +// Static +///////////////////////////////////////////////////////////////////////////////////////// +void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url) +{ + std::string region_url = gAgent.getRegion()->getCapability("ParcelNavigateMedia"); + if (!region_url.empty()) + { + // send navigate event to sim for link sharing + LLSD body; + body["agent-id"] = gAgent.getID(); + body["local-id"] = LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID(); + body["url"] = url; + LLHTTPClient::post(region_url, body, new LLHTTPClient::Responder); + } + else + { + llwarns << "can't get ParcelNavigateMedia capability" << llendl; + } + +} + +///////////////////////////////////////////////////////////////////////////////////////// +// inherited from LLViewerMediaObserver +// virtual +void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + switch(event) + { + case MEDIA_EVENT_CONTENT_UPDATED: + { + // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL; + }; + break; + + case MEDIA_EVENT_TIME_DURATION_UPDATED: + { + // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_SIZE_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL; + }; + break; + + case MEDIA_EVENT_CURSOR_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_NAVIGATE_BEGIN: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << LL_ENDL; + }; + break; + + case MEDIA_EVENT_NAVIGATE_COMPLETE: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_PROGRESS_UPDATED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL; + }; + break; + + case MEDIA_EVENT_STATUS_TEXT_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_LOCATION_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_CLICK_LINK_HREF: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; + }; + break; + + case MEDIA_EVENT_PLUGIN_FAILED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; + }; + break; + + case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; + }; + break; + + case MEDIA_EVENT_NAME_CHANGED: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; + }; + break; + }; +} bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel) { @@ -399,3 +567,19 @@ bool callback_play_media(const LLSD& notification, const LLSD& response, LLParce return false; } +// TODO: observer +/* +void LLViewerParcelMediaNavigationObserver::onNavigateComplete( const EventType& event_in ) +{ + std::string url = event_in.getStringValue(); + + if (mCurrentURL != url && ! mFromMessage) + { + LLViewerParcelMedia::sendMediaNavigateMessage(url); + } + + mCurrentURL = url; + mFromMessage = false; + +} +*/ diff --git a/linden/indra/newview/llviewerparcelmedia.h b/linden/indra/newview/llviewerparcelmedia.h index 18988704d..0f1e85c78 100644 --- a/linden/indra/newview/llviewerparcelmedia.h +++ b/linden/indra/newview/llviewerparcelmedia.h @@ -33,18 +33,22 @@ #ifndef LLVIEWERPARCELMEDIA_H #define LLVIEWERPARCELMEDIA_H -#include "llmediabase.h" +#include "llviewermedia.h" class LLMessageSystem; class LLParcel; +class LLViewerParcelMediaNavigationObserver; + // This class understands land parcels, network traffic, LSL media // transport commands, and talks to the LLViewerMedia class to actually // do playback. It allows us to remove code from LLViewerParcelMgr. -class LLViewerParcelMedia +class LLViewerParcelMedia : public LLViewerMediaObserver { + LOG_CLASS(LLViewerParcelMedia); public: static void initClass(); + static void cleanupClass(); static void update(LLParcel* parcel); // called when the agent's parcel has a new URL, or the agent has @@ -60,17 +64,38 @@ class LLViewerParcelMedia static void start(); // restart after pause - no need for all the setup + static void focus(bool focus); + static void seek(F32 time); // jump to timecode time - static LLMediaBase::EStatus getStatus(); + static LLViewerMediaImpl::EMediaStatus getStatus(); + static std::string getMimeType(); + static viewer_media_t getParcelMedia(); static void processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ); static void processParcelMediaUpdate( LLMessageSystem *msg, void ** ); + static void sendMediaNavigateMessage(const std::string& url); + + // inherited from LLViewerMediaObserver + virtual void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); public: static S32 sMediaParcelLocalID; static LLUUID sMediaRegionID; + // HACK: this will change with Media on a Prim + static viewer_media_t sMediaImpl; +}; + + +class LLViewerParcelMediaNavigationObserver +{ +public: + std::string mCurrentURL; + bool mFromMessage; + + // void onNavigateComplete( const EventType& event_in ); + }; #endif diff --git a/linden/indra/newview/llviewerparcelmediaautoplay.cpp b/linden/indra/newview/llviewerparcelmediaautoplay.cpp index dbb9c3200..ccd6b14d3 100644 --- a/linden/indra/newview/llviewerparcelmediaautoplay.cpp +++ b/linden/indra/newview/llviewerparcelmediaautoplay.cpp @@ -109,7 +109,7 @@ BOOL LLViewerParcelMediaAutoPlay::tick() if ((!mPlayed) && // if we've never played (mTimeInParcel > AUTOPLAY_TIME) && // and if we've been here for so many seconds (this_media_url.size() != 0) && // and if the parcel has media - (!LLViewerMedia::isMediaPlaying())) // and if the media is not already playing + (LLViewerParcelMedia::sMediaImpl.isNull())) // and if the media is not already playing { if (this_media_texture_id.notNull()) // and if the media texture is good { diff --git a/linden/indra/newview/llviewerparcelmediaautoplay.h b/linden/indra/newview/llviewerparcelmediaautoplay.h index cc2e70b1b..16279e7f1 100644 --- a/linden/indra/newview/llviewerparcelmediaautoplay.h +++ b/linden/indra/newview/llviewerparcelmediaautoplay.h @@ -33,7 +33,6 @@ #ifndef LLVIEWERPARCELMEDIAAUTOPLAY_H #define LLVIEWERPARCELMEDIAAUTOPLAY_H -#include "llmediabase.h" #include "lltimer.h" // timer to automatically play media diff --git a/linden/indra/newview/llviewerparcelmgr.cpp b/linden/indra/newview/llviewerparcelmgr.cpp index 61b91fe67..3ed41a3b5 100644 --- a/linden/indra/newview/llviewerparcelmgr.cpp +++ b/linden/indra/newview/llviewerparcelmgr.cpp @@ -35,7 +35,7 @@ #include "llviewerparcelmgr.h" // Library includes -#include "audioengine.h" +#include "llaudioengine.h" #include "indra_constants.h" #include "llcachename.h" #include "llgl.h" @@ -1599,6 +1599,9 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // Request access list information for this land LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN); + // Request the media url filter list for this land + LLViewerParcelMgr::getInstance()->requestParcelMediaURLFilter(); + // Request dwell for this land, if it's not public land. LLViewerParcelMgr::getInstance()->mSelectedDwell = 0.f; if (0 != local_id) @@ -1726,21 +1729,6 @@ void optionally_start_music(const std::string& music_url) } } - -void callback_start_music(S32 option, void* data) -{ - if (option == 0) - { - // Before the callback, we verified the url was good. - // We fetch again to avoid lag while loading. - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - gAudiop->startInternetStream(parcel->getMusicURL()); - - LLOverlayBar::musicFirstRun(); - } - gSavedSettings.setWarning("FirstStreamingMusic", FALSE); -} - // static void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void **user) { @@ -1937,6 +1925,66 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which) } } +class LLParcelMediaURLFilterResponder : public LLHTTPClient::Responder +{ + virtual void result(const LLSD& content) + { + LLViewerParcelMgr::getInstance()->receiveParcelMediaURLFilter(content); + } +}; + +void LLViewerParcelMgr::requestParcelMediaURLFilter() +{ + if (!mSelected) + { + return; + } + + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); + if (!region) + { + return; + } + + LLParcel* parcel = mCurrentParcel; + if (!parcel) + { + llwarns << "no parcel" << llendl; + return; + } + + LLSD body; + body["local-id"] = parcel->getLocalID(); + body["list"] = parcel->getMediaURLFilterList(); + + std::string url = region->getCapability("ParcelMediaURLFilterList"); + if (!url.empty()) + { + LLHTTPClient::post(url, body, new LLParcelMediaURLFilterResponder); + } + else + { + llwarns << "can't get ParcelMediaURLFilterList cap" << llendl; + } +} + + +void LLViewerParcelMgr::receiveParcelMediaURLFilter(const LLSD &content) +{ + if (content.has("list")) + { + LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel; + if (!parcel) return; + + if (content["local-id"].asInteger() == parcel->getLocalID()) + { + parcel->setMediaURLFilterList(content["list"]); + + LLViewerParcelMgr::getInstance()->notifyObservers(); + } + } +} + void LLViewerParcelMgr::deedLandToGroup() { diff --git a/linden/indra/newview/llviewerparcelmgr.h b/linden/indra/newview/llviewerparcelmgr.h index 9f762a186..9bf609639 100644 --- a/linden/indra/newview/llviewerparcelmgr.h +++ b/linden/indra/newview/llviewerparcelmgr.h @@ -198,6 +198,11 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListRequest(U32 flags); + // asks for the parcel's media url filter list + void requestParcelMediaURLFilter(); + // receive the response + void receiveParcelMediaURLFilter(const LLSD &content); + // Dwell is not part of the usual parcel update information because the // simulator doesn't actually know the per-parcel dwell. Ack! We have // to get it out of the database. diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index 4257f70da..f06c3d8b5 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp @@ -322,7 +322,7 @@ void LLViewerRegion::loadCache() LLUUID cache_id; nread = fread(&cache_id.mData, 1, UUID_BYTES, fp); - if (nread != UUID_BYTES || mCacheID != cache_id) + if (nread != (size_t)UUID_BYTES || mCacheID != cache_id) { llinfos << "Cache ID doesn't match for this region, discarding" << llendl; @@ -398,7 +398,7 @@ void LLViewerRegion::saveCache() } // write the cache id for this sim - if (fwrite(&mCacheID.mData, 1, UUID_BYTES, fp) != UUID_BYTES) + if (fwrite(&mCacheID.mData, 1, UUID_BYTES, fp) != (size_t)UUID_BYTES) { llwarns << "Short write" << llendl; } @@ -1428,6 +1428,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("ParcelPropertiesUpdate"); + capabilityNames.append("ParcelMediaURLFilterList"); + capabilityNames.append("ParcelNavigateMedia"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp index 981c9bcf6..34577a7eb 100644 --- a/linden/indra/newview/llviewertexteditor.cpp +++ b/linden/indra/newview/llviewertexteditor.cpp @@ -33,7 +33,7 @@ #include "llviewerprecompiledheaders.h" #include "llfocusmgr.h" -#include "audioengine.h" +#include "llaudioengine.h" #include "llagent.h" #include "llinventory.h" #include "llinventorymodel.h" diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index eb8977c63..f7713c22c 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -54,7 +54,7 @@ // // linden library includes -#include "audioengine.h" // mute on minimize +#include "llaudioengine.h" // mute on minimize #include "indra_constants.h" #include "llassetstorage.h" #include "llfontgl.h" @@ -156,7 +156,6 @@ #include "lltoolselectland.h" #include "lltoolview.h" #include "lluictrlfactory.h" -#include "lluploaddialog.h" #include "llurldispatcher.h" // SLURL from other app instance #include "llvieweraudio.h" #include "llviewercamera.h" @@ -164,6 +163,8 @@ #include "llviewerimagelist.h" #include "llviewerinventory.h" #include "llviewerkeyboard.h" +#include "llviewermedia.h" +#include "llviewermediafocus.h" #include "llviewermenu.h" #include "llviewermessage.h" #include "llviewerobjectlist.h" @@ -310,7 +311,9 @@ class LLDebugText S32 hours = (S32)(time / (60*60)); S32 mins = (S32)((time - hours*(60*60)) / 60); S32 secs = (S32)((time - hours*(60*60) - mins*60)); - addText(xpos, ypos, llformat(" Debug %d: %d:%02d:%02d", idx, hours,mins,secs)); ypos += y_inc2; + std::string label = gDebugTimerLabel[idx]; + if (label.empty()) label = llformat("Debug: %d", idx); + addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2; } F32 time = gFrameTimeSeconds; @@ -795,6 +798,7 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK if (handle) return handle; + // *HACK: this should be rolled into the composite tool logic, not // hardcoded at the top level. if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance()) @@ -1141,7 +1145,7 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data) case SLURL_MESSAGE_TYPE: // received URL std::string url = (const char*)data; - LLWebBrowserCtrl* web = NULL; + LLMediaCtrl* web = NULL; const bool trusted_browser = false; if (LLURLDispatcher::dispatch(url, web, trusted_browser)) { @@ -1736,6 +1740,19 @@ void LLViewerWindow::initWorldUI() // menu holder appears on top to get first pass at all mouse events mRootView->sendChildToFront(gMenuHolder); + + if ( gHUDView == NULL ) + { + LLRect hud_rect = full_window; + hud_rect.mBottom += 50; + if (gMenuBarView) + { + hud_rect.mTop -= gMenuBarView->getRect().getHeight(); + } + gHUDView = new LLHUDView(hud_rect); + // put behind everything else in the UI + mRootView->addChildAtEnd(gHUDView); + } } // Destroy the UI @@ -2180,7 +2197,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) if (key < 0x80) { // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first. - return gFocusMgr.childHasKeyboardFocus(mRootView); + return (gFocusMgr.getKeyboardFocus() != NULL); } } @@ -2243,7 +2260,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } // Traverses up the hierarchy - LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus(); + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); if( keyboard_focus ) { // arrow keys move avatar while chatting hack @@ -2377,7 +2394,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask) } // Traverses up the hierarchy - LLView* keyboard_focus = gFocusMgr.getKeyboardFocus(); + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); if( keyboard_focus ) { if (keyboard_focus->handleUnicodeChar(uni_char, FALSE)) @@ -2530,7 +2547,7 @@ BOOL LLViewerWindow::handlePerFrameHover() } // clean up current focus - LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (cur_focus) { if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain()) @@ -2910,12 +2927,18 @@ BOOL LLViewerWindow::handlePerFrameHover() { do_pick = FALSE; } + + if(LLViewerMediaFocus::getInstance()->getFocus()) + { + // When in-world media is in focus, pick every frame so that browser mouse-overs, dragging scrollbars, etc. work properly. + do_pick = TRUE; + } if (do_pick) { mouse_moved_since_pick = FALSE; mPickTimer.reset(); - pickAsync(getCurrentMouseX(), getCurrentMouseY(), mask, hoverPickCallback, TRUE); + pickAsync(getCurrentMouseX(), getCurrentMouseY(), mask, hoverPickCallback, TRUE, TRUE); } previous_x = x; @@ -4694,7 +4717,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL result_first_try = FALSE; BOOL result_second_try = FALSE; - LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus(); + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); send_agent_pause(); llinfos << "Stopping GL during changeDisplaySettings" << llendl; stopGL(); @@ -4923,7 +4946,6 @@ LLBottomPanel::LLBottomPanel(const LLRect &rect) : mFactoryMap["toolbar"] = LLCallbackMap(createToolBar, NULL); mFactoryMap["overlay"] = LLCallbackMap(createOverlayBar, NULL); - mFactoryMap["hud"] = LLCallbackMap(createHUD, NULL); LLUICtrlFactory::getInstance()->buildPanel(this, "panel_bars.xml", &getFactoryMap()); setOrigin(rect.mLeft, rect.mBottom); @@ -4946,12 +4968,6 @@ void LLBottomPanel::draw() LLPanel::draw(); } -void* LLBottomPanel::createHUD(void* data) -{ - gHUDView = new LLHUDView(); - return gHUDView; -} - void* LLBottomPanel::createOverlayBar(void* data) { @@ -5164,12 +5180,8 @@ void LLPickInfo::updateXYCoords() LLPointer<LLViewerImage> imagep = gImageList.getImage(tep->getID()); if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull()) { - LLCoordGL coords; - - coords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth()); - coords.mY = llround(mUVCoords.mV[VY] * (F32)imagep->getHeight()); - - gViewerWindow->getWindow()->convertCoords(coords, &mXYCoords); + mXYCoords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth()); + mXYCoords.mY = llround((1.f - mUVCoords.mV[VY]) * (F32)imagep->getHeight()); } } } diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index c8b26be3a..14b8d3e7a 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -37,7 +37,7 @@ #include <stdio.h> #include <ctype.h> -#include "audioengine.h" +#include "llaudioengine.h" #include "noise.h" #include "llagent.h" // Get state values from here @@ -69,6 +69,7 @@ #include "lltoolmorph.h" #include "llviewercamera.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -3825,6 +3826,18 @@ void LLVOAvatar::idleUpdateTractorBeam() { return; } + const LLPickInfo& pick = gViewerWindow->getLastPick(); + + // No beam for media textures + // TODO: this will change for Media on a Prim + if(pick.getObject() && pick.mObjectFace >= 0) + { + const LLTextureEntry* tep = pick.getObject()->getTE(pick.mObjectFace); + if (tep && LLViewerMedia::textureHasMedia(tep->getID())) + { + return; + } + } // This is only done for yourself (maybe it should be in the agent?) if (!needsRenderBeam() || !mIsBuilt) @@ -3935,7 +3948,7 @@ void LLVOAvatar::idleUpdateTractorBeam() } else { - const LLPickInfo& pick = gViewerWindow->getLastPick(); + mBeam->setPositionGlobal(pick.mPosGlobal); } diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index 5f7327d88..385dbe0c4 100644 --- a/linden/indra/newview/llvovolume.cpp +++ b/linden/indra/newview/llvovolume.cpp @@ -1694,7 +1694,7 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p trans_mat.translate(getRegion()->getOriginAgent()); } - volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans); + volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); nodep->mSilhouetteExists = TRUE; } diff --git a/linden/indra/newview/llweb.cpp b/linden/indra/newview/llweb.cpp index fb4b063eb..7021b4815 100644 --- a/linden/indra/newview/llweb.cpp +++ b/linden/indra/newview/llweb.cpp @@ -38,7 +38,7 @@ #include "llviewerwindow.h" #include "llviewercontrol.h" -#include "llfloaterhtmlhelp.h" +#include "llfloatermediabrowser.h" // static void LLWeb::initClass() diff --git a/linden/indra/newview/mozilla-powerpc-darwin-readme.txt b/linden/indra/newview/mozilla-powerpc-darwin-readme.txt index be67ad31c..e69de29bb 100644 --- a/linden/indra/newview/mozilla-powerpc-darwin-readme.txt +++ b/linden/indra/newview/mozilla-powerpc-darwin-readme.txt @@ -1,71 +0,0 @@ -NOTE: these directions have been obsoleted. There are now shell scripts that will check out, build, and package the necessary pieces -of the mozilla code in lindelib/mozilla-1.8.0/mac-build. I'm leaving this file here for historical interest. -------------- -Written by Monroe on June 17, 2005. - -Here's how to rebuild the Mozilla components for the Mac build. - -Check out the mozilla source from cvs - -cd to the mozilla directory (the same one that contains client.mk) - -cp .mozconfig.opt.shared.small .mozconfig - -Add the following line to the .mozconfig file you just created: - -ac_add_options --with-macos-sdk=/Developer/SDKs/MacOSX10.2.8.sdk - -make -f client.mk build - -wait a while. - -The build products you need to extract are in objdir-opt-shared-small/dist/bin and objdir-opt-shared-small/dist/lib. - -Copy the following to linden/libraries/firefox-1.0.4/<arch>/lib_release and linden/libraries/firefox-1.0.4/<arch>/lib_release: - -objdir-opt-shared-small/dist/lib/libembed_base_s.a -objdir-opt-shared-small/dist/lib/libxpcomglue_s.a -objdir-opt-shared-small/dist/bin/libxpcom.dylib -objdir-opt-shared-small/dist/bin/libplds4.dylib -objdir-opt-shared-small/dist/bin/libplc4.dylib -objdir-opt-shared-small/dist/bin/libnspr4.dylib -objdir-opt-shared-small/dist/bin/libgkgfx.dylib - -This first part should be repeated with .mozconfig.debug.shared.small to generate the libraries in the two matching lib_debug directories. The debug version of the bin directory is prohibitively large, so we're just using the release version of that part. - -Much of the contents of objdir-opt-shared-small/dist/bin also needs to go into a tar file that will be used when generating the application bundle. - -The bin directory will be populated with symlinks. If you just tar it up as-is, you'll get a tar file full of symlinks, which is not useful. - -Use 'cp -RL source dest' to make a copy of the bin directory with all symlinks expanded. This will be more useful. - -Remove things that aren't needed. This includes at least: - -asdecode -firefox -firefox-bin -firefox-config -LICENSE -nsinstall -mangle -regxpcom -regchrome -README.txt -run-mozilla.sh -xpcshell -xpt_dump -shlibsign -xpt_link -xpidl -xpicleanup - -There may be other pieces that aren't needed as well. I expect this will be refined moving forward. - -Because of the way the tar file will be expanded (directly inside the application bundle, in Contents/MacOS), it's important to create it so that it won't expand at a subdirectory of the current path. The way to to this is to cd to the dist/bin directory and do something like this: - -tar -zcvf ../mozilla-powerpc-darwin.tgz . - -This will create a tar file containing everything in the current directory, and will place the file one level up (so it doesn't interfere with its own creation). This file should replace the file with the above name checked into cvs in linden/indra/newview/. One of the lines in the shell script phase of the build extracts it appropriately into the application bundle. - -If any of this is unclear, please contact Monroe and I'll try to clarify and update this file. - diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index f10aca500..72da3c631 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -35,7 +35,7 @@ #include "pipeline.h" // library includes -#include "audioengine.h" // For MAX_BUFFERS for debugging. +#include "llaudioengine.h" // For MAX_BUFFERS for debugging. #include "imageids.h" #include "llerror.h" #include "llviewercontrol.h" diff --git a/linden/indra/newview/skins/default/textures/textures.xml b/linden/indra/newview/skins/default/textures/textures.xml index 0b4a08867..f2189a450 100644 --- a/linden/indra/newview/skins/default/textures/textures.xml +++ b/linden/indra/newview/skins/default/textures/textures.xml @@ -16,7 +16,9 @@ <texture name="toolbar_btn_selected.tga" scale_left="7" scale_top="32" scale_right="121" scale_bottom="0" /> <texture name="button_enabled_selected_32x128.tga" preload="true" scale_left="16" scale_top="16" scale_right="112" scale_bottom="16" /> - + + <texture name="media_panel_bg.png" preload="true" scale_left="9" scale_top="9" scale_right="9" scale_bottom="9" /> + <texture name="media_panel_hoverrectangle.png" preload="true" scale_left="9" scale_top="9" scale_right="9" scale_bottom="9" /> <texture name="checkbox_disabled_false.tga" preload="true"/> <texture name="checkbox_disabled_true.tga" preload="true"/> <texture name="checkbox_enabled_false.tga" preload="true"/> @@ -376,7 +378,23 @@ <texture name="default_profile_picture.j2c"/> <texture name="locked_image.j2c"/> + <!-- Kitty Viewer Art --> <texture name="Inv_WindLight" file_name="Inv_WindLight.png" preload="false" /> <texture name="Inv_WaterLight" file_name="Inv_WaterLight.png" preload="false" /> + + <texture name="media_btn_back.png"/> + <texture name="media_btn_done.png"/> + <texture name="media_btn_forward.png"/> + <texture name="media_btn_home.png"/> + <texture name="media_btn_newwindow.png"/> + <texture name="media_btn_optimalzoom.png"/> + <texture name="media_btn_reload.png"/> + <texture name="media_btn_scrolldown.png"/> + <texture name="media_btn_scrollleft.png"/> + <texture name="media_btn_scrollright.png"/> + <texture name="media_btn_scrollup.png"/> + <texture name="media_btn_stoploading.png"/> + <texture name="media_panel_divider.png"/> + </textures> diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_about_land.xml b/linden/indra/newview/skins/default/xui/en-us/floater_about_land.xml index 9bc91e742..c8aacbaa7 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_about_land.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_about_land.xml @@ -800,143 +800,633 @@ Only large parcels can be listed in search. No Pushing (Region Override) </string> </panel> - <panel border="true" bottom="-349" enabled="true" follows="left|top|right|bottom" - height="363" label="Media" left="1" mouse_opaque="true" - name="land_media_panel" width="458"> - <text type="string" length="1" bottom="-25" follows="left|top" font="SansSerifSmall" halign="left" height="16" - left="10" mouse_opaque="true" name="with media:" width="65"> - Media Type: - </text> - <combo_box allow_text_entry="false" bottom_delta="0" follows="left|top" height="18" - left="80" max_chars="20" name="media type" - tool_tip="Specify if the URL is a movie, web page, or other media" - width="120" /> - <text bottom_delta="0" follows="left|top" font="SansSerifSmall" height="16" - left_delta="130" name="mime_type" width="200" /> - <text type="string" length="1" bottom_delta="-20" follows="left|top" font="SansSerifSmall" halign="left" - height="16" left="10" name="at URL:" width="65"> - Media URL: - </text> - <line_editor bottom_delta="0" follows="left|top" font="SansSerifSmall" height="16" left="80" - max_length="255" name="media_url" right="-80" - select_all_on_focus_received="true" select_on_focus="true" - text_readonly_color="0.576471 0.662745 0.835294 1" /> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" halign="center" - height="16" label="Set..." label_selected="Set..." mouse_opaque="true" - name="set_media_url" right="-12" scale_image="true" width="60" /> - <text type="string" length="1" bottom_delta="-20" follows="left|top" font="SansSerifSmall" halign="left" - height="16" left="10" name="Description:" width="364"> + <panel + border="true" + border_visible="true" + bottom="-363" + enabled="true" + follows="left|top|right|bottom" + height="513" + label="Media" + left="1" + mouse_opaque="true" + name="land_media_panel" + width="458"> + <text + bottom="-25" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="16" + left="10" + length="1" + mouse_opaque="true" + name="with media:" + type="string" + width="65"> + Type: + </text> + <combo_box + allow_text_entry="false" + bottom_delta="0" + follows="left|top" + height="18" + left="80" + max_chars="20" + name="media type" + tool_tip="Specify if the URL is a movie, web page, or other media" + width="120" /> + <text + bottom_delta="0" + follows="left|top" + font="SansSerifSmall" + height="16" + left_delta="130" + name="mime_type" + width="200" /> + <text type="string" + bottom_delta="-21" + follows="left|top" + font="SansSerifSmall" halign="left" + height="16" + left="10" + length="1" + name="at URL:" + width="65"> + Home URL: + </text> + <line_editor + bottom_delta="0" + follows="left|top|right" + font="SansSerifSmall" + height="16" + left="80" + max_length="255" + name="media_url" + right="-90" + select_all_on_focus_received="true" + select_on_focus="true" + text_readonly_color="0.576471 0.662745 0.835294 1" /> + <button + bottom_delta="0" + follows="right|top" + font="SansSerifSmall" + halign="center" + height="16" + label="Set..." + label_selected="Set..." + mouse_opaque="true" + name="set_media_url" + right="-12" + scale_image="true" + width="70" /> + <text + bottom_delta="-22" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="16" + left="10" + length="1" + name="at URL:" + type="string" + width="65"> + Current URL: + </text> + <text + bottom_delta="0" + follows="left|top|right" + font="SansSerifSmall" + halign="left" + height="16" + left="80" + name="current_url" + right="-90" /> + <button + bottom_delta="0" + follows="right|top" + font="SansSerifSmall" + halign="center" + height="16" + label="Reset..." + label_selected="Reset..." + mouse_opaque="true" + name="reset_media_url" + right="-12" + scale_image="true" + width="70" /> + <check_box + bottom_delta="-22" + enabled="true" + follows="left|top" + font="SansSerifSmall" + height="16" + initial_value="false" + label="Hide URL" + left="80" + mouse_opaque="true" + name="hide_media_url" + radio_style="false" + tool_tip="Checking this option will hide the media URL from any non-authorized viewers of this parcel information. Note this is not available for HTML types." + width="150" /> + <text + bottom_delta="0" + follows="right|top" + font="SansSerifSmall" + halign="right" + height="16" + length="1" + name="media_reset" + right="-164" + tool_tip="Amount of time until parcel automatically reverts to default URL (0 for never return)" + type="string" + width="185"> + Return to Home URL in: + </text> + <spinner + bottom_delta="0" + decimal_digits="0" + enabled="false" + follows="right|top" + halign="right" + height="16" + increment="1" + initial_val="0" + max_val="1024" + min_val="0" + name="media_reset_time" + right="-90" + tool_tip="Amount of time until parcel reverts to default URL (0 for never return)" + width="64" /> + <text + bottom_delta="0" + follows="right|top" + font="SansSerifSmall" + halign="left" + height="16" + left_delta="70" + length="1" + name="minutes" + right="-10" + type="string"> + Minutes + </text> + <text + bottom_delta="-22" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="16" + left="10" + length="1" + name="Description:" + type="string" + width="364"> Description: </text> - <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0" - follows="left|top" font="SansSerifSmall" height="16" left="80" - max_length="255" name="url_description" right="-80" - select_all_on_focus_received="true" select_on_focus="true" - tool_tip="Text displayed next to play/load button" spell_check="true" /> - <text type="string" length="1" bottom_delta="-20" follows="left|top" font="SansSerifSmall" halign="left" - height="16" left="10" name="Media texture:" width="364"> - Replace -Texture: - </text> - <texture_picker allow_no_texture="true" bottom_delta="-64" can_apply_immediately="false" - default_image_name="Default" follows="left|top" height="80" label="" - left="80" name="media texture" tool_tip="Click to choose a picture" - width="64" /> - <text type="string" length="1" bottom_delta="48" follows="left|top" font="SansSerifSmall" halign="left" - height="16" left_delta="75" name="replace_texture_help" width="270"> - (Objects using this texture will show the movie or -web page after you click the play arrow.) - </text> - <text type="string" length="1" bottom_delta="-55" follows="left|top" font="SansSerifSmall" halign="left" - height="16" left="10" mouse_opaque="true" name="Options:" width="292"> - Media -Options: - </text> - <check_box bottom_delta="0" enabled="true" follows="left|top" font="SansSerifSmall" - height="16" initial_value="false" label="Auto scale" left="80" - mouse_opaque="true" name="media_auto_scale" radio_style="false" - tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required." - width="200" /> - <check_box bottom_delta="0" enabled="true" follows="left|top" font="SansSerifSmall" - height="16" initial_value="false" label="Loop Media" left="250" - mouse_opaque="true" name="media_loop" radio_style="false" - tool_tip="Play media in a loop. When the media has finished playing, it will restart from the beginning." - width="200" /> - <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" - height="16" initial_value="false" label="Hide Media URL" left="80" - mouse_opaque="true" name="hide_media_url" radio_style="false" - tool_tip="Checking this option will hide the media url to any non-authorized viewers of this parcel information. Note this is not available for HTML types." - width="200" /> - <check_box bottom_delta="0" enabled="true" follows="left|top" font="SansSerifSmall" - height="16" initial_value="false" label="Hide Music URL" left="250" - mouse_opaque="true" name="hide_music_url" radio_style="false" - tool_tip="Checking this option will hide the music url to any non-authorized viewers of this parcel information" - width="200" /> - <text type="string" length="1" bottom_delta="-25" follows="left|top" font="SansSerifSmall" halign="left" - height="16" left="85" name="media_size" - tool_tip="Size to render Web media, leave 0 for default." width="85"> - Media size: - </text> - <spinner bottom_delta="0" decimal_digits="0" enabled="false" follows="left|top" - halign="right" height="16" increment="1" initial_val="0" left_delta="65" - max_val="1024" min_val="0" name="media_size_width" - tool_tip="Size to render Web media, leave 0 for default." width="64" /> - <spinner bottom_delta="0" decimal_digits="0" enabled="false" follows="left|top" - halign="right" height="16" increment="1" initial_val="0" left_delta="80" - max_val="1024" min_val="0" name="media_size_height" - tool_tip="Size to render Web media, leave 0 for default." width="64" /> - <text type="string" length="1" bottom_delta="0" follows="left|top" font="SansSerifSmall" halign="left" - height="16" left_delta="70" name="pixels" right="-10"> + <line_editor + bevel_style="in" + border_style="line" + border_thickness="1" + bottom_delta="0" + follows="left|top|right" + font="SansSerifSmall" + height="16" + left="80" + max_length="255" + name="url_description" + right="-90" + select_all_on_focus_received="true" + select_on_focus="true" + tool_tip="Text displayed next to play/load button" /> + <text + bottom_delta="-28" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="16" + left="10" + length="1" + name="Media texture:" + type="string" + width="364"> + Texture: + </text> + <texture_picker + allow_no_texture="true" + bottom_delta="-64" + can_apply_immediately="false" + default_image_name="Default" + follows="left|top" + height="80" + label="" + left="80" + name="media texture" + tool_tip="Click to choose a texture" + width="64" /> + <text + type="string" + length="1" + bottom_delta="0" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="80" + left_delta="75" + name="replace_texture_help" + width="270"> + Objects using this texture will show the movie or +web page after you click the play arrow. + +Select the thumbnail to choose a different texture. + </text> + <text + bottom_delta="-16" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="16" + left="10" + length="1" + mouse_opaque="true" + name="Options:" + top_delta="0" + type="string" + width="64"> + Options: + </text> + <check_box + bottom_delta="0" + enabled="true" + follows="left|top" + font="SansSerifSmall" + height="16" + initial_value="false" + label="Loop" + left="80" + mouse_opaque="true" + name="media_loop" + radio_style="false" + tool_tip="Play media in a loop. When the media has finished playing, it will restart from the beginning." + width="200" /> + <check_box + bottom_delta="0" + enabled="true" + follows="left|top" + font="SansSerifSmall" + height="16" + initial_value="false" + label="Auto scale" + left_delta="80" + mouse_opaque="true" + name="media_auto_scale" + radio_style="false" + tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required." + width="200" /> + <text + bottom_delta="-24" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="16" + left="10" + length="1" + name="media_size" + tool_tip="Size to render Web media, leave 0 for default." + type="string" + width="85"> + Media Size: + </text> + <spinner + bottom_delta="0" + decimal_digits="0" + enabled="false" + follows="left|top" + halign="right" + height="16" + increment="1" + initial_val="0" + left="80" + max_val="1024" + min_val="0" + name="media_size_width" + tool_tip="Width to render Web media, leave 0 for default." + width="60" /> + <spinner + bottom_delta="0" + decimal_digits="0" + enabled="false" + follows="left|top" + halign="right" + height="16" + increment="1" + initial_val="0" + left_delta="64" + max_val="1024" + min_val="0" + name="media_size_height" + tool_tip="Height to render Web media, leave 0 for default." + width="60" /> + <text + bottom_delta="0" + follows="left|top" + font="SansSerifSmall" + halign="left" + height="16" + left_delta="64" + length="1" + name="pixels" + type="string" + width="70"> pixels </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-40" drop_shadow_visible="true" enabled="true" - follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" - height="16" left="10" mouse_opaque="true" name="MusicURL:" v_pad="0" - width="364"> + <text + bg_visible="false" + border_drop_shadow_visible="false" + border_visible="false" + bottom_delta="-30" + drop_shadow_visible="true" + enabled="true" + follows="left|top" + font="SansSerifSmall" + h_pad="0" + halign="left" + height="16" + left="10" + length="1" + mouse_opaque="true" + name="Interaction:" + type="string" + v_pad="0" + width="364"> + Interaction: + </text> + <radio_group + bottom_delta="-2" + draw_border="false" + enabled="true" + follows="left|top" + height="22" + left="80" + mouse_opaque="true" + name="radio_navigate_allow" + tab_stop="true" + width="219"> + <radio_item + bottom="-20" + enabled="true" + follows="left|top" + height="16" + left="0" + length="1" + mouse_opaque="true" + name="Anyone" + tool_tip="Any resident can interact with media." + type="string" + width="70"> + Anyone + </radio_item> + <radio_item + bottom="-20" + enabled="true" + follows="left|top" + height="16" + left="80" + length="1" + mouse_opaque="true" + name="Group" + tool_tip="Group permissions control who can interact with media." + type="string" + width="70"> + Group + </radio_item> + </radio_group> + <check_box + bottom_delta="-22" + enabled="true" + follows="left|top" + font="SansSerifSmall" + height="16" + initial_value="false" + label="Allow browsing only within these domains:" + left="80" + mouse_opaque="true" + name="check navigate filter" + radio_style="false" + width="292" /> + <line_editor + bevel_style="in" + border_style="line" + border_thickness="1" + bottom_delta="-20" + enabled="true" + follows="left|top|right" + font="SansSerifSmall" + handle_edit_keys_directly="false" + height="16" + left="80" + max_length="63" + mouse_opaque="true" + name="navigate_filter_domain" + right="-90" + select_all_on_focus_received="false" + select_on_focus="false" /> + <button + bottom_delta="0" + enabled="true" + follows="right|top" + font="SansSerifSmall" + halign="center" + height="16" + label="Add..." + label_selected="Add..." + right="-12" + mouse_opaque="true" + name="add_navigate_filter" + scale_image="true" + width="70" /> + <scroll_list + bottom_delta="-52" + can_resize="false" + column_padding="0" + draw_heading="false" + draw_stripes="false" + follows="left|top|right" + height="50" + halign="left" + left="80" + multi_select="false" + name="filter_list" + right="-90" + search_column="0" + sort_column="0"> + <column + halign="left" + label="Domain" + name="domain" + sort="domain"/> + </scroll_list> + <button + bottom_delta="0" + enabled="true" + follows="right|top" + font="SansSerifSmall" + halign="center" + height="16" + label="Remove" + label_selected="Remove" + right="-12" + mouse_opaque="true" + name="remove_navigate_filter" + scale_image="true" + width="70" /> + </panel> + <panel + border="true" + follows="left|top|right|bottom" + height="363" + label="Audio" + layout="topleft" + left_delta="0" + name="land_audio_panel" + top_delta="1" + width="458"> + <text + bottom="-45" + follows="left|top" + height="16" + layout="topleft" + left="10" + length="1" + name="MusicURL:" + type="string" + width="364"> Music URL: </text> - <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0" - enabled="true" follows="left|top" font="SansSerifSmall" - handle_edit_keys_directly="false" height="16" left="80" max_length="255" - mouse_opaque="true" name="music_url" right="-15" - select_all_on_focus_received="true" select_on_focus="true"/> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-40" drop_shadow_visible="true" enabled="true" - follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" - height="16" left="10" mouse_opaque="true" name="Sound:" v_pad="0" - width="364"> + <line_editor + border_style="line" + border_thickness="1" + bottom_delta="0" + follows="left|top|right" + height="16" + layout="topleft" + left="80" + max_length="255" + name="music_url" + right="-15" + select_on_focus="true" /> + <check_box + bottom_delta="-25" + enabled="true" + follows="left|top" + font="SansSerifSmall" + height="16" + initial_value="false" + label="Hide URL" + left="80" + mouse_opaque="true" + name="hide_music_url" + radio_style="false" + tool_tip="Checking this option will hide the music URL from any non-authorized viewers of this parcel information." + width="150" /> + <text + bottom_delta="-65" + follows="left|top" + height="16" + layout="topleft" + left="10" + length="1" + name="Sound:" + type="string" + width="364"> Sound: </text> - <check_box bottom_delta="0" enabled="true" follows="left|top" font="SansSerifSmall" - height="16" initial_value="false" - label="Restrict gesture and object sounds to this parcel" left="80" - mouse_opaque="true" name="check sound local" radio_style="false" - width="292" /> - <button bottom_delta="0" enabled="true" follows="left|top" font="SansSerif" - halign="center" height="18" label="?" label_selected="?" left="372" - mouse_opaque="true" name="?" width="18" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-40" enabled="true" follows="left|top" font="SansSerifSmall" - h_pad="0" halign="left" height="16" left="10" mouse_opaque="false" - name="Voice settings:" tab_stop="false" v_pad="0" width="364"> + <check_box + bottom_delta="0" + follows="left|top" + height="16" + label="Restrict gesture and object sounds to this parcel" + layout="topleft" + left_delta="70" + name="check_sound_local" + width="200" /> + <button + bottom_delta="0" + follows="left|top" + height="18" + label="?" + label_selected="?" + layout="topleft" + left_delta="292" + name="?" + width="18" /> + <text + bottom_delta="-65" + follows="left|top" + height="16" + layout="topleft" + left="10" + length="1" + mouse_opaque="false" + name="Voice:" + type="string" + width="364"> Voice: </text> - <check_box bottom_delta="-0" enabled="true" follows="left|top" - height="54" left="80" mouse_opaque="true" name="parcel_enable_voice_channel" - tab_stop="true" width="463" - label="Enable Voice" - /> - <check_box bottom_delta="-0" enabled="false" follows="left|top" - height="54" left="80" mouse_opaque="true" name="parcel_enable_voice_channel_is_estate_disabled" - tab_stop="true" width="463" - label="Enable Voice (established by the Estate)" - /> - <check_box bottom_delta="-20" enabled="true" follows="left|top" - height="54" left="100" mouse_opaque="true" name="parcel_enable_voice_channel_parcel" - tab_stop="true" width="443" - label="Restrict Voice to this parcel" - /> + <radio_group + bottom_delta="-40" + draw_border="false" + enabled="true" + follows="left|top" + height="60" + left="80" + mouse_opaque="true" + name="parcel_voice_channel" + tab_stop="true" + width="219"> + <radio_item + bottom="-19" + enabled="true" + follows="left|top" + height="16" + left="0" + length="1" + mouse_opaque="true" + name="Estate" + tool_tip="Use the estate voice channel." + type="string" + width="70"> + Estate Channel + </radio_item> + <radio_item + bottom="-39" + enabled="true" + follows="left|top" + height="16" + left="0" + length="1" + mouse_opaque="true" + name="Parcel" + tool_tip="Restrict Voice to this parcel." + type="string" + width="70"> + Parcel Channel + </radio_item> + <radio_item + bottom="-59" + enabled="true" + follows="left|top" + height="16" + left="0" + length="1" + mouse_opaque="true" + name="Disabled" + tool_tip="Disable voice on this parcel." + type="string" + width="70"> + Disabled + </radio_item> + </radio_group> </panel> <panel border="true" bottom="-349" enabled="true" follows="left|top|right|bottom" height="333" label="Access" left="1" mouse_opaque="true" diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_media_browser.xml b/linden/indra/newview/skins/default/xui/en-us/floater_media_browser.xml index b30ca89d9..c1bfdcc8c 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_media_browser.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_media_browser.xml @@ -18,7 +18,20 @@ <button bottom_delta="0" enabled="true" follows="right|top" height="20" label="Home" left_delta="58" name="home" width="55" /> </layout_panel> - <layout_panel auto_resize="false" bottom="0" height="20" left="0" + <layout_panel auto_resize="false" bottom="0" height="20" left="0" name="time_controls" user_resize="false" + width="800"> + <button bottom="0" follows="left|top" height="20" label="rewind" left="0" name="rewind" + width="55" /> + <button bottom_delta="0" follows="left|top" height="20" label="" left_delta="55" + name="play" width="55" image_unselected="button_anim_play.tga" image_selected="button_anim_play_selected.tga" scale_image="true" /> + <button bottom_delta="0" follows="left|top" height="20" label="" left_delta="0" + name="pause" width="55" image_unselected="button_anim_pause.tga" image_selected="button_anim_pause_selected.tga" scale_image="true" /> + <button bottom_delta="0" follows="left|top" height="20" label="stop" + left_delta="65" name="stop" width="55" /> + <button bottom_delta="0" follows="left|top" height="20" label="forward" + left_delta="75" name="seek" width="55" /> + </layout_panel> + <layout_panel auto_resize="false" bottom="0" height="20" left="0" name="parcel_owner_controls" user_resize="false" width="540"> <button bottom="0" enabled="false" follows="left|top" height="20" label="Send Current URL to Parcel" left="0" name="assign" width="200" /> @@ -38,4 +51,10 @@ name="close" width="70" /> </layout_panel> </layout_stack> + <string name="home_page_url"> + http://www.secondlife.com + </string> + <string name="support_page_url"> + http://support.secondlife.com + </string> </floater> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml index e3d102148..e69de29bb 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml @@ -1,456 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<mimetypes name="default"> - <defaultlabel> - (Unknown) - </defaultlabel> - <defaultwidget> - none - </defaultwidget> - <defaultimpl> - LLMediaImplLLMozLib - </defaultimpl> - <widgetset name="web"> - <label name="web_label"> - Web Content - </label> - <icon> - icn_media_web.tga - </icon> - <default_type> - text/html - </default_type> - <tooltip name="web_tooltip"> - This location has Web content - </tooltip> - <playtip name="web_playtip"> - Show Web content - </playtip> - <allow_resize> - true - </allow_resize> - <allow_looping> - false - </allow_looping> - </widgetset> - <widgetset name="movie"> - <label name="movie_label"> - Movie - </label> - <default_type> - video/* - </default_type> - <icon> - icn_media_movie.tga - </icon> - <tooltip name="movie_tooltip"> - There is a movie to play here - </tooltip> - <playtip name="movie_playtip"> - Play movie - </playtip> - <allow_resize> - false - </allow_resize> - <allow_looping> - true - </allow_looping> - </widgetset> - <widgetset name="none"> - <label name="none_label"> - No Content - </label> - <default_type> - none/none - </default_type> - <icon> - icn_media_web.tga - </icon> - <tooltip name="none_tooltip"> - No media here - </tooltip> - <playtip name="none_playtip" /> - <allow_resize> - false - </allow_resize> - <allow_looping> - false - </allow_looping> - </widgetset> - <widgetset name="image"> - <label name="image_label"> - Image - </label> - <icon> - icn_media_web.tga - </icon> - <default_type> - image/* - </default_type> - <tooltip name="image_tooltip"> - There is an image at this location - </tooltip> - <playtip name="image_playtip"> - View this location's image - </playtip> - <allow_resize> - false - </allow_resize> - <allow_looping> - false - </allow_looping> - </widgetset> - <widgetset name="audio"> - <label name="audio_label"> - Audio - </label> - <icon> - icn_media_web.tga - </icon> - <default_type> - audio/* - </default_type> - <tooltip name="audio_tooltip"> - There is audio at this location - </tooltip> - <playtip name="audio_playtip"> - Play this location's audio - </playtip> - <allow_resize> - false - </allow_resize> - <allow_looping> - true - </allow_looping> - </widgetset> - <scheme name="rtsp"> - <label name="rtsp_label"> - Real Time Streaming - </label> - <widgettype> - movie - </widgettype> - </scheme> - <mimetype name="blank"> - <label name="blank_label"> - - None - - </label> - <widgettype> - none - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> - <mimetype name="none/none"> - <label name="none/none_label"> - - None - - </label> - <widgettype> - none - </widgettype> - </mimetype> - <mimetype name="audio/*"> - <label name="audio2_label"> - Audio - </label> - <widgettype> - audio - </widgettype> - </mimetype> - <mimetype name="video/*"> - <label name="video2_label"> - Video - </label> - <widgettype> - movie - </widgettype> - </mimetype> - <mimetype name="image/*"> - <label name="image2_label"> - Image - </label> - <widgettype> - image - </widgettype> - </mimetype> - <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> - <label name="vnd.secondlife.qt.legacy_label"> - Movie (QuickTime) - </label> - <widgettype> - movie - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> - <mimetype name="application/javascript"> - <label name="application/javascript_label"> - Javascript - </label> - <widgettype> - web - </widgettype> - </mimetype> - <mimetype name="application/ogg"> - <label name="application/ogg_label"> - Ogg Audio/Video - </label> - <widgettype> - audio - </widgettype> - </mimetype> - <mimetype name="application/pdf"> - <label name="application/pdf_label"> - PDF Document - </label> - <widgettype> - image - </widgettype> - </mimetype> - <mimetype name="application/postscript"> - <label name="application/postscript_label"> - Postscript Document - </label> - <widgettype> - image - </widgettype> - </mimetype> - <mimetype name="application/rtf"> - <label name="application/rtf_label"> - Rich Text (RTF) - </label> - <widgettype> - image - </widgettype> - </mimetype> - <mimetype name="application/smil"> - <label name="application/smil_label"> - Synchronized Multimedia Integration Language (SMIL) - </label> - <widgettype> - movie - </widgettype> - </mimetype> - <mimetype name="application/xhtml+xml"> - <label name="application/xhtml+xml_label"> - Web Page (XHTML) - </label> - <widgettype> - web - </widgettype> - </mimetype> - <mimetype name="application/x-director"> - <label name="application/x-director_label"> - Macromedia Director - </label> - <widgettype> - image - </widgettype> - </mimetype> - <mimetype name="application/x-shockwave-flash"> - <label name="application/x-shockwave-flash_label"> - Flash - </label> - <widgettype> - image - </widgettype> - </mimetype> - <mimetype name="audio/mid"> - <label name="audio/mid_label"> - Audio (MIDI) - </label> - <widgettype> - audio - </widgettype> - </mimetype> - <mimetype name="audio/mpeg"> - <label name="audio/mpeg_label"> - Audio (MP3) - </label> - <widgettype> - audio - </widgettype> - </mimetype> - <mimetype name="audio/x-aiff"> - <label name="audio/x-aiff_label"> - Audio (AIFF) - </label> - <widgettype> - audio - </widgettype> - </mimetype> - <mimetype name="audio/x-wav"> - <label name="audio/x-wav_label"> - Audio (WAV) - </label> - <widgettype> - audio - </widgettype> - </mimetype> - <mimetype menu="1" name="image/bmp"> - <label name="image/bmp_label"> - Image (BMP) - </label> - <widgettype> - image - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype menu="1" name="image/gif"> - <label name="image/gif_label"> - Image (GIF) - </label> - <widgettype> - image - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype menu="1" name="image/jpeg"> - <label name="image/jpeg_label"> - Image (JPEG) - </label> - <widgettype> - image - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype menu="1" name="image/png"> - <label name="image/png_label"> - Image (PNG) - </label> - <widgettype> - image - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype name="image/svg+xml"> - <label name="image/svg+xml_label"> - Image (SVG) - </label> - <widgettype> - image - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype menu="1" name="image/tiff"> - <label name="image/tiff_label"> - Image (TIFF) - </label> - <widgettype> - image - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype menu="1" name="text/html"> - <label name="text/html_label"> - Web Page - </label> - <widgettype> - web - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype menu="1" name="text/plain"> - <label name="text/plain_label"> - Text - </label> - <widgettype> - text - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype name="text/xml"> - <label name="text/xml_label"> - XML - </label> - <widgettype> - text - </widgettype> - <impl> - LLMediaImplLLMozLib - </impl> - </mimetype> - <mimetype menu="1" name="video/mpeg"> - <label name="video/mpeg_label"> - Movie (MPEG) - </label> - <widgettype> - movie - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> - <mimetype name="video/mp4"> - <label name="video/mp4_label"> - Movie (MP4) - </label> - <widgettype> - movie - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> - <mimetype menu="1" name="video/quicktime"> - <label name="video/quicktime_label"> - Movie (QuickTime) - </label> - <widgettype> - movie - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> - <mimetype name="video/x-ms-asf"> - <label name="video/x-ms-asf_label"> - Movie (Windows Media ASF) - </label> - <widgettype> - movie - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> - <mimetype name="video/x-ms-wmv"> - <label name="video/x-ms-wmv_label"> - Movie (Windows Media WMV) - </label> - <widgettype> - movie - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> - <mimetype menu="1" name="video/x-msvideo"> - <label name="video/x-msvideo_label"> - Movie (AVI) - </label> - <widgettype> - movie - </widgettype> - <impl> - LLMediaImplQuickTime - </impl> - </mimetype> -</mimetypes> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml new file mode 100644 index 000000000..2977d7a2e --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml @@ -0,0 +1,445 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<mimetypes name="default"> + <defaultlabel> + (Unknown) + </defaultlabel> + <defaultwidget> + none + </defaultwidget> + <defaultimpl> + media_plugin_webkit + </defaultimpl> + <widgetset name="web"> + <label name="web_label"> + Web Content + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + text/html + </default_type> + <tooltip name="web_tooltip"> + This location has Web content + </tooltip> + <playtip name="web_playtip"> + Show Web content + </playtip> + <allow_resize> + true + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="movie"> + <label name="movie_label"> + Movie + </label> + <default_type> + video/* + </default_type> + <icon> + icn_media_movie.tga + </icon> + <tooltip name="movie_tooltip"> + There is a movie to play here + </tooltip> + <playtip name="movie_playtip"> + Play movie + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <widgetset name="image"> + <label name="image_label"> + Image + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + image/* + </default_type> + <tooltip name="image_tooltip"> + There is an image at this location + </tooltip> + <playtip name="image_playtip"> + View this location's image + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="audio"> + <label name="audio_label"> + Audio + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + audio/* + </default_type> + <tooltip name="audio_tooltip"> + There is audio at this location + </tooltip> + <playtip name="audio_playtip"> + Play this location's audio + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <scheme name="rtsp"> + <label name="rtsp_label"> + Real Time Streaming + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </scheme> + <mimetype name="blank"> + <label name="blank_label"> + - None - + </label> + <widgettype> + none + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="none/none"> + <label name="none/none_label"> + - None - + </label> + <widgettype> + none + </widgettype> + </mimetype> + <mimetype name="audio/*"> + <label name="audio2_label"> + Audio + </label> + <widgettype> + audio + </widgettype> + </mimetype> + <mimetype name="video/*"> + <label name="video2_label"> + Video + </label> + <widgettype> + movie + </widgettype> + </mimetype> + <mimetype name="image/*"> + <label name="image2_label"> + Image + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> + <label name="vnd.secondlife.qt.legacy_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="application/javascript"> + <label name="application/javascript_label"> + Javascript + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/ogg"> + <label name="application/ogg_label"> + Ogg Audio/Video + </label> + <widgettype> + audio + </widgettype> + </mimetype> + <mimetype name="application/pdf"> + <label name="application/pdf_label"> + PDF Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/postscript"> + <label name="application/postscript_label"> + Postscript Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/rtf"> + <label name="application/rtf_label"> + Rich Text (RTF) + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/smil"> + <label name="application/smil_label"> + Synchronized Multimedia Integration Language (SMIL) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="application/xhtml+xml"> + <label name="application/xhtml+xml_label"> + Web Page (XHTML) + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/x-director"> + <label name="application/x-director_label"> + Macromedia Director + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="audio/mid"> + <label name="audio/mid_label"> + Audio (MIDI) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="audio/mpeg"> + <label name="audio/mpeg_label"> + Audio (MP3) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="audio/x-aiff"> + <label name="audio/x-aiff_label"> + Audio (AIFF) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="audio/x-wav"> + <label name="audio/x-wav_label"> + Audio (WAV) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype menu="1" name="image/bmp"> + <label name="image/bmp_label"> + Image (BMP) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/gif"> + <label name="image/gif_label"> + Image (GIF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/jpeg"> + <label name="image/jpeg_label"> + Image (JPEG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/png"> + <label name="image/png_label"> + Image (PNG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="image/svg+xml"> + <label name="image/svg+xml_label"> + Image (SVG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/tiff"> + <label name="image/tiff_label"> + Image (TIFF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/html"> + <label name="text/html_label"> + Web Page + </label> + <widgettype> + web + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/plain"> + <label name="text/plain_label"> + Text + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="text/xml"> + <label name="text/xml_label"> + XML + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="video/mpeg"> + <label name="video/mpeg_label"> + Movie (MPEG) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="video/mp4"> + <label name="video/mp4_label"> + Movie (MP4) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype menu="1" name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="video/x-ms-asf"> + <label name="video/x-ms-asf_label"> + Movie (Windows Media ASF) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype name="video/x-ms-wmv"> + <label name="video/x-ms-wmv_label"> + Movie (Windows Media WMV) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> + <mimetype menu="1" name="video/x-msvideo"> + <label name="video/x-msvideo_label"> + Movie (AVI) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_gstreamer + </impl> + </mimetype> +</mimetypes> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml new file mode 100644 index 000000000..4a7a6e17a --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml @@ -0,0 +1,445 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<mimetypes name="default"> + <defaultlabel> + (Unknown) + </defaultlabel> + <defaultwidget> + none + </defaultwidget> + <defaultimpl> + media_plugin_webkit + </defaultimpl> + <widgetset name="web"> + <label name="web_label"> + Web Content + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + text/html + </default_type> + <tooltip name="web_tooltip"> + This location has Web content + </tooltip> + <playtip name="web_playtip"> + Show Web content + </playtip> + <allow_resize> + true + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="movie"> + <label name="movie_label"> + Movie + </label> + <default_type> + video/* + </default_type> + <icon> + icn_media_movie.tga + </icon> + <tooltip name="movie_tooltip"> + There is a movie to play here + </tooltip> + <playtip name="movie_playtip"> + Play movie + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <widgetset name="image"> + <label name="image_label"> + Image + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + image/* + </default_type> + <tooltip name="image_tooltip"> + There is an image at this location + </tooltip> + <playtip name="image_playtip"> + View this location's image + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="audio"> + <label name="audio_label"> + Audio + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + audio/* + </default_type> + <tooltip name="audio_tooltip"> + There is audio at this location + </tooltip> + <playtip name="audio_playtip"> + Play this location's audio + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <scheme name="rtsp"> + <label name="rtsp_label"> + Real Time Streaming + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </scheme> + <mimetype name="blank"> + <label name="blank_label"> + - None - + </label> + <widgettype> + none + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="none/none"> + <label name="none/none_label"> + - None - + </label> + <widgettype> + none + </widgettype> + </mimetype> + <mimetype name="audio/*"> + <label name="audio2_label"> + Audio + </label> + <widgettype> + audio + </widgettype> + </mimetype> + <mimetype name="video/*"> + <label name="video2_label"> + Video + </label> + <widgettype> + movie + </widgettype> + </mimetype> + <mimetype name="image/*"> + <label name="image2_label"> + Image + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> + <label name="vnd.secondlife.qt.legacy_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="application/javascript"> + <label name="application/javascript_label"> + Javascript + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/ogg"> + <label name="application/ogg_label"> + Ogg Audio/Video + </label> + <widgettype> + audio + </widgettype> + </mimetype> + <mimetype name="application/pdf"> + <label name="application/pdf_label"> + PDF Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/postscript"> + <label name="application/postscript_label"> + Postscript Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/rtf"> + <label name="application/rtf_label"> + Rich Text (RTF) + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/smil"> + <label name="application/smil_label"> + Synchronized Multimedia Integration Language (SMIL) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="application/xhtml+xml"> + <label name="application/xhtml+xml_label"> + Web Page (XHTML) + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/x-director"> + <label name="application/x-director_label"> + Macromedia Director + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="audio/mid"> + <label name="audio/mid_label"> + Audio (MIDI) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/mpeg"> + <label name="audio/mpeg_label"> + Audio (MP3) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/x-aiff"> + <label name="audio/x-aiff_label"> + Audio (AIFF) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/x-wav"> + <label name="audio/x-wav_label"> + Audio (WAV) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="image/bmp"> + <label name="image/bmp_label"> + Image (BMP) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/gif"> + <label name="image/gif_label"> + Image (GIF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/jpeg"> + <label name="image/jpeg_label"> + Image (JPEG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/png"> + <label name="image/png_label"> + Image (PNG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="image/svg+xml"> + <label name="image/svg+xml_label"> + Image (SVG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/tiff"> + <label name="image/tiff_label"> + Image (TIFF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/html"> + <label name="text/html_label"> + Web Page + </label> + <widgettype> + web + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/plain"> + <label name="text/plain_label"> + Text + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="text/xml"> + <label name="text/xml_label"> + XML + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="video/mpeg"> + <label name="video/mpeg_label"> + Movie (MPEG) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/mp4"> + <label name="video/mp4_label"> + Movie (MP4) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/x-ms-asf"> + <label name="video/x-ms-asf_label"> + Movie (Windows Media ASF) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/x-ms-wmv"> + <label name="video/x-ms-wmv_label"> + Movie (Windows Media WMV) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="video/x-msvideo"> + <label name="video/x-msvideo_label"> + Movie (AVI) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> +</mimetypes> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml new file mode 100644 index 000000000..4a7a6e17a --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml @@ -0,0 +1,445 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<mimetypes name="default"> + <defaultlabel> + (Unknown) + </defaultlabel> + <defaultwidget> + none + </defaultwidget> + <defaultimpl> + media_plugin_webkit + </defaultimpl> + <widgetset name="web"> + <label name="web_label"> + Web Content + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + text/html + </default_type> + <tooltip name="web_tooltip"> + This location has Web content + </tooltip> + <playtip name="web_playtip"> + Show Web content + </playtip> + <allow_resize> + true + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="movie"> + <label name="movie_label"> + Movie + </label> + <default_type> + video/* + </default_type> + <icon> + icn_media_movie.tga + </icon> + <tooltip name="movie_tooltip"> + There is a movie to play here + </tooltip> + <playtip name="movie_playtip"> + Play movie + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <widgetset name="image"> + <label name="image_label"> + Image + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + image/* + </default_type> + <tooltip name="image_tooltip"> + There is an image at this location + </tooltip> + <playtip name="image_playtip"> + View this location's image + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="audio"> + <label name="audio_label"> + Audio + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + audio/* + </default_type> + <tooltip name="audio_tooltip"> + There is audio at this location + </tooltip> + <playtip name="audio_playtip"> + Play this location's audio + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <scheme name="rtsp"> + <label name="rtsp_label"> + Real Time Streaming + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </scheme> + <mimetype name="blank"> + <label name="blank_label"> + - None - + </label> + <widgettype> + none + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="none/none"> + <label name="none/none_label"> + - None - + </label> + <widgettype> + none + </widgettype> + </mimetype> + <mimetype name="audio/*"> + <label name="audio2_label"> + Audio + </label> + <widgettype> + audio + </widgettype> + </mimetype> + <mimetype name="video/*"> + <label name="video2_label"> + Video + </label> + <widgettype> + movie + </widgettype> + </mimetype> + <mimetype name="image/*"> + <label name="image2_label"> + Image + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> + <label name="vnd.secondlife.qt.legacy_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="application/javascript"> + <label name="application/javascript_label"> + Javascript + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/ogg"> + <label name="application/ogg_label"> + Ogg Audio/Video + </label> + <widgettype> + audio + </widgettype> + </mimetype> + <mimetype name="application/pdf"> + <label name="application/pdf_label"> + PDF Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/postscript"> + <label name="application/postscript_label"> + Postscript Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/rtf"> + <label name="application/rtf_label"> + Rich Text (RTF) + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/smil"> + <label name="application/smil_label"> + Synchronized Multimedia Integration Language (SMIL) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="application/xhtml+xml"> + <label name="application/xhtml+xml_label"> + Web Page (XHTML) + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/x-director"> + <label name="application/x-director_label"> + Macromedia Director + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="audio/mid"> + <label name="audio/mid_label"> + Audio (MIDI) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/mpeg"> + <label name="audio/mpeg_label"> + Audio (MP3) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/x-aiff"> + <label name="audio/x-aiff_label"> + Audio (AIFF) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/x-wav"> + <label name="audio/x-wav_label"> + Audio (WAV) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="image/bmp"> + <label name="image/bmp_label"> + Image (BMP) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/gif"> + <label name="image/gif_label"> + Image (GIF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/jpeg"> + <label name="image/jpeg_label"> + Image (JPEG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/png"> + <label name="image/png_label"> + Image (PNG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="image/svg+xml"> + <label name="image/svg+xml_label"> + Image (SVG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/tiff"> + <label name="image/tiff_label"> + Image (TIFF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/html"> + <label name="text/html_label"> + Web Page + </label> + <widgettype> + web + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/plain"> + <label name="text/plain_label"> + Text + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="text/xml"> + <label name="text/xml_label"> + XML + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="video/mpeg"> + <label name="video/mpeg_label"> + Movie (MPEG) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/mp4"> + <label name="video/mp4_label"> + Movie (MP4) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/x-ms-asf"> + <label name="video/x-ms-asf_label"> + Movie (Windows Media ASF) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/x-ms-wmv"> + <label name="video/x-ms-wmv_label"> + Movie (Windows Media WMV) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="video/x-msvideo"> + <label name="video/x-msvideo_label"> + Movie (AVI) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> +</mimetypes> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_bars.xml b/linden/indra/newview/skins/default/xui/en-us/panel_bars.xml index 4a13604bb..aab98db36 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_bars.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_bars.xml @@ -15,7 +15,4 @@ <layout_panel auto_resize="false" filename="panel_toolbar.xml" name="toolbar" use_bounding_rect="true" user_resize="false" width="1024" min_height="28" /> </layout_stack> - <panel auto_resize="true" background_visible="false" bottom="50" - follows="left|right|top|bottom" height="728" left="0" mouse_opaque="false" - name="hud" user_resize="false" width="1024" /> </panel> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_hud.xml b/linden/indra/newview/skins/default/xui/en-us/panel_hud.xml new file mode 100644 index 000000000..95f828996 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/panel_hud.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel border="false" auto_resize="true" background_visible="false" bottom="50" + follows="left|right|top|bottom" height="728" left="0" mouse_opaque="false" + name="hud" user_resize="false" width="1024" /> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_media_hud.xml b/linden/indra/newview/skins/default/xui/en-us/panel_media_hud.xml new file mode 100644 index 000000000..1c0781a5b --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/panel_media_hud.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel border="false" follows="" height="160" visible="false" mouse_opaque="false" + label="" name="MediaHUD" width="208" background_visible="false" background_opaque="false" bg_alpha_color="1 1 1 0.0"> +<panel name="media_region" left="20" right="-20" bottom="35" top="-20" follows="left|right|top|bottom" visible="true" background_opaque="false" + mouse_opaque="false"/> + <!--icon name="bg_image" image_name="media_panel_hoverrectangle.png" visible="true" left="10" bottom="32" right="-10" top="-10" follows="left|right|top|bottom"/--> + <layout_stack orientation="horizontal" left="0" bottom="0" follows="left|right|bottom" visible="true" width="208" height="32"> + <layout_panel user_resize="false"/> + <layout_panel user_resize="false" auto_resize="false" width="210" min_width="208"> + <panel name="media_focused_controls" width="208" left="0" height="32" bottom="0" visible="true"> + <icon name="media_panel_transportcontrols_bg" image_name="media_panel_bg.png" visible="true" height="32" width="99" scale_image="true" bottom="0"/> + <button name="back" label="" left="4" width="20" bottom="6" height="22" image_unselected="media_btn_back.png" + image_selected="media_btn_back.png" scale_image="true"/> + <icon name="media_panel_divider-1" image_name="media_panel_divider.png" visible="true" height="22" width="3" left_delta="20" + scale_image="false" bottom="5"/> + <button name="fwd" label="" left_delta="3" width="17" bottom_delta="0" height="22" image_unselected="media_btn_forward.png" + image_selected="media_btn_forward.png" scale_image="true"/> + <icon name="media_panel_divider-2" image_name="media_panel_divider.png" visible="true" height="22" width="3" left_delta="17" + scale_image="false" bottom="5"/> + <button name="home" label="" left_delta="3" width="22" bottom_delta="0" height="22" image_unselected="media_btn_home.png" + image_selected="media_btn_home.png" scale_image="true"/> + <button name="media_stop" label="" left_delta="0" width="22" bottom_delta="0" height="22" image_unselected="button_anim_stop.tga" + image_selected="button_anim_stop.tga" scale_image="true"/> + <icon name="media_panel_divider-3" image_name="media_panel_divider.png" visible="true" height="22" width="3" left_delta="22" + scale_image="false" bottom="5"/> + <button name="reload" label="" left_delta="3" width="22" bottom_delta="0" height="22" image_unselected="media_btn_reload.png" + image_selected="media_btn_reload.png" scale_image="true"/> + <button name="stop" label="" left_delta="0" width="22" bottom_delta="0" height="22" image_unselected="media_btn_stoploading.png" + image_selected="media_btn_stoploading.png" scale_image="true" visible="false"/> + <button name="play" label="" left_delta="0" width="22" bottom_delta="0" height="22" image_unselected="button_anim_play.tga" + image_selected="button_anim_play.tga" scale_image="true" visible="false"/> + <button name="pause" label="" left_delta="0" width="22" bottom_delta="0" height="22" image_unselected="button_anim_pause.tga" + image_selected="button_anim_pause.tga" scale_image="true" visible="false"/> + <icon name="media_panel_scrollbg" image_name="media_panel_scrollbg.png" visible="true" height="32" width="32" + scale_image="false" bottom="0" left="97"/> + <button name="scrollup" label="" left="109" width="8" bottom="20" height="8" image_unselected="media_btn_scrollup.png" + image_selected="media_btn_scrollup.png" scale_image="false"/> + <button name="scrollleft" label="" left="100" width="8" bottom="12" height="8" image_unselected="media_btn_scrollleft.png" + image_selected="media_btn_scrollleft.png" scale_image="false"/> + <button name="scrollright" label="" left="117" width="8" bottom="12" height="8" image_unselected="media_btn_scrollright.png" + image_selected="media_btn_scrollright.png" scale_image="false"/> + <button name="scrolldown" label="" left="109" width="8" bottom="4" height="8" image_unselected="media_btn_scrolldown.png" + image_selected="media_btn_scrolldown.png" scale_image="false"/> + <icon name="media_panel_metacontrols_bg" image_name="media_panel_bg.png" visible="true" height="32" width="81" + scale_image="true" bottom="0" left="127"/> + <button name="zoom_frame" label="" left_delta="4" width="22" bottom="5" height="22" image_unselected="media_btn_optimalzoom.png" + image_selected="media_btn_optimalzoom.png" scale_image="true"/> + <icon name="media_panel_divider-4" image_name="media_panel_divider.png" visible="true" height="22" width="3" left_delta="22" + scale_image="false" bottom="5"/> + <button name="new_window" label="" left_delta="3" width="24" bottom_delta="1" height="22" image_unselected="media_btn_newwindow.png" + image_selected="media_btn_newwindow.png" scale_image="true"/> + <icon name="media_panel_divider-5" image_name="media_panel_divider.png" visible="true" height="22" width="3" left_delta="24" + scale_image="false" bottom="5"/> + <button name="close" label="" left_delta="3" width="21" bottom_delta="1" height="22" image_unselected="media_btn_done.png" + image_selected="media_btn_done.png" scale_image="true"/> + </panel> + <panel name="media_hover_controls" width="57" left="74" height="32" bottom="0" visible="false"> + <icon name="media_panel_metacontrols_bg-hover" image_name="media_panel_bg.png" visible="true" height="32" width="57" scale_image="true" bottom="0" left="0"/> + <button name="zoom_frame_hover" label="" left_delta="4" width="22" bottom="5" height="22" image_unselected="media_btn_optimalzoom.png" image_selected="media_btn_optimalzoom.png" + scale_image="true"/> + <icon name="media_panel_divider" image_name="media_panel_divider.png" visible="true" height="22" width="3" left_delta="22" scale_image="false" bottom="5"/> + <button name="new_window_hover" label="" left_delta="3" width="24" bottom_delta="1" height="22" image_unselected="media_btn_newwindow.png" image_selected="media_btn_newwindow.png" + scale_image="true"/> + </panel> + </layout_panel> + <layout_panel user_resize="false"/> + </layout_stack> +</panel> diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 6b5e80023..fcebda92e 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -229,6 +229,12 @@ def construct(self): self.path("imprudence.url") + # Plugin host application + self.path(os.path.join(os.pardir, + 'llplugin', 'slplugin', self.args['configuration'], "SLPlugin.exe"), + "SLPlugin.exe") + + self.path("featuretable.txt") # For use in crash reporting (generates minidumps) @@ -251,7 +257,41 @@ def construct(self): self.path("alut.dll") self.end_prefix() - # Mozilla appears to force a dependency on these files so we need to ship it (CP) - updated to vc8 versions (nyx) + + # Media plugins - QuickTime + if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"): + self.path("media_plugin_quicktime.dll") + self.end_prefix() + + # Media plugins - WebKit/Qt + if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"): + self.path("media_plugin_webkit.dll") + self.end_prefix() + + # For WebKit/Qt plugin runtimes + if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"): + self.path("libeay32.dll") + self.path("qtcore4.dll") + self.path("qtgui4.dll") + self.path("qtnetwork4.dll") + self.path("qtopengl4.dll") + self.path("qtwebkit4.dll") + self.path("ssleay32.dll") + self.end_prefix() + + # For WebKit/Qt plugin runtimes (image format plugins) + if self.prefix(src="../../libraries/i686-win32/lib/release/imageformats", dst="llplugin/imageformats"): + self.path("qgif4.dll") + self.path("qico4.dll") + self.path("qjpeg4.dll") + self.path("qmng4.dll") + self.path("qsvg4.dll") + self.path("qtiff4.dll") + self.end_prefix() + + # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 + self.path("skins/default/xui/en-us/mime_types_windows.xml", "skins/default/xui/en-us/mime_types.xml") + # These need to be installed as a SxS assembly, currently a 'private' assembly. # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx if self.prefix(src=self.args['configuration'], dst=""): @@ -278,34 +318,6 @@ def construct(self): # same thing for auto-updater. #self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst="updater.exe.config") - # Mozilla runtime DLLs (CP) - if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): - self.path("freebl3.dll") - self.path("js3250.dll") - self.path("nspr4.dll") - self.path("nss3.dll") - self.path("nssckbi.dll") - self.path("plc4.dll") - self.path("plds4.dll") - self.path("smime3.dll") - self.path("softokn3.dll") - self.path("ssl3.dll") - self.path("xpcom.dll") - self.path("xul.dll") - self.end_prefix() - - # Mozilla runtime misc files (CP) - if self.prefix(src="app_settings/mozilla"): - self.path("chrome/*.*") - self.path("components/*.*") - self.path("greprefs/*.*") - self.path("plugins/*.*") - self.path("res/*.*") - self.path("res/*/*") - self.end_prefix() - - # Mozilla hack to get it to accept newer versions of msvc*80.dll than are listed in manifest - # necessary as llmozlib2-vc80.lib refers to an old version of msvc*80.dll - can be removed when new version of llmozlib is built - Nyx # Vivox runtimes if self.prefix(src="vivox-runtime/i686-win32", dst=""): # self.path("alut.dll") @@ -534,11 +546,8 @@ def construct(self): self.path(self.args['configuration'] + "/Imprudence.app", dst="") if self.prefix(src="", dst="Contents"): # everything goes in Contents - # Expand the tar file containing the assorted mozilla bits into - # <bundle>/Contents/MacOS/ - self.contents_of_tar(self.args['source']+'/mozilla-universal-darwin.tgz', 'MacOS') - - self.path("Info-Imprudence.plist", dst="Info.plist") + + self.path("Info-Imprudence.plist", dst="Info.plist") # copy additional libs in <bundle>/Contents/MacOS/ if self.prefix(src="../../libraries/universal-darwin/lib_release", dst="MacOS/"): @@ -590,12 +599,6 @@ def construct(self): self.end_prefix("../../libraries/universal-darwin/lib_release") - # replace the default theme with our custom theme (so scrollbars work). - if self.prefix(src="mozilla-theme", dst="MacOS/chrome"): - self.path("classic.jar") - self.path("classic.manifest") - self.end_prefix("MacOS/chrome") - # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): super(DarwinManifest, self).construct() @@ -723,7 +726,21 @@ def construct(self): # our apps # self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") + + # plugin launcher + self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin") + + # plugins + if self.prefix(src="", dst="llplugin"): + self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib") + self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib") + self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib") + + self.end_prefix("llplugin") + # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 + self.path("skins/default/xui/en-us/mime_types_mac.xml", "skins/default/xui/en-us/mime_types.xml") + # command line arguments for connecting to the proper grid self.put_in_file(self.flags_list(), 'arguments.txt') @@ -766,7 +783,7 @@ def package_finish(self): # make sure we don't have stale files laying about self.remove(sparsename, finalname) - self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 300 -layout SPUD' % { + self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 400 -layout SPUD' % { 'sparse':sparsename, 'vol':volname}) @@ -851,6 +868,23 @@ def construct(self): # Create an appropriate gridargs.dat for this package, denoting required grid. self.put_in_file(self.flags_list(), 'gridargs.dat') + self.path("linux_tools/launch_url.sh","launch_url.sh") + self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin") + if self.prefix("res-sdl"): + self.path("*") + # recurse + self.end_prefix("res-sdl") + + # plugins + if self.prefix(src="", dst="bin/llplugin"): + self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") + self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") + self.end_prefix("bin/llplugin") + + # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 + self.path("skins/default/xui/en-us/mime_types_linux.xml", "skins/default/xui/en-us/mime_types.xml") + + self.path("featuretable_linux.txt") def package_finish(self): @@ -904,17 +938,7 @@ class Linux_i686Manifest(LinuxManifest): def construct(self): super(Linux_i686Manifest, self).construct() self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") -# self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin") - self.path("linux_tools/launch_url.sh","launch_url.sh") - if self.prefix("res-sdl"): - self.path("*") - # recurse - self.end_prefix("res-sdl") - - self.path("featuretable_linux.txt") - #self.path("secondlife-i686.supp") - self.path("app_settings/mozilla-runtime-linux-i686") if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"): self.path("libapr-1.so.0") diff --git a/linden/indra/newview/viewer_manifest.py~ b/linden/indra/newview/viewer_manifest.py~ new file mode 100755 index 000000000..452b1658d --- /dev/null +++ b/linden/indra/newview/viewer_manifest.py~ @@ -0,0 +1,1176 @@ +#!/usr/bin/python +# @file viewer_manifest.py +# @author Ryan Williams +# @brief Description of all installer viewer files, and methods for packaging +# them into installers for all supported platforms. +# +# $LicenseInfo:firstyear=2006&license=viewergpl$ +# +# Copyright (c) 2006-2009, Linden Research, Inc. +# +# Second Life Viewer Source Code +# The source code in this file ("Source Code") is provided by Linden Lab +# to you under the terms of the GNU General Public License, version 2.0 +# ("GPL"), unless you have obtained a separate licensing agreement +# ("Other License"), formally executed by you and Linden Lab. Terms of +# the GPL can be found in doc/GPL-license.txt in this distribution, or +# online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +# +# There are special exceptions to the terms and conditions of the GPL as +# it is applied to this Source Code. View the full text of the exception +# in the file doc/FLOSS-exception.txt in this software distribution, or +# online at +# http://secondlifegrid.net/programs/open_source/licensing/flossexception +# +# By copying, modifying or distributing this software, you acknowledge +# that you have read and understood your obligations described above, +# and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +# DO NOT RUN THIS FILE DIRECTLY +# Instead, run develop.py with "configure -DPACKAGE:BOOL=ON" e.g.: +# develop.py -G vc80 configure -DPACKAGE:BOOL=ON +# to generate the "package" project in Visual Studio 2005 +# Note: as of Imprudence 1.3, this defaults to on for Windows + +import sys +import os.path +import re +import tarfile +viewer_dir = os.path.dirname(__file__) +# add llmanifest library to our path so we don't have to muck with PYTHONPATH +sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util')) +from llmanifest import LLManifest, main, proper_windows_path, path_ancestors + +class ViewerManifest(LLManifest): + def construct(self): + super(ViewerManifest, self).construct() + self.exclude("*.svn*") + self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg") + self.path(src="../../etc/message.xml", dst="app_settings/message.xml") + + if self.prefix(src="app_settings"): + self.exclude("logcontrol.xml") + self.exclude("logcontrol-dev.xml") + self.path("*.pem") + self.path("*.ini") + self.path("*.xml") + self.path("*.db2") + + # include the entire shaders directory recursively + self.path("shaders") + # ... and the entire windlight directory + self.path("windlight") + self.end_prefix("app_settings") + + if self.prefix(src="character"): + self.path("*.llm") + self.path("*.xml") + self.path("*.tga") + self.end_prefix("character") + + # Include our fonts + if self.prefix(src="fonts"): + self.path("LiberationSans-Bold.ttf") + self.path("LiberationSans-Regular.ttf") + self.path("VeraMono.ttf") + self.path("DejaVuSansCondensed-BoldOblique.ttf") + self.path("DejaVuSansCondensed-Bold.ttf") + self.path("DejaVuSansCondensed-Oblique.ttf") + self.path("DejaVuSansCondensed.ttf") + self.path("GPL.txt") + self.path("Liberation-License.txt") + self.path("Vera-License.txt") + self.end_prefix("fonts") + + # skins + if self.prefix(src="skins"): + self.path("paths.xml") + # include the entire textures directory recursively + if self.prefix(src="*/textures"): + self.path("*.tga") + self.path("*.j2c") + self.path("*.jpg") + self.path("*.png") + self.path("textures.xml") + self.end_prefix("*/textures") + self.path("*/xui/*/*.xml") + self.path("*/*.xml") + + # Local HTML files (e.g. loading screen) + if self.prefix(src="*/html"): + self.path("*.png") + self.path("*/*/*.html") + self.path("*/*/*.gif") + self.path("*/*/*.png") + self.end_prefix("*/html") + self.end_prefix("skins") + + # Files in the newview/ directory + self.path("gpu_table.txt") + + + # Gather up the README file, etc. + def gather_documents(self): + # From the top level directory (imprudence) + if self.prefix("../../..", dst=""): + self.path("README.txt") + self.path("MANIFESTO.txt") + self.path("CONTRIBUTE.txt") + self.path("RELEASE_NOTES.txt") + self.path("ChangeLog.txt", required=False) + self.end_prefix("../../..") + + # From the linden directory + if self.prefix("../..", dst="doc"): + self.path("LICENSE-source.txt") + self.path("LICENSE-logos.txt", "LICENSE-artwork.txt") + self.end_prefix("../..") + + # From the linden/doc directory + if self.prefix("../../doc", dst="doc"): + self.path("contributions.txt") + self.path("GPL-license.txt", "GPL.txt") + self.path("FLOSS-exception.txt") + self.end_prefix("../../doc") + + + def login_channel(self): + """Channel reported for login and upgrade purposes ONLY; + used for A/B testing""" + # NOTE: Do not return the normal channel if login_channel + # is not specified, as some code may branch depending on + # whether or not this is present + return self.args.get('login_channel') + + def grid(self): + return self.args['grid'] + def channel(self): + return self.args['channel'] + def channel_unique(self): + return self.channel().replace("Imprudence", "").strip() + def channel_oneword(self): + return "".join(self.channel_unique().split()) + def channel_lowerword(self): + return self.channel_oneword().lower() + + def flags_list(self): + """ Convenience function that returns the command-line flags + for the grid""" + + # Set command line flags relating to the target grid + grid_flags = '' + if not self.default_grid(): + grid_flags = "--grid %(grid)s "\ + "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\ + {'grid':self.grid()} + + # set command line flags for channel + channel_flags = '' + if self.login_channel() and self.login_channel() != self.channel(): + # Report a special channel during login, but use default + channel_flags = '--channel "%s"' % (self.login_channel()) + elif not self.default_channel(): + channel_flags = '--channel "%s"' % self.channel() + + # Deal with settings + setting_flags = '' + if not self.default_channel() or not self.default_grid(): + if self.default_grid(): + setting_flags = '--settings settings_%s.xml'\ + % self.channel_lowerword() + else: + setting_flags = '--settings settings_%s_%s.xml'\ + % (self.grid(), self.channel_lowerword()) + + return " ".join((channel_flags, grid_flags, setting_flags)).strip() + + +class WindowsManifest(ViewerManifest): + def final_exe(self): + if self.default_channel(): + if self.default_grid(): + return "imprudence.exe" + else: + return "imprudencepreview.exe" + else: + return ''.join(self.channel().split()) + '.exe' + + + def construct(self): + super(WindowsManifest, self).construct() + # the final exe is complicated because we're not sure where it's coming from, + # nor do we have a fixed name for the executable + self.path(self.find_existing_file('debug/imprudence-bin.exe', 'release/imprudence-bin.exe', 'relwithdebinfo/imprudence-bin.exe'), dst=self.final_exe()) + + self.gather_documents() + + if self.prefix("../..", dst="doc"): + self.path("LICENSE-libraries.txt") + self.end_prefix("../..") + + + self.path("imprudence.url") + + # Plugin host application + self.path(os.path.join(os.pardir, + 'llplugin', 'slplugin', self.args['configuration'], "SLPlugin.exe"), + "SLPlugin.exe") + + + self.path("featuretable.txt") + + # For use in crash reporting (generates minidumps) + self.path("dbghelp.dll") + + # For using FMOD for sound... DJS + #self.path("fmod.dll") + + # For spellchecking + self.path("libhunspell.dll") + + # For textures + if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): + self.path("openjpeg.dll") + self.end_prefix() + + # For sound + if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): + self.path("openal32.dll") + self.path("alut.dll") + self.end_prefix() + + + # Media plugins - QuickTime + if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"): + self.path("media_plugin_quicktime.dll") + self.end_prefix() + + # Media plugins - WebKit/Qt + if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"): + self.path("media_plugin_webkit.dll") + self.end_prefix() + + # For WebKit/Qt plugin runtimes + if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"): + self.path("libeay32.dll") + self.path("qtcore4.dll") + self.path("qtgui4.dll") + self.path("qtnetwork4.dll") + self.path("qtopengl4.dll") + self.path("qtwebkit4.dll") + self.path("ssleay32.dll") + self.end_prefix() + + # For WebKit/Qt plugin runtimes (image format plugins) + if self.prefix(src="../../libraries/i686-win32/lib/release/imageformats", dst="llplugin/imageformats"): + self.path("qgif4.dll") + self.path("qico4.dll") + self.path("qjpeg4.dll") + self.path("qmng4.dll") + self.path("qsvg4.dll") + self.path("qtiff4.dll") + self.end_prefix() + + # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 + self.path("skins/default/xui/en-us/mime_types_windows.xml", "skins/default/xui/en-us/mime_types.xml") + + # These need to be installed as a SxS assembly, currently a 'private' assembly. + # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx + if self.prefix(src=self.args['configuration'], dst=""): + if self.args['configuration'] == 'Debug': + self.path("msvcr80d.dll") + self.path("msvcp80d.dll") + self.path("Microsoft.VC80.DebugCRT.manifest") + else: + self.path("msvcr80.dll") + self.path("msvcp80.dll") + self.path("Microsoft.VC80.CRT.manifest") + self.end_prefix() + + # The config file name needs to match the exe's name. + self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst=self.final_exe() + ".config") + + # We need this one too, so that llkdu loads at runtime - DEV-41194 + #self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst="llkdu.dll.2.config") + self.path("llkdu.dll.2.config") + + # We need this one too, so that win_crash_logger.exe loads at runtime - DEV-19004 + #self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst="win_crash_logger.exe.config") + + # same thing for auto-updater. + #self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst="updater.exe.config") + + # Vivox runtimes + if self.prefix(src="vivox-runtime/i686-win32", dst=""): + # self.path("alut.dll") + self.path("wrap_oal.dll") + self.path("SLVoice.exe") + # self.path("SLVoiceAgent.exe") + # self.path("libeay32.dll") + # self.path("srtp.dll") + # self.path("ssleay32.dll") + # self.path("tntk.dll") + self.path("vivoxsdk.dll") + self.path("ortp.dll") + + self.end_prefix() + + # Gstreamer plugins + if self.prefix(src="lib/gstreamer-plugins", dst=""): + self.path("*.dll", dst="lib/gstreamer-plugins/*.dll") + self.end_prefix() + + # Gstreamer libs + if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): + self.path("iconv.dll") + self.path("libxml2.dll") + self.path("libcairo-2.dll") + self.path("libgio-2.0-0.dll") + self.path("libglib-2.0-0.dll") + self.path("libgmodule-2.0-0.dll") + self.path("libgobject-2.0-0.dll") + self.path("libgthread-2.0-0.dll") + self.path("charset.dll") + self.path("intl.dll") + self.path("libgcrypt-11.dll") + self.path("libgnutls-26.dll") + self.path("libgpg-error-0.dll") + self.path("libgstapp.dll") + self.path("libgstaudio.dll") + self.path("libgstbase-0.10.dll") + self.path("libgstcdda.dll") + self.path("libgstcontroller-0.10.dll") + self.path("libgstdataprotocol-0.10.dll") + self.path("libgstdshow.dll") + self.path("libgstfft.dll") + self.path("libgstinterfaces.dll") + self.path("libgstnet-0.10.dll") + self.path("libgstnetbuffer.dll") + self.path("libgstpbutils.dll") + self.path("libgstreamer-0.10.dll") + self.path("libgstriff.dll") + self.path("libgstrtp.dll") + self.path("libgstrtsp.dll") + self.path("libgstsdp.dll") + self.path("libgsttag.dll") + self.path("libgstvideo.dll") + self.path("libjpeg.dll") + self.path("libmp3lame-0.dll") + self.path("libneon-27.dll") + self.path("libogg-0.dll") + self.path("liboil-0.3-0.dll") + self.path("libopenjpeg-2.dll") + self.path("libpng12-0.dll") + self.path("libschroedinger-1.0-0.dll") + self.path("libspeex-1.dll") + self.path("libtheora-0.dll") + self.path("libvorbis-0.dll") + self.path("libvorbisenc-2.dll") + self.path("libxml2-2.dll") + self.path("glew32.dll") + self.path("xvidcore.dll") + self.path("zlib1.dll") + self.end_prefix() + +# # pull in the crash logger and updater from other projects +# self.path(src=self.find_existing_file( # tag:"crash-logger" here as a cue to the exporter +# "../win_crash_logger/debug/windows-crash-logger.exe", +# "../win_crash_logger/release/windows-crash-logger.exe", +# "../win_crash_logger/relwithdebinfo/windows-crash-logger.exe"), +# dst="win_crash_logger.exe") + self.path(src=self.find_existing_file( + "../win_updater/debug/windows-updater.exe", + "../win_updater/release/windows-updater.exe", + "../win_updater/relwithdebinfo/windows-updater.exe"), + dst="updater.exe") + + # For google-perftools tcmalloc allocator. + #if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): + # self.path("libtcmalloc_minimal.dll") + # self.end_prefix() + + + def nsi_file_commands(self, install=True): + def wpath(path): + if path.endswith('/') or path.endswith(os.path.sep): + path = path[:-1] + path = path.replace('/', '\\') + return path + + result = "" + dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])] + # sort deepest hierarchy first + dest_files.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b)) + dest_files.reverse() + out_path = None + for pkg_file in dest_files: + rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,'')) + installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file))) + pkg_file = wpath(os.path.normpath(pkg_file)) + if installed_dir != out_path: + if install: + out_path = installed_dir + result += 'SetOutPath ' + out_path + '\n' + if install: + result += 'File ' + pkg_file + '\n' + else: + result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n' + # at the end of a delete, just rmdir all the directories + if not install: + deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list] + # find all ancestors so that we don't skip any dirs that happened to have no non-dir children + deleted_dirs = [] + for d in deleted_file_dirs: + deleted_dirs.extend(path_ancestors(d)) + # sort deepest hierarchy first + deleted_dirs.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b)) + deleted_dirs.reverse() + prev = None + for d in deleted_dirs: + if d != prev: # skip duplicates + result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n' + prev = d + + return result + + def package_finish(self): + # a standard map of strings for replacing in the templates + substitution_strings = { + 'version' : '.'.join(self.args['version']).replace(' ', '_'), + 'version_short' : '.'.join(self.args['version'][:-1]).replace(' ', '_'), + 'version_dashes' : '-'.join(self.args['version']).replace(' ', '_'), + 'final_exe' : self.final_exe(), + 'grid':self.args['grid'], + 'grid_caps':self.args['grid'].upper(), + # escape quotes becase NSIS doesn't handle them well + 'flags':self.flags_list().replace('"', '$\\"'), + 'channel':self.channel(), + 'channel_oneword':self.channel_oneword(), + 'channel_unique':self.channel_unique(), + } + + version_vars = """ + !define INSTEXE "%(final_exe)s" + !define VERSION "%(version_short)s" + !define VERSION_LONG "%(version)s" + !define VERSION_DASHES "%(version_dashes)s" + """ % substitution_strings + if self.default_channel(): + if self.default_grid(): + # release viewer + installer_file = "Imprudence_%(version_dashes)s_Setup.exe" + grid_vars_template = """ + OutFile "%(installer_file)s" + !define INSTFLAGS "%(flags)s" + !define INSTNAME "Imprudence" + !define SHORTCUT "Imprudence" + !define URLNAME "imprudence" + Caption "Imprudence ${VERSION}" + """ + else: + # beta grid viewer + installer_file = "Imprudence_%(version_dashes)s_(%(grid_caps)s)_Setup.exe" + grid_vars_template = """ + OutFile "%(installer_file)s" + !define INSTFLAGS "%(flags)s" + !define INSTNAME "Imprudence%(grid_caps)s" + !define SHORTCUT "Imprudence (%(grid_caps)s)" + !define URLNAME "imprudence%(grid)s" + !define UNINSTALL_SETTINGS 1 + Caption "Imprudence %(grid)s ${VERSION}" + """ + else: + # some other channel on some grid + installer_file = "Imprudence_%(version_dashes)s_%(channel_oneword)s_Setup.exe" + grid_vars_template = """ + OutFile "%(installer_file)s" + !define INSTFLAGS "%(flags)s" + !define INSTNAME "Imprudence%(channel_oneword)s" + !define SHORTCUT "%(channel)s" + !define URLNAME "imprudence" + !define UNINSTALL_SETTINGS 1 + Caption "%(channel)s ${VERSION}" + """ + if 'installer_name' in self.args: + installer_file = self.args['installer_name'] + else: + installer_file = installer_file % substitution_strings + substitution_strings['installer_file'] = installer_file + + tempfile = "imprudence_setup_tmp.nsi" + # the following replaces strings in the nsi template + # it also does python-style % substitution + self.replace_in("installers/windows/installer_template.nsi", tempfile, { + "%%VERSION%%":version_vars, + "%%SOURCE%%":self.get_src_prefix(), + "%%GRID_VARS%%":grid_vars_template % substitution_strings, + "%%INSTALL_FILES%%":self.nsi_file_commands(True), + "%%DELETE_FILES%%":self.nsi_file_commands(False)}) + + # We use the Unicode version of NSIS, available from + # http://www.scratchpaper.com/ + NSIS_path = 'C:\\Program Files\\NSIS\\Unicode\\makensis.exe' + self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile)) + # self.remove(self.dst_path_of(tempfile)) + # If we're on a build machine, sign the code using our Authenticode certificate. JC + sign_py = 'C:\\buildscripts\\code-signing\\sign.py' + if os.path.exists(sign_py): + self.run_command(sign_py + ' ' + self.dst_path_of(installer_file)) + else: + print "Skipping code signing,", sign_py, "does not exist" + self.created_path(self.dst_path_of(installer_file)) + self.package_file = installer_file + + +class DarwinManifest(ViewerManifest): + def construct(self): + # copy over the build result (this is a no-op if run within the xcode script) + self.path(self.args['configuration'] + "/Imprudence.app", dst="") + + if self.prefix(src="", dst="Contents"): # everything goes in Contents + + self.path("Info-Imprudence.plist", dst="Info.plist") + + # copy additional libs in <bundle>/Contents/MacOS/ + if self.prefix(src="../../libraries/universal-darwin/lib_release", dst="MacOS/"): + + self.path("libndofdev.dylib") + + self.path("libopenal.1.dylib") + self.path("libalut.0.dylib") + + self.path("libglib-2.0.dylib") + self.path("libgmodule-2.0.dylib") + self.path("libgobject-2.0.dylib") + self.path("libgthread-2.0.dylib") + + self.path("libgstreamer-0.10.dylib") + self.path("libgstapp-0.10.dylib") + self.path("libgstaudio-0.10.dylib") + self.path("libgstbase-0.10.dylib") + self.path("libgstcdda-0.10.dylib") + self.path("libgstcontroller-0.10.dylib") + self.path("libgstdataprotocol-0.10.dylib") + self.path("libgstfft-0.10.dylib") + self.path("libgstinterfaces-0.10.dylib") + self.path("libgstnet-0.10.dylib") + self.path("libgstnetbuffer-0.10.dylib") + self.path("libgstpbutils-0.10.dylib") + self.path("libgstriff-0.10.dylib") + self.path("libgstrtp-0.10.dylib") + self.path("libgstrtsp-0.10.dylib") + self.path("libgstsdp-0.10.dylib") + self.path("libgsttag-0.10.dylib") + self.path("libgstvideo-0.10.dylib") + + self.path("libxml2.2.dylib") + self.path("libfaad.2.dylib") + self.path("libFLAC.8.dylib") + self.path("libintl.3.dylib") + self.path("libjpeg.62.dylib") + self.path("libpng12.0.dylib") + self.path("libneon.27.dylib") + self.path("libogg.0.dylib") + self.path("liboil-0.3.0.dylib") + self.path("libopenjpeg.1.4.dylib") + self.path("libtheora.0.dylib") + self.path("libvorbis.0.dylib") + self.path("libvorbisenc.2.dylib") + self.path("libvorbisfile.3.dylib") + + self.end_prefix("../../libraries/universal-darwin/lib_release") + + # most everything goes in the Resources directory + if self.prefix(src="", dst="Resources"): + super(DarwinManifest, self).construct() + + if self.prefix("cursors_mac"): + self.path("*.tif") + self.end_prefix("cursors_mac") + + # From the linden directory + if self.prefix("../..", dst="doc"): + self.path("LICENSE-libraries.txt") + self.end_prefix("../..") + + self.gather_documents() + + self.path("featuretable_mac.txt") + self.path("SecondLife.nib") + + self.path("viewer.icns") + + # Translations + self.path("English.lproj") + self.path("German.lproj") + self.path("Japanese.lproj") + self.path("Korean.lproj") + self.path("da.lproj") + self.path("es.lproj") + self.path("fr.lproj") + self.path("hu.lproj") + self.path("it.lproj") + self.path("nl.lproj") + self.path("pl.lproj") + self.path("pt.lproj") + self.path("ru.lproj") + self.path("tr.lproj") + self.path("uk.lproj") + self.path("zh-Hans.lproj") + + + if self.prefix(src="../../libraries/universal-darwin/lib_release/gstreamer-plugins", dst="lib/gstreamer-plugins"): + self.path("libgstaacparse.so") + self.path("libgstadder.so") + self.path("libgstaiffparse.so") + self.path("libgstamrparse.so") + self.path("libgstapp.so") + self.path("libgstaudioconvert.so") + self.path("libgstaudiorate.so") + self.path("libgstaudioresample.so") + self.path("libgstautodetect.so") + self.path("libgstavi.so") + self.path("libgstcoreelements.so") + self.path("libgstcoreindexers.so") + self.path("libgstdebug.so") + self.path("libgstdecodebin.so") + self.path("libgstdecodebin2.so") + self.path("libgstdeinterlace2.so") + self.path("libgstequalizer.so") + self.path("libgstfaad.so") + self.path("libgstffmpeg.so") + self.path("libgstffmpegcolorspace.so") + self.path("libgstffmpegscale.so") + self.path("libgstfilter.so") + self.path("libgstflac.so") + self.path("libgstflv.so") + self.path("libgstgdp.so") + self.path("libgsth264parse.so") + self.path("libgsticydemux.so") + self.path("libgstid3demux.so") + self.path("libgstinterleave.so") + self.path("libgstjpeg.so") + self.path("libgstlevel.so") + self.path("libgstmetadata.so") + self.path("libgstmpeg4videoparse.so") + self.path("libgstmpegdemux.so") + self.path("libgstmpegvideoparse.so") + self.path("libgstmultifile.so") + self.path("libgstmultipart.so") + self.path("libgstneonhttpsrc.so") + self.path("libgstogg.so") + self.path("libgstosxaudio.so") + self.path("libgstosxvideosink.so") + self.path("libgstplaybin.so") + self.path("libgstpng.so") + self.path("libgstpostproc.so") + self.path("libgstqtdemux.so") + #self.path("libgstqtwrapper.so") + self.path("libgstqueue2.so") + self.path("libgstreal.so") + self.path("libgstrtp.so") + self.path("libgstrtpmanager.so") + self.path("libgstrtsp.so") + self.path("libgstsdpelem.so") + self.path("libgstselector.so") + self.path("libgststereo.so") + self.path("libgsttcp.so") + self.path("libgsttheora.so") + self.path("libgsttypefindfunctions.so") + self.path("libgstudp.so") + self.path("libgstvideobalance.so") + self.path("libgstvideobox.so") + self.path("libgstvideocrop.so") + self.path("libgstvideoflip.so") + self.path("libgstvideomixer.so") + self.path("libgstvideorate.so") + self.path("libgstvideoscale.so") + self.path("libgstvideosignal.so") + self.path("libgstvolume.so") + self.path("libgstvorbis.so") + self.path("libgstwavparse.so") + + self.end_prefix("../../libraries/universal-darwin/lib_release/gstreamer-plugins") + + + # SLVoice and vivox lols + self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib") + self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib") + self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib") + self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib") + self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice") + #self.path("vivox-runtime/universal-darwin/SLVoiceAgent.app", "SLVoiceAgent.app") + + #libfmodwrapper.dylib + #self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib") + + # our apps +# self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") + self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") + + # plugin launcher + self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin") + + # plugins + if self.prefix(src="", dst="llplugin"): + self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib") + self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib") + self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib") + + self.end_prefix("llplugin") + + # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 + self.path("skins/default/xui/en-us/mime_types_mac.xml", "skins/default/xui/en-us/mime_types.xml") + + # command line arguments for connecting to the proper grid + self.put_in_file(self.flags_list(), 'arguments.txt') + + self.end_prefix("Resources") + + self.end_prefix("Contents") + + # NOTE: the -S argument to strip causes it to keep enough info for + # annotated backtraces (i.e. function names in the crash log). 'strip' with no + # arguments yields a slightly smaller binary but makes crash logs mostly useless. + # This may be desirable for the final release. Or not. + if ("package" in self.args['actions'] or + "unpacked" in self.args['actions']): + self.run_command('strip -S "%(viewer_binary)s"' % + { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')}) + + + def package_finish(self): + channel_standin = 'Imprudence' # hah, our default channel is not usable on its own + if not self.default_channel(): + channel_standin = self.channel() + + imagename="Imprudence_" + '_'.join(self.args['version']) + + # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning. + # If we really need differently named volumes, we'll need to create multiple DS_Store file images, or use some other trick. + + volname="Imprudence Installer" # DO NOT CHANGE without understanding comment above + + if self.default_channel(): + if not self.default_grid(): + # beta case + imagename = imagename + '_' + self.args['grid'].upper() + else: + # first look, etc + imagename = imagename + '_' + self.channel_oneword().upper() + + sparsename = imagename + ".sparseimage" + finalname = imagename + ".dmg" + # make sure we don't have stale files laying about + self.remove(sparsename, finalname) + + self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 400 -layout SPUD' % { + 'sparse':sparsename, + 'vol':volname}) + + # mount the image and get the name of the mount point and device node + hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"') + devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip() + volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip() + + # Copy everything in to the mounted .dmg + + if self.default_channel() and not self.default_grid(): + app_name = "Imprudence " + self.args['grid'] + else: + app_name = channel_standin.strip() + + # Hack: + # Because there is no easy way to coerce the Finder into positioning + # the app bundle in the same place with different app names, we are + # adding multiple .DS_Store files to svn. There is one for release, + # one for release candidate and one for first look. Any other channels + # will use the release .DS_Store, and will look broken. + # - Ambroff 2008-08-20 + dmg_template = os.path.join( + 'installers', + 'darwin', + '%s-dmg' % "".join(self.channel_unique().split()).lower()) + + if not os.path.exists (self.src_path_of(dmg_template)): + dmg_template = os.path.join ('installers', 'darwin', 'release-dmg') + + for s,d in {self.get_dst_prefix():app_name + ".app", + os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns", + os.path.join(dmg_template, "background.jpg"): "background.jpg", + os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items(): + print "Copying to dmg", s, d + self.copy_action(self.src_path_of(s), os.path.join(volpath, d)) + + # Hide the background image, DS_Store file, and volume icon file (set their "visible" bit) + self.run_command('SetFile -a V "' + os.path.join(volpath, ".VolumeIcon.icns") + '"') + self.run_command('SetFile -a V "' + os.path.join(volpath, "background.jpg") + '"') + self.run_command('SetFile -a V "' + os.path.join(volpath, ".DS_Store") + '"') + + # Create the alias file (which is a resource file) from the .r + self.run_command('rez "' + self.src_path_of("installers/darwin/release-dmg/Applications-alias.r") + '" -o "' + os.path.join(volpath, "Applications") + '"') + + # Set the alias file's alias and custom icon bits + self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"') + + # Set the disk image root's custom icon bit + self.run_command('SetFile -a C "' + volpath + '"') + + # Unmount the image + self.run_command('hdiutil detach -force "' + devfile + '"') + + print "Converting temp disk image to final disk image" + self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname}) + # get rid of the temp file + self.package_file = finalname + self.remove(sparsename) + +class LinuxManifest(ViewerManifest): + def construct(self): + super(LinuxManifest, self).construct() + + self.path("res/imprudence_icon.png","imprudence_icon.png") + if self.prefix("linux_tools", dst=""): + #self.path("client-readme.txt","README-linux.txt") + self.path("client-readme-voice.txt","README-linux-voice.txt") + #self.path("client-readme-joystick.txt","README-linux-joystick.txt") + self.path("wrapper.sh","imprudence") + self.path("handle_secondlifeprotocol.sh") + self.path("register_secondlifeprotocol.sh") + self.path("getvoice.sh") + self.end_prefix("linux_tools") + + self.gather_documents() + + # From the linden directory + if self.prefix("../..", dst="doc"): + self.path("LICENSE-libraries.txt") + self.end_prefix("../..") + + # Create an appropriate gridargs.dat for this package, denoting required grid. + self.put_in_file(self.flags_list(), 'gridargs.dat') + self.path("linux_tools/launch_url.sh","launch_url.sh") + self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin") + if self.prefix("res-sdl"): + self.path("*") + # recurse + self.end_prefix("res-sdl") + + # plugins + if self.prefix(src="", dst="bin/llplugin"): + self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") + self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") + self.end_prefix("bin/llplugin") + + # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 + self.path("skins/default/xui/en-us/mime_types_linux.xml", "skins/default/xui/en-us/mime_types.xml") + + self.path("featuretable_linux.txt") + + + def package_finish(self): + if 'installer_name' in self.args: + installer_name = self.args['installer_name'] + else: + installer_name_components = ['Imprudence_', self.args.get('arch')] + installer_name_components.extend(self.args['version']) + installer_name = "_".join(installer_name_components) + if self.default_channel(): + if not self.default_grid(): + installer_name += '_' + self.args['grid'].upper() + else: + installer_name += '_' + self.channel_oneword().upper() + + # Fix access permissions + self.run_command(""" + find %(dst)s -type d | xargs --no-run-if-empty chmod 755; + find %(dst)s -type f -perm 0700 | xargs --no-run-if-empty chmod 0755; + find %(dst)s -type f -perm 0500 | xargs --no-run-if-empty chmod 0555; + find %(dst)s -type f -perm 0600 | xargs --no-run-if-empty chmod 0644; + find %(dst)s -type f -perm 0400 | xargs --no-run-if-empty chmod 0444; + true""" % {'dst':self.get_dst_prefix() }) + + self.package_file = installer_name + '.tar.bz2' + + # Disabled for now. It's a waste of time to package every compile. + + # if("package" in self.args['actions'] or + # "unpacked" in self.args['actions']): + # + # # temporarily move directory tree so that it has the right + # # name in the tarfile + # self.run_command("mv %(dst)s %(inst)s" % { + # 'dst': self.get_dst_prefix(), + # 'inst': self.build_path_of(installer_name)}) + # try: + # # --numeric-owner hides the username of the builder for + # # security etc. + # self.run_command('tar -C %(dir)s --numeric-owner -cjf ' + # '%(inst_path)s.tar.bz2 %(inst_name)s' % { + # 'dir': self.get_build_prefix(), + # 'inst_name': installer_name, + # 'inst_path':self.build_path_of(installer_name)}) + # finally: + # self.run_command("mv %(inst)s %(dst)s" % { + # 'dst': self.get_dst_prefix(), + # 'inst': self.build_path_of(installer_name)}) + +class Linux_i686Manifest(LinuxManifest): + def construct(self): + super(Linux_i686Manifest, self).construct() + self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") + + + if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"): + self.path("libapr-1.so.0") + self.path("libaprutil-1.so.0") + self.path("libdb-4.2.so") + self.path("libcrypto.so.0.9.7") + self.path("libexpat.so.1") + self.path("libssl.so.0.9.7") + self.path("libuuid.so", "libuuid.so.1") + self.path("libSDL-1.2.so.0") + self.path("libELFIO.so") + self.path("libopenjpeg.so.2") + self.path("libxml2.so.2") + self.path("libz.so.1") + + # OpenAL + self.path("libopenal.so.1") + self.path("libalut.so.0") + + # GTK+ and dependencies + self.path("libatk-1.0.so.0") + self.path("libcairo.so.2") + self.path("libfontconfig.so.1") + self.path("libfreetype.so.6") + # self.path("libgdk_pixbuf-2.0.so.0") # see linux64 why + self.path("libgdk-x11-2.0.so.0") + self.path("libgtk-x11-2.0.so.0") + # self.path("libpango-1.0.so.0") # dto. + # self.path("libpangoft2-1.0.so.0") + # self.path("libpangox-1.0.so.0") + # self.path("libpangoxft-1.0.so.0") + self.path("libpixman-1.so.0") + + # Gstreamer libs + self.path("libgstbase-0.10.so.0") + self.path("libgstreamer-0.10.so.0") + self.path("libgstaudio-0.10.so.0") + self.path("libgstbase-0.10.so.0") + self.path("libgstcontroller-0.10.so.0") + self.path("libgstdataprotocol-0.10.so.0") + self.path("libgstinterfaces-0.10.so.0") + self.path("libgstnetbuffer-0.10.so.0") + self.path("libgstpbutils-0.10.so.0") + self.path("libgstriff-0.10.so.0") + self.path("libgstrtp-0.10.so.0") + self.path("libgstrtsp-0.10.so.0") + self.path("libgstsdp-0.10.so.0") + self.path("libgsttag-0.10.so.0") + self.path("libgstvideo-0.10.so.0") + + # Gstreamer plugin dependencies + self.path("libfaad.so.0") + self.path("libogg.so.0") + self.path("libtheora.so.0") + self.path("libvorbis.so.0") + self.path("libvorbisenc.so.2") + self.path("liboil-0.3.so.0") + + # Gstreamer plugins + if self.prefix("gstreamer-plugins"): + self.path("libgstalsa.so") + self.path("libgstasf.so") + self.path("libgstaudioconvert.so") + self.path("libgstaudioresample.so") + self.path("libgstautodetect.so") + self.path("libgstavi.so") + self.path("libgstcoreelements.so") + self.path("libgstcoreindexers.so") + self.path("libgstdecodebin2.so") + self.path("libgstdecodebin.so") + self.path("libgstesd.so") + self.path("libgstfaad.so") + self.path("libgstffmpeg.so") + self.path("libgstgnomevfs.so") + self.path("libgsticydemux.so") + self.path("libgstid3demux.so") + self.path("libgstmpegdemux.so") + self.path("libgstmultifile.so") + self.path("libgstmultipart.so") + self.path("libgstogg.so") + self.path("libgstossaudio.so") + self.path("libgstplaybin.so") + self.path("libgstpulse.so") + self.path("libgstqtdemux.so") + self.path("libgstqueue2.so") + self.path("libgsttcp.so") + self.path("libgsttheora.so") + self.path("libgsttypefindfunctions.so") + self.path("libgstudp.so") + self.path("libgstvideoscale.so") + self.path("libgstvolume.so") + self.path("libgstvorbis.so") + self.path("libgstwavparse.so") + + self.end_prefix("gstreamer-plugins") + + self.end_prefix("lib") + + # Vivox runtimes and libs + if self.prefix(src="vivox-runtime/i686-linux", dst="bin"): + self.path("SLVoice") + self.end_prefix("bin") + + if self.prefix(src="vivox-runtime/i686-linux", dst="lib"): + self.path("libalut.so") + self.path("libortp.so") + self.path("libvivoxsdk.so") + self.end_prefix("lib") + +class Linux_x86_64Manifest(LinuxManifest): + def construct(self): + super(Linux_x86_64Manifest, self).construct() + self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") +# self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin") + + self.path("linux_tools/launch_url.sh","launch_url.sh") + if self.prefix("res-sdl"): + self.path("*") + # recurse + self.end_prefix("res-sdl") + + self.path("featuretable_linux.txt") + #self.path("secondlife-x86_64.supp") + + self.path("app_settings/mozilla-runtime-linux-x86_64") + + if self.prefix("../../libraries/x86_64-linux/lib_release_client", dst="lib64"): + self.path("libapr-1.so.0") + self.path("libaprutil-1.so.0") + self.path("libdb-4.2.so") + self.path("libcrypto.so.0.9.8") + self.path("libexpat.so.1") + self.path("libssl.so.0.9.8") + self.path("libuuid.so", "libuuid.so.1") + self.path("libSDL-1.2.so.0") + self.path("libELFIO.so") + self.path("libjpeg.so.7") + self.path("libpng12.so.0") + self.path("libopenjpeg.so.2") + self.path("libxml2.so.2") + #self.path("libz.so.1") #not needed + + # OpenAL + self.path("libopenal.so.1") + self.path("libalut.so.0") + + # GTK+ and dependencies + self.path("libatk-1.0.so.0") + self.path("libcairo.so.2") + self.path("libfontconfig.so.1") + self.path("libfreetype.so.6") + self.path("libgdk_pixbuf-2.0.so.0") # was commented to use systems gdk pixbufs instead - + # but seems webkit needs it o_O . Packaging for testing now. + self.path("libgdk-x11-2.0.so.0") + self.path("libgtk-x11-2.0.so.0") +# self.path("libpango-1.0.so.0") # use systems pango instead +# self.path("libpangoft2-1.0.so.0") # Both gdk pixbufs and pango would load systems modules +# self.path("libpangox-1.0.so.0") # and crash if not compatible or present. +# self.path("libpangoxft-1.0.so.0") # So we depend system gdk pixbufs and pango anyway. + self.path("libpixman-1.so.0") + + # Gstreamer libs + self.path("libgstbase-0.10.so.0") + self.path("libgstreamer-0.10.so.0") + self.path("libgstaudio-0.10.so.0") + self.path("libgstbase-0.10.so.0") + self.path("libgstcontroller-0.10.so.0") + self.path("libgstdataprotocol-0.10.so.0") + self.path("libgstinterfaces-0.10.so.0") + self.path("libgstnetbuffer-0.10.so.0") + self.path("libgstpbutils-0.10.so.0") + self.path("libgstriff-0.10.so.0") + self.path("libgstrtp-0.10.so.0") + self.path("libgstrtsp-0.10.so.0") + self.path("libgstsdp-0.10.so.0") + self.path("libgsttag-0.10.so.0") + self.path("libgstvideo-0.10.so.0") + + # Gstreamer plugin dependencies + self.path("libfaad.so.0") + self.path("libogg.so.0") + self.path("libtheora.so.0") + self.path("libvorbis.so.0") + self.path("libvorbisenc.so.2") + self.path("liboil-0.3.so.0") + + # Gstreamer plugins + if self.prefix("gstreamer-plugins"): + self.path("libgstalsa.so") + self.path("libgstasf.so") + self.path("libgstaudioconvert.so") + self.path("libgstaudioresample.so") + self.path("libgstautodetect.so") + self.path("libgstavi.so") + self.path("libgstcoreelements.so") + self.path("libgstcoreindexers.so") + self.path("libgstdecodebin2.so") + self.path("libgstdecodebin.so") + self.path("libgstesd.so") + self.path("libgstfaad.so") + self.path("libgstffmpeg.so") + self.path("libgstffmpegcolorspace.so") + self.path("libgstgnomevfs.so") + self.path("libgsticydemux.so") + self.path("libgstid3demux.so") + self.path("libgstmpegdemux.so") + self.path("libgstmultifile.so") + self.path("libgstmultipart.so") + self.path("libgstogg.so") + self.path("libgstossaudio.so") + self.path("libgstplaybin.so") + self.path("libgstpulse.so") + self.path("libgstqtdemux.so") + self.path("libgstqueue2.so") + self.path("libgsttcp.so") + self.path("libgsttheora.so") + self.path("libgsttypefindfunctions.so") + self.path("libgstudp.so") + self.path("libgstvideoscale.so") + self.path("libgstvolume.so") + self.path("libgstvorbis.so") + self.path("libgstwavparse.so") + + self.end_prefix("gstreamer-plugins") + self.end_prefix("lib64") + + + # Vivox runtimes and libs + if self.prefix(src="vivox-runtime/i686-linux", dst="bin"): + self.path("SLVoice") + self.end_prefix("bin") + + if self.prefix(src="vivox-runtime/i686-linux", dst="lib32"): + #self.path("libalut.so") + self.path("libortp.so") + self.path("libvivoxsdk.so") + self.end_prefix("lib32") + + # 32bit libs needed for voice + if self.prefix("../../libraries/x86_64-linux/lib_release_client/32bit-compat", dst="lib32"): + self.path("libalut.so") + self.path("libidn.so.11") + self.path("libopenal.so.1") + # self.path("libortp.so") + self.path("libuuid.so.1") + self.end_prefix("lib32") + +if __name__ == "__main__": + main() diff --git a/linden/indra/test_apps/llplugintest/CMakeLists.txt b/linden/indra/test_apps/llplugintest/CMakeLists.txt new file mode 100644 index 000000000..a6cb74007 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/CMakeLists.txt @@ -0,0 +1,378 @@ +# -*- cmake -*- + +project(llplugintest) + +include(00-Common) +include(FindOpenGL) +include(LLCommon) +include(LLPlugin) +include(Linking) +include(PluginAPI) +include(LLImage) +include(LLMath) +include(LLMessage) +include(LLRender) +include(LLWindow) +include(Glut) +include(Glui) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLMESSAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} +) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(COREFOUNDATION_LIBRARY CoreFoundation) +endif (DARWIN) + +### demo_plugin + +#set(demo_plugin_SOURCE_FILES +# demo_plugin.cpp +# ) +# +#add_library(demo_plugin +# SHARED +# ${demo_plugin_SOURCE_FILES} +#) +# +#target_link_libraries(demo_plugin +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +# ${PLUGIN_API_WINDOWS_LIBRARIES} +#) +# +#add_dependencies(demo_plugin +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +#) +# +#if (DARWIN) +# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name +# set_target_properties( +# demo_plugin +# PROPERTIES +# PREFIX "" +# BUILD_WITH_INSTALL_RPATH 1 +# INSTALL_NAME_DIR "@executable_path" +# ) +#endif (DARWIN) + +### plugin_host + +#set(plugin_host_SOURCE_FILES +# plugin_host.cpp +# ) +# +#add_executable(plugin_host +# WIN32 +# ${plugin_host_SOURCE_FILES} +#) +# +#set_target_properties(plugin_host +# PROPERTIES +# WIN32_EXECUTABLE +# FALSE +#) +# +#target_link_libraries(plugin_host +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +# ${PLUGIN_API_WINDOWS_LIBRARIES} +#) +# +#add_dependencies(plugin_host +# demo_plugin +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +#) + +### plugin_process_launcher + +#set(plugin_process_launcher_SOURCE_FILES +# plugin_process_launcher.cpp +# ) +# +#add_executable(plugin_process_launcher +# WIN32 +# ${plugin_process_launcher_SOURCE_FILES} +#) +# +#set_target_properties(plugin_process_launcher +# PROPERTIES +# WIN32_EXECUTABLE +# FALSE +#) +# +#target_link_libraries(plugin_process_launcher +# ${LLPLUGIN_LIBRARIES} +# ${LLMESSAGE_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +# ${PLUGIN_API_WINDOWS_LIBRARIES} +#) +# +#add_dependencies(plugin_process_launcher +# SLPlugin +# demo_plugin +# ${LLPLUGIN_LIBRARIES} +# ${LLMESSAGE_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +#) + +### media_simple_test + +#set(media_simple_test_SOURCE_FILES +# media_simple_test.cpp +# ) +# +#add_executable(media_simple_test +# WIN32 +# ${media_simple_test_SOURCE_FILES} +#) +# +#add_dependencies(media_simple_test copy_win_libs) +# +#set_target_properties(media_simple_test +# PROPERTIES +# WIN32_EXECUTABLE +# FALSE +#) +# +#target_link_libraries(media_simple_test +# ${GLUT_LIBRARY} +# ${OPENGL_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +#) + +### media_plugin_test + +#set(media_plugin_test_SOURCE_FILES +# media_plugin_test.cpp +# ) +# +#add_executable(media_plugin_test +# WIN32 +# ${media_plugin_test_SOURCE_FILES} +#) +# +#set_target_properties(media_plugin_test +# PROPERTIES +# WIN32_EXECUTABLE +# FALSE +#) +# +#target_link_libraries(media_plugin_test +# ${GLUT_LIBRARY} +# ${OPENGL_LIBRARIES} +# ${LLPLUGIN_LIBRARIES} +# ${LLMESSAGE_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +# ${PLUGIN_API_WINDOWS_LIBRARIES} +#) +# +#add_dependencies(media_plugin_test +# copy_win_libs +# SLPlugin +# demo_media_plugin +# ${LLPLUGIN_LIBRARIES} +# ${LLMESSAGE_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +#) + +### demo_media_plugin + +#set(demo_media_plugin_SOURCE_FILES +# demo_media_plugin.cpp +# ) +# +#add_library(demo_media_plugin +# SHARED +# ${demo_media_plugin_SOURCE_FILES} +#) +# +#target_link_libraries(demo_media_plugin +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +# ${PLUGIN_API_WINDOWS_LIBRARIES} +#) +# +#add_dependencies(demo_media_plugin +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +#) +# +#if (DARWIN) +# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name +# set_target_properties( +# demo_media_plugin +# PROPERTIES +# PREFIX "" +# BUILD_WITH_INSTALL_RPATH 1 +# INSTALL_NAME_DIR "@executable_path" +# ) +#endif (DARWIN) + +### demo_media_plugin_2 + +#set(demo_media_plugin_2_SOURCE_FILES +# demo_media_plugin_2.cpp +# ) +# +#add_library(demo_media_plugin_2 +# SHARED +# ${demo_media_plugin_2_SOURCE_FILES} +#) +# +#target_link_libraries(demo_media_plugin_2 +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +# ${PLUGIN_API_WINDOWS_LIBRARIES} +#) +# +#add_dependencies(demo_media_plugin_2 +# ${LLPLUGIN_LIBRARIES} +# ${LLCOMMON_LIBRARIES} +#) +# +#if (DARWIN) +# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name +# set_target_properties( +# demo_media_plugin_2 +# PROPERTIES +# PREFIX "" +# BUILD_WITH_INSTALL_RPATH 1 +# INSTALL_NAME_DIR "@executable_path" +# ) +#endif (DARWIN) + +### llmediaplugintest + +set(llmediaplugintest_SOURCE_FILES + llmediaplugintest.cpp + llmediaplugintest.h + bookmarks.txt + ) + +add_executable(llmediaplugintest + WIN32 + ${llmediaplugintest_SOURCE_FILES} +) + +set_target_properties(llmediaplugintest + PROPERTIES + WIN32_EXECUTABLE + FALSE +) + +target_link_libraries(llmediaplugintest + ${GLUT_LIBRARY} + ${GLUI_LIBRARY} + ${OPENGL_LIBRARIES} + ${LLPLUGIN_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +if (DARWIN) + # The testbed needs to use a couple of CoreFoundation calls now, to deal with being a bundled app. + target_link_libraries(llmediaplugintest + ${COREFOUNDATION_LIBRARY} + ) +endif (DARWIN) + +add_dependencies(llmediaplugintest + copy_win_libs + SLPlugin + media_plugin_quicktime + media_plugin_webkit + media_plugin_example + ${LLPLUGIN_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +# turn off weird GLUI pragma +add_definitions(-DGLUI_NO_LIB_PRAGMA) + +if (DARWIN OR LINUX) + # glui.h contains code that triggers the "overloaded-virtual" warning in gcc. + set_source_files_properties(llmediaplugintest.cpp PROPERTIES COMPILE_FLAGS "-Wno-overloaded-virtual") +endif (DARWIN OR LINUX) + +# Gather build products of the various dependencies into the build directory for the testbed. + +if (DARWIN) + # path inside the app bundle where we'll need to copy plugins and other related files + set(PLUGINS_DESTINATION_DIR + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llmediaplugintest.app/Contents/Resources + ) + + # create the Contents/Resources directory + add_custom_command( + TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + make_directory + ${PLUGINS_DESTINATION_DIR} + COMMENT "Creating Resources directory in app bundle." + ) +else (DARWIN) + set(PLUGINS_DESTINATION_DIR + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ + ) +endif (DARWIN) + +get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION) +add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN} ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_SLPLUGIN} +) + +if (DARWIN OR WINDOWS) + get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION) + add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_WEBKIT_PLUGIN} + ) + + get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION) + add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_QUICKTIME_PLUGIN} ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_QUICKTIME_PLUGIN} + ) + + get_target_property(BUILT_EXAMPLE_PLUGIN media_plugin_example LOCATION) + add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_EXAMPLE_PLUGIN} ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_EXAMPLE_PLUGIN} + ) + + # copy over bookmarks file if llmediaplugintest gets built + get_target_property(BUILT_LLMEDIAPLUGINTEST llmediaplugintest LOCATION) + add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/ + DEPENDS ${BUILT_LLMEDIAPLUGINTEST} + ) + # also copy it to the same place as SLPlugin, which is what the mac wants... + add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR} + DEPENDS ${BUILT_LLMEDIAPLUGINTEST} + ) +endif (DARWIN OR WINDOWS) + +if (DARWIN) + add_custom_command(TARGET llmediaplugintest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR} + DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib + ) +endif (DARWIN) + + diff --git a/linden/indra/test_apps/llplugintest/bookmarks.txt b/linden/indra/test_apps/llplugintest/bookmarks.txt new file mode 100644 index 000000000..796cc5d1b --- /dev/null +++ b/linden/indra/test_apps/llplugintest/bookmarks.txt @@ -0,0 +1,28 @@ +# format is description, url (don't put ',' chars in description :) +# if no ',' found, whole line is used for both description and url +(WK) Google Home Page,http://www.google.com +(WK) BBC News Home Page,http://news.bbc.co.uk +(WK) Second Life,http://secondlife.com +(WK) WebKit Home ,http://www.webkit.org +(WK) Yahoo News,http://news.yahoo.com +(WK) Canvas Paint (DHTML version of MS Paint),http://www.canvaspaint.org +(WK) DHTML Lemmings!,http://www.elizium.nu/scripts/lemmings/ +(WK) DHTML graphics demos,http://www.dhteumeuleu.com/ +(WK) Neat Javascript 3D,http://gyu.que.jp/jscloth/ +(QT) Local sample,file:///C|/Program Files/QuickTime/Sample.mov +(QT) Movie - Watchmen Trailer,http://movies.apple.com/movies/wb/watchmen/watchmen-tlr2_480p.mov +(QT) Movie - Transformers - Revenge of the Fallen,http://movies.apple.com/movies/paramount/transformers2/transformersrevengeofthefallen-tlr1_h.320.mov +(QT) Movie - Terminator Salvation,http://movies.apple.com/movies/wb/terminatorsalvation/terminatorsalvation-tlr3_h.320.mov +(QT) Movie - Angels and Demons,http://movies.apple.com/movies/sony_pictures/angelsanddemons/angelsanddemons-video_h.320.mov +(QT) Movie - Sin City Trailer,http://movies.apple.com/movies/miramax/sin_city/sin_city_480.mov +(QT) Movie - The Incredibles Trailer,http://movies.apple.com/movies/disney/the_incredibles/the_incredibles-tlr_a480.mov +(QT) Movie - Streaming Apple Event,http://stream.qtv.apple.com/events/mar/0903lajkszg/m_090374535329zdwg_650_ref.mov +(QT) Movie - MPEG-4 from Amazon S3,http://s3.amazonaws.com/callum-linden/flashdemo/interactive_flash_demo.mp4 +(QT) Movie - Star Trek,http://movies.apple.com/movies/paramount/star_trek/startrek-tlr3_h.320.mov +(QT) Movie - Ice Age 3,http://movies.apple.com/movies/fox/ice_age_iii/iceage3-tlrd_h.320.mov +(QT) Movie - AstroBoy,http://movies.apple.com/movies/summit/astroboy/astroboy-tsr_h.320.mov +(QT) Movie - Ante Up,http://movies.apple.com/movies/independent/anteup/anteup_h.320.mov +(QT) Movie - Every Little Step,http://movies.apple.com/movies/sony/everylittlestep/everylittlestep-clip_h.320.mov +(QT) Movie - The Informers,http://movies.apple.com/movies/independent/theinformers/theinformers_h.320.mov +(QT) Animated GIF,http://upload.wikimedia.org/wikipedia/commons/4/44/Optical.greysquares.arp-animated.gif +(QT) Apple Text Descriptors,http://ubrowser.com/tmp/apple_text.txt diff --git a/linden/indra/test_apps/llplugintest/demo_media_plugin.cpp b/linden/indra/test_apps/llplugintest/demo_media_plugin.cpp new file mode 100644 index 000000000..89e15fd72 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/demo_media_plugin.cpp @@ -0,0 +1,472 @@ +/** + * @file demo_plugin.cpp + * @brief Test plugin to be loaded by the llplugin testbed. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" + +// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint + +class DemoMediaPlugin +{ +public: + + static int init(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); + +private: + DemoMediaPlugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~DemoMediaPlugin(); + + static void staticReceiveMessage(const char *message_string, void **user_data); + void receiveMessage(const char *message_string); + void sendMessage(const LLPluginMessage &message); + void setDirty(int left, int top, int right, int bottom); + + LLPluginInstance::sendMessageFunction mHostSendFunction; + void *mHostUserData; + bool mDeleteMe; + + class SharedSegmentInfo + { + public: + void *mAddress; + size_t mSize; + }; + + typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap; + + SharedSegmentMap mSharedSegments; + +public: + + void clear(void) + { +// return; + + if(mPixels != NULL) + { + for( int y = 0; y < mHeight; ++y ) + { + unsigned char *row = mPixels + ( y * mTextureWidth * mDepth); + for(int x = 0; x < mWidth; ++x) + { + unsigned char *pixel = row + (x * mDepth); + if(0) + { + pixel[0] = 0x20; + pixel[1] = 0x20; + pixel[2] = 0x20; + } + else + { + pixel[0] = rand() % 0x40; + pixel[1] = rand() % 0x40; + pixel[2] = rand() % 0x40; + } + } + } + + setDirty(0, 0, mWidth, mHeight); + } + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void update() + { + const time_t interval = 5; + static time_t last_time = time( NULL ); + time_t cur_time = time( NULL ); + + if ( cur_time - last_time > interval ) + { + clear(); + + last_time = cur_time; + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ) + { + // make sure we don't write outside the buffer + if((x < 0) || (x >= mWidth) || (y < 0) || (y >= mHeight)) + return; + + if(mPixels != NULL) + { + unsigned char *pixel = mPixels; + pixel += y * mTextureWidth * mDepth; // row offset + pixel += (x * mDepth); // columm offset + pixel[0] = b; + pixel[1] = g; + pixel[2] = r; + + setDirty(x, y, x+1, y+1); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseDown( int x, int y ) + { + write_pixel( x, y, 0xff, 0x00, 0x00 ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseUp( int x, int y ) + { + write_pixel( x, y, 0xff, 0xff, 0x00 ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int x, int y ) + { + write_pixel( x , y , 0xff, 0x00, 0xff ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyPress( unsigned char key ) + { + }; + +private: + unsigned char* mPixels; + int mWidth; + int mHeight; + int mTextureWidth; + int mTextureHeight; + int mDepth; +}; + +int DemoMediaPlugin::init(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + DemoMediaPlugin *self = new DemoMediaPlugin(host_send_func, host_user_data); + *plugin_send_func = staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + + +DemoMediaPlugin::DemoMediaPlugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) +{ + std::cerr << "DemoMediaPlugin constructor" << std::endl; + + mHostSendFunction = host_send_func; + mHostUserData = host_user_data; + mDeleteMe = false; +} + +DemoMediaPlugin::~DemoMediaPlugin() +{ + std::cerr << "DemoMediaPlugin destructor" << std::endl; +} + +void DemoMediaPlugin::staticReceiveMessage(const char *message_string, void **user_data) +{ + DemoMediaPlugin *self = (DemoMediaPlugin*)*user_data; + + if(self != NULL) + { + self->receiveMessage(message_string); + + // If the plugin has processed the delete message, delete it. + if(self->mDeleteMe) + { + delete self; + *user_data = NULL; + } + } +} + +void DemoMediaPlugin::receiveMessage(const char *message_string) +{ +// std::cerr << "DemoMediaPlugin::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + // Normally a plugin would only specify one of these two subclasses, but this is a demo... + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + sendMessage(message); + + // Plugin gets to decide the texture parameters to use. + mDepth = 3; + + message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_RGB); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", false); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + update(); + } + else if(message_name == "shutdown") + { + sendMessage(LLPluginMessage("base", "shutdown_response")); + + mDeleteMe = true; + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = (void*)message_in.getValueU32("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + + std::cerr << "DemoMediaPlugin::receiveMessage: shared memory added, name: " << name + << ", size: " << info.mSize + << ", address: " << info.mAddress + << std::endl; + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + std::cerr << "DemoMediaPlugin::receiveMessage: shared memory remove, name = " << name << std::endl; + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + } + mSharedSegments.erase(iter); + } + else + { + std::cerr << "DemoMediaPlugin::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + std::cerr << "DemoMediaPlugin::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + std::cerr << "Got size change, new size is " << width << " by " << height << std::endl; + std::cerr << " texture size is " << texture_width << " by " << texture_height << std::endl; + + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + clear(); + } + } + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); +// std::string modifiers = message.getValue("modifiers"); + +// std::cerr << "DemoMediaPlugin::receiveMessage: mouse event \"" << event +// << "\", coords " << x << ", " << y +// << std::endl; + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + } + } + else + { + std::cerr << "DemoMediaPlugin::receiveMessage: unknown media message: " << message_string << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) + { + if(message_name == "focus") + { + // foo = message_in.getValueBoolean("focused"); + } + else if(message_name == "clear_cache") + { + } + else if(message_name == "clear_cookies") + { + } + else if(message_name == "enable_cookies") + { + // foo = message_in.getValueBoolean("enable"); + } + else if(message_name == "proxy_setup") + { + // foo = message_in.getValueBoolean("enable"); + // bar = message_in.getValue("host"); + // baz = message_in.getValueS32("port"); + } + else if(message_name == "browse_stop") + { + } + else if(message_name == "browse_reload") + { + // foo = message_in.getValueBoolean("ignore_cache"); + } + else if(message_name == "browse_forward") + { + } + else if(message_name == "browse_back") + { + } + else if(message_name == "set_status_redirect") + { + // foo = message_in.getValueS32("code"); + // bar = message_in.getValue("url"); + } + else + { + std::cerr << "DemoMediaPlugin::receiveMessage: unknown media_browser message: " << message_string << std::endl; + } + } + else + { + std::cerr << "DemoMediaPlugin::receiveMessage: unknown message class: " << message_class << std::endl; + } + + } +} + +void DemoMediaPlugin::sendMessage(const LLPluginMessage &message) +{ + std::string output = message.generate(); + mHostSendFunction(output.c_str(), &mHostUserData); +} + +void DemoMediaPlugin::setDirty(int left, int top, int right, int bottom) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueS32("left", left); + message.setValueS32("top", top); + message.setValueS32("right", right); + message.setValueS32("bottom", bottom); + + sendMessage(message); +} + + +extern "C" +{ +#ifdef WIN32 + __declspec(dllexport) +#endif + int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); +} + +int +#ifdef WIN32 + __declspec(dllexport) +#endif + LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return DemoMediaPlugin::init(host_send_func, host_user_data, plugin_send_func, plugin_user_data); +} + +#ifdef WIN32 +int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* params ) +{ + return 1; +} +#endif diff --git a/linden/indra/test_apps/llplugintest/demo_media_plugin_2.cpp b/linden/indra/test_apps/llplugintest/demo_media_plugin_2.cpp new file mode 100644 index 000000000..7a76f7405 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/demo_media_plugin_2.cpp @@ -0,0 +1,578 @@ +/** + * @file demo_plugin.cpp + * @brief Test plugin to be loaded by the llplugin testbed. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" + +// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint + +class DemoMediaPlugin2 +{ +public: + + static int init(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); + +private: + DemoMediaPlugin2(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~DemoMediaPlugin2(); + + static void staticReceiveMessage(const char *message_string, void **user_data); + void receiveMessage(const char *message_string); + void sendMessage(const LLPluginMessage &message); + void setDirty(int left, int top, int right, int bottom); + + LLPluginInstance::sendMessageFunction mHostSendFunction; + void *mHostUserData; + bool mDeleteMe; + + class SharedSegmentInfo + { + public: + void *mAddress; + size_t mSize; + }; + + typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap; + + SharedSegmentMap mSharedSegments; + +public: + void updatePixels(void) + { + if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 ) + return; + + if ( mPixels == 0 ) + return; + + if ( mFirstTime ) + { + // now we have a valid width/height - we can initialize positions + for( int n = 0; n < NumObjects; ++n ) + { + mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 ); + mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 ); + + mColorR[ n ] = rand() % 0xa0 + 0x60; + mColorG[ n ] = rand() % 0xa0 + 0x60; + mColorB[ n ] = rand() % 0xa0 + 0x60; + + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + + mBlockSize[ n ] = rand() % 0x16 + 0x04; + }; + + delete [] mBackgroundPixels; + + mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ]; + + mFirstTime = false; + }; + + if ( time( NULL ) > mLastUpdateTime + 3 ) + { + const int num_squares = rand() % 20 + 4; + int sqr1_r = rand() % 0x80 + 0x20; + int sqr1_g = rand() % 0x80 + 0x20; + int sqr1_b = rand() % 0x80 + 0x20; + int sqr2_r = rand() % 0x80 + 0x20; + int sqr2_g = rand() % 0x80 + 0x20; + int sqr2_b = rand() % 0x80 + 0x20; + + for ( int y1 = 0; y1 < num_squares; ++y1 ) + { + for ( int x1 = 0; x1 < num_squares; ++x1 ) + { + int px_start = mWidth * x1 / num_squares; + int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares; + int py_start = mHeight * y1 / num_squares; + int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares; + + for( int y2 = py_start; y2 < py_end; ++y2 ) + { + for( int x2 = px_start; x2 < px_end; ++x2 ) + { + int rowspan = mWidth * mDepth; + + if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b; + } + else + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b; + }; + }; + }; + }; + }; + + time( &mLastUpdateTime ); + }; + + memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth ); + + for( int n = 0; n < NumObjects; ++n ) + { + if ( rand() % 50 == 0 ) + { + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + }; + + if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] ) + mXInc[ n ] =- mXInc[ n ]; + + if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] ) + mYInc[ n ] =- mYInc[ n ]; + + mXpos[ n ] += mXInc[ n ]; + mYpos[ n ] += mYInc[ n ]; + + for( int y = 0; y < mBlockSize[ n ]; ++y ) + { + for( int x = 0; x < mBlockSize[ n ]; ++x ) + { + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ]; + }; + }; + }; + + // TODO: experiment with setDirty to just follow block position + setDirty( 0, 0, mWidth, mHeight ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void update() + { + updatePixels(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ) + { + // make sure we don't write outside the buffer + if((x < 0) || (x >= mWidth) || (y < 0) || (y >= mHeight)) + return; + + if( mBackgroundPixels != NULL) + { + unsigned char *pixel = mBackgroundPixels; + pixel += y * mWidth * mDepth; // row offset + pixel += (x * mDepth); // columm offset + pixel[0] = b; + pixel[1] = g; + pixel[2] = r; + + setDirty(x, y, x+1, y+1); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseDown( int x, int y ) + { + write_pixel( x, y, 0xff, 0x00, 0x00 ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseUp( int x, int y ) + { + write_pixel( x, y, 0xff, 0xff, 0x00 ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int x, int y ) + { + write_pixel( x , y , 0xff, 0x00, 0xff ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyPress( unsigned char key ) + { + }; + +private: + unsigned char* mPixels; + int mWidth; + int mHeight; + int mTextureWidth; + int mTextureHeight; + int mDepth; + time_t mLastUpdateTime; + bool mFirstTime; + unsigned char* mBackgroundPixels; + enum Constants2 { NumObjects = 20 }; + int mColorR[ NumObjects ]; + int mColorG[ NumObjects ]; + int mColorB[ NumObjects ]; + int mXpos[ NumObjects ]; + int mYpos[ NumObjects ]; + int mXInc[ NumObjects ]; + int mYInc[ NumObjects ]; + int mBlockSize[ NumObjects ]; +}; + +int DemoMediaPlugin2::init(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + DemoMediaPlugin2 *self = new DemoMediaPlugin2(host_send_func, host_user_data); + *plugin_send_func = staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + + +DemoMediaPlugin2::DemoMediaPlugin2(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) +{ + std::cerr << "DemoMediaPlugin2 constructor" << std::endl; + + mHostSendFunction = host_send_func; + mHostUserData = host_user_data; + mDeleteMe = false; + + mLastUpdateTime = 0; + mFirstTime = true; + mLastUpdateTime = 0; + mWidth = 0; + mHeight = 0; + mDepth = 0; + mPixels = 0; + mBackgroundPixels = 0; + + srand( get_clock_count() ) ; +} + +DemoMediaPlugin2::~DemoMediaPlugin2() +{ + std::cerr << "DemoMediaPlugin2 destructor" << std::endl; +} + +void DemoMediaPlugin2::staticReceiveMessage(const char *message_string, void **user_data) +{ + DemoMediaPlugin2 *self = (DemoMediaPlugin2*)*user_data; + + if(self != NULL) + { + self->receiveMessage(message_string); + + // If the plugin has processed the delete message, delete it. + if(self->mDeleteMe) + { + delete self; + *user_data = NULL; + } + } +} + +void DemoMediaPlugin2::receiveMessage(const char *message_string) +{ +// std::cerr << "DemoMediaPlugin2::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + // Normally a plugin would only specify one of these two subclasses, but this is a demo... + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + sendMessage(message); + + // Plugin gets to decide the texture parameters to use. + mDepth = 3; + + message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_RGB); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", false); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + update(); + } + else if(message_name == "shutdown") + { + sendMessage(LLPluginMessage("base", "shutdown_response")); + + mDeleteMe = true; + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = (void*)message_in.getValueU32("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + + std::cerr << "DemoMediaPlugin2::receiveMessage: shared memory added, name: " << name + << ", size: " << info.mSize + << ", address: " << info.mAddress + << std::endl; + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + std::cerr << "DemoMediaPlugin2::receiveMessage: shared memory remove, name = " << name << std::endl; + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = NULL; + } + mSharedSegments.erase(iter); + } + else + { + std::cerr << "DemoMediaPlugin2::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + std::cerr << "DemoMediaPlugin2::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + std::cerr << "Got size change, new size is " << width << " by " << height << std::endl; + std::cerr << " texture size is " << texture_width << " by " << texture_height << std::endl; + + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + mFirstTime = true; + updatePixels(); + } + } + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); +// std::string modifiers = message.getValue("modifiers"); + +// std::cerr << "DemoMediaPlugin2::receiveMessage: mouse event \"" << event +// << "\", coords " << x << ", " << y +// << std::endl; + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + } + } + else + { + std::cerr << "DemoMediaPlugin2::receiveMessage: unknown media message: " << message_string << std::endl; + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) + { + if(message_name == "focus") + { + // foo = message_in.getValueBoolean("focused"); + } + else if(message_name == "clear_cache") + { + } + else if(message_name == "clear_cookies") + { + } + else if(message_name == "enable_cookies") + { + // foo = message_in.getValueBoolean("enable"); + } + else if(message_name == "proxy_setup") + { + // foo = message_in.getValueBoolean("enable"); + // bar = message_in.getValue("host"); + // baz = message_in.getValueS32("port"); + } + else if(message_name == "browse_stop") + { + } + else if(message_name == "browse_reload") + { + // foo = message_in.getValueBoolean("ignore_cache"); + } + else if(message_name == "browse_forward") + { + } + else if(message_name == "browse_back") + { + } + else if(message_name == "set_status_redirect") + { + // foo = message_in.getValueS32("code"); + // bar = message_in.getValue("url"); + } + else + { + std::cerr << "DemoMediaPlugin2::receiveMessage: unknown media_browser message: " << message_string << std::endl; + } + } + else + { + std::cerr << "DemoMediaPlugin2::receiveMessage: unknown message class: " << message_class << std::endl; + } + + } +} + +void DemoMediaPlugin2::sendMessage(const LLPluginMessage &message) +{ + std::string output = message.generate(); + mHostSendFunction(output.c_str(), &mHostUserData); +} + +void DemoMediaPlugin2::setDirty(int left, int top, int right, int bottom) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueS32("left", left); + message.setValueS32("top", top); + message.setValueS32("right", right); + message.setValueS32("bottom", bottom); + + sendMessage(message); +} + + +extern "C" +{ +#ifdef WIN32 + __declspec(dllexport) +#endif + int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); +} + +int +#ifdef WIN32 + __declspec(dllexport) +#endif + LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return DemoMediaPlugin2::init(host_send_func, host_user_data, plugin_send_func, plugin_user_data); +} + +#ifdef WIN32 +int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* params ) +{ + return 1; +} +#endif diff --git a/linden/indra/test_apps/llplugintest/demo_plugin.cpp b/linden/indra/test_apps/llplugintest/demo_plugin.cpp new file mode 100644 index 000000000..772fa16ad --- /dev/null +++ b/linden/indra/test_apps/llplugintest/demo_plugin.cpp @@ -0,0 +1,220 @@ +/** + * @file demo_plugin.cpp + * @brief Test plugin to be loaded by the llplugin testbed. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#ifdef WIN32 +#include <windows.h> +#endif + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" + +// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint + +class DemoPlugin +{ +public: + + static int init(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); + +private: + DemoPlugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~DemoPlugin(); + + static void staticReceiveMessage(const char *message_string, void **user_data); + void receiveMessage(const char *message_string); + void sendMessage(const LLPluginMessage &message); + + LLPluginInstance::sendMessageFunction mHostSendFunction; + void *mHostUserData; + bool mDeleteMe; + + int mSharedSegmentFillValue; + void *mSharedSegmentBase; + size_t mSharedSegmentSize; +}; + +int DemoPlugin::init(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + DemoPlugin *self = new DemoPlugin(host_send_func, host_user_data); + *plugin_send_func = staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} + +DemoPlugin::DemoPlugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) +{ + std::cerr << "DemoPlugin constructor" << std::endl; + + mHostSendFunction = host_send_func; + mHostUserData = host_user_data; + mDeleteMe = false; + mSharedSegmentBase = NULL; + mSharedSegmentSize = 0; + mSharedSegmentFillValue = 0; +} + +DemoPlugin::~DemoPlugin() +{ + std::cerr << "DemoPlugin destructor" << std::endl; +} + +void DemoPlugin::staticReceiveMessage(const char *message_string, void **user_data) +{ + DemoPlugin *self = (DemoPlugin*)*user_data; + + if(self != NULL) + { + self->receiveMessage(message_string); + + // If the plugin has processed the delete message, delete it. + if(self->mDeleteMe) + { + delete self; + *user_data = NULL; + } + } +} + +void DemoPlugin::receiveMessage(const char *message_string) +{ +// std::cerr << "DemoPlugin::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if(message_class == "base") + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + message.setValueLLSD("versions", versions); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. +// std::cerr << "DemoPlugin::receiveMessage: idle processing" << std::endl; + if(mSharedSegmentBase != NULL) + { + // Fill the shared memory segment + memset(mSharedSegmentBase, mSharedSegmentFillValue, mSharedSegmentSize); + // and increment the fill value + mSharedSegmentFillValue++; + } + } + else if(message_name == "shutdown") + { + sendMessage(LLPluginMessage("base", "shutdown_response")); + + mDeleteMe = true; + } + else if(message_name == "shm_added") + { + // Normally, we would check the name and match it up with something from another message. + // For this test, just fill any segment that comes in. + mSharedSegmentSize = (size_t)message_in.getValueS32("size"); + mSharedSegmentBase = (void*)message_in.getValueU32("address"); + + std::cerr << "DemoPlugin::receiveMessage: shared memory added, name: " << message_in.getValue("name") + << ", size: " << mSharedSegmentSize + << ", address: " << mSharedSegmentBase + << std::endl; + + memset(mSharedSegmentBase, mSharedSegmentFillValue, mSharedSegmentSize); + + } + else if(message_name == "shm_remove") + { + std::cerr << "DemoPlugin::receiveMessage: shared memory remove" << std::endl; + + // Normally, we would check the name and match it up with something from another message. + // For this test, just stop filling the only segment we track. + + mSharedSegmentBase = NULL; + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", message_in.getValue("name")); + sendMessage(message); + } + else + { + std::cerr << "DemoPlugin::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else + { + std::cerr << "DemoPlugin::receiveMessage: unknown message class: " << message_class << std::endl; + } + + } +} + +void DemoPlugin::sendMessage(const LLPluginMessage &message) +{ + std::string output = message.generate(); + mHostSendFunction(output.c_str(), &mHostUserData); +} + + +extern "C" +{ +#ifdef WIN32 + __declspec(dllexport) +#endif + int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); +} + +int +#ifdef WIN32 + __declspec(dllexport) +#endif + LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + return DemoPlugin::init(host_send_func, host_user_data, plugin_send_func, plugin_user_data); +} + +#ifdef WIN32 +int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* params ) +{ + return 1; +} +#endif diff --git a/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp b/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp new file mode 100644 index 000000000..27cb52a50 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -0,0 +1,2179 @@ +/** + * @file LLMediaPluginTest.cpp + * @brief Primary test application for LLMedia (Separate Process) Plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "indra_constants.h" + +#include "llapr.h" +#include "llerrorcontrol.h" + +#include <math.h> +#include <iomanip> +#include <sstream> +#include <ctime> + +#include "llmediaplugintest.h" + +#if __APPLE__ + #include <GLUT/glut.h> + #include <CoreFoundation/CoreFoundation.h> +#else + #define FREEGLUT_STATIC + #include "GL/freeglut.h" + #define GLUI_FREEGLUT +#endif + +#if LL_WINDOWS +#pragma warning(disable: 4263) +#pragma warning(disable: 4264) +#endif +#include "glui.h" + + +LLMediaPluginTest* gApplication = 0; +static void gluiCallbackWrapper( int control_id ); + +//////////////////////////////////////////////////////////////////////////////// +// +static bool isTexture( GLuint texture ) +{ + bool result = false; + + // glIsTexture will sometimes return false for real textures... do this instead. + if(texture != 0) + result = true; + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +mediaPanel::mediaPanel() +{ + mMediaTextureHandle = 0; + mPickTextureHandle = 0; + mMediaSource = NULL; + mPickTexturePixels = NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +// +mediaPanel::~mediaPanel() +{ + // delete OpenGL texture handles + if ( isTexture( mPickTextureHandle ) ) + { + std::cerr << "remMediaPanel: deleting pick texture " << mPickTextureHandle << std::endl; + glDeleteTextures( 1, &mPickTextureHandle ); + mPickTextureHandle = 0; + } + + if ( isTexture( mMediaTextureHandle ) ) + { + std::cerr << "remMediaPanel: deleting media texture " << mMediaTextureHandle << std::endl; + glDeleteTextures( 1, &mMediaTextureHandle ); + mMediaTextureHandle = 0; + } + + if(mPickTexturePixels) + { + delete mPickTexturePixels; + } + + if(mMediaSource) + { + delete mMediaSource; + } + +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int window_height ) : + mVersionMajor( 2 ), + mVersionMinor( 0 ), + mVersionPatch( 0 ), + mMaxPanels( 25 ), + mViewportAspect( 0 ), + mAppWindow( app_window ), + mCurMouseX( 0 ), + mCurMouseY( 0 ), + mFuzzyMedia( true ), + mSelectedPanel( 0 ), + mMediaBrowserControlEnableCookies( 0 ), + mMediaBrowserControlBackButton( 0 ), + mMediaBrowserControlForwardButton( 0 ), + mMediaTimeControlVolume( 100 ), + mMediaTimeControlSeekSeconds( 0 ), + mGluiMediaTimeControlWindowFlag( true ), + mGluiMediaBrowserControlWindowFlag( true ), + mMediaBrowserControlBackButtonFlag( true ), + mMediaBrowserControlForwardButtonFlag( true ), + mHomeWebUrl( "http://www.google.com/" ) +{ + // debugging spam + std::cout << std::endl << " GLUT version: " << "3.7.6" << std::endl; // no way to get real version from GLUT + std::cout << std::endl << " GLUI version: " << GLUI_Master.get_version() << std::endl; + std::cout << std::endl << "Media Plugin Test version: " << mVersionMajor << "." << mVersionMinor << "." << mVersionPatch << std::endl; + + // bookmark title + mBookmarks.push_back( std::pair< std::string, std::string >( "--- Bookmarks ---", "" ) ); + + // insert hardcoded URLs here as required for testing + //mBookmarks.push_back( std::pair< std::string, std::string >( "description", "url" ) ); + + // read bookmarks from file. + // note: uses command in ./CmakeLists.txt which copies bookmmarks file from source directory + // to app directory (WITHOUT build configuration dir) (this is cwd in Windows within MSVC) + // For example, test_apps\llplugintest and not test_apps\llplugintest\Release + // This may need to be changed for Mac/Linux builds. + // See https://jira.lindenlab.com/browse/DEV-31350 for large list of media URLs from AGNI + const std::string bookmarks_filename( "bookmarks.txt" ); + std::ifstream file_handle( bookmarks_filename.c_str() ); + if ( file_handle.is_open() ) + { + std::cout << "Reading bookmarks for test" << std::endl; + while( ! file_handle.eof() ) + { + std::string line; + std::getline( file_handle, line ); + if ( file_handle.eof() ) + break; + + if ( line.substr( 0, 1 ) != "#" ) + { + size_t comma_pos = line.find_first_of( ',' ); + if ( comma_pos != std::string::npos ) + { + std::string description = line.substr( 0, comma_pos ); + std::string url = line.substr( comma_pos + 1 ); + mBookmarks.push_back( std::pair< std::string, std::string >( description, url ) ); + } + else + { + mBookmarks.push_back( std::pair< std::string, std::string >( line, line ) ); + }; + }; + }; + std::cout << "Read " << mBookmarks.size() << " bookmarks" << std::endl; + } + else + { + std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl; + }; + + // initialize linden lab APR module + ll_init_apr(); + + // Set up llerror logging + { + LLError::initForApplication("."); + LLError::setDefaultLevel(LLError::LEVEL_INFO); + //LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG); + } + + // lots of randomness in this app + srand( ( unsigned int )time( 0 ) ); + + // build GUI + makeChrome(); + + // OpenGL initialilzation + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + glClearDepth( 1.0f ); + glEnable( GL_DEPTH_TEST ); + glEnable( GL_COLOR_MATERIAL ); + glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); + glDepthFunc( GL_LEQUAL ); + glEnable( GL_TEXTURE_2D ); + glDisable( GL_BLEND ); + glColor3f( 1.0f, 1.0f, 1.0f ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); + + // start with a sane view + resetView(); + + // initial media panel + const int num_initial_panels = 1; + for( int i = 0; i < num_initial_panels; ++i ) + { + //addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); + addMediaPanel( mHomeWebUrl ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLMediaPluginTest::~LLMediaPluginTest() +{ + // delete all media panels + for( int i = 0; i < (int)mMediaPanels.size(); ++i ) + { + remMediaPanel( mMediaPanels[ i ] ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::reshape( int width, int height ) +{ + // update viewport (the active window inside the chrome) + int viewport_x, viewport_y; + int viewport_height, viewport_width; + GLUI_Master.get_viewport_area( &viewport_x, &viewport_y, &viewport_width, &viewport_height ); + mViewportAspect = (float)( viewport_width ) / (float)( viewport_height ); + glViewport( viewport_x, viewport_y, viewport_width, viewport_height ); + + // save these as we'll need them later + mWindowWidth = width; + mWindowHeight = height; + + // adjust size of URL bar so it doesn't get clipped + mUrlEdit->set_w( mWindowWidth - 360 ); + + // GLUI requires this + if ( glutGetWindow() != mAppWindow ) + glutSetWindow( mAppWindow ); + + // trigger re-display + glutPostRedisplay(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::bindTexture(GLuint texture, GLint row_length, GLint alignment) +{ + glEnable( GL_TEXTURE_2D ); + + glBindTexture( GL_TEXTURE_2D, texture ); + glPixelStorei( GL_UNPACK_ROW_LENGTH, row_length ); + glPixelStorei( GL_UNPACK_ALIGNMENT, alignment ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaPluginTest::checkGLError(const char *name) +{ + bool result = false; + GLenum error = glGetError(); + + if(error != GL_NO_ERROR) + { + // For some reason, glGenTextures is returning GL_INVALID_VALUE... + std::cout << name << " ERROR 0x" << std::hex << error << std::dec << std::endl; + result = true; + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::drawGeometry( int panel ) +{ + // texture coordinates for each panel + GLfloat non_opengl_texture_coords[ 8 ] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; + GLfloat opengl_texture_coords[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; + + GLfloat *texture_coords = mMediaPanels[ panel ]->mAppTextureCoordsOpenGL?opengl_texture_coords:non_opengl_texture_coords; + + // base coordinates for each panel + GLfloat base_vertex_pos[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; + + // calculate posiitons + const int num_panels = (int)mMediaPanels.size(); + const int num_rows = (int)sqrt( (float)num_panels ); + const int num_cols = num_panels / num_rows; + const int panel_x = ( panel / num_rows ); + const int panel_y = ( panel % num_rows ); + + const float spacing = 0.1f; + const GLfloat offset_x = num_cols * ( 1.0 + spacing ) / 2; + const GLfloat offset_y = num_rows * ( 1.0 + spacing ) / 2; + + // Adjust for media aspect ratios + { + float aspect = 1.0f; + + if(mMediaPanels[ panel ]->mMediaHeight != 0) + { + aspect = (float)mMediaPanels[ panel ]->mMediaWidth / (float)mMediaPanels[ panel ]->mMediaHeight; + } + + if(aspect > 1.0f) + { + // media is wider than it is high -- adjust the top and bottom in + for( int corner = 0; corner < 4; ++corner ) + { + float temp = base_vertex_pos[corner * 2 + 1]; + + if(temp < 0.5f) + temp += 0.5 - (0.5f / aspect); + else + temp -= 0.5 - (0.5f / aspect); + + base_vertex_pos[corner * 2 + 1] = temp; + } + } + else if(aspect < 1.0f) + { + // media is higher than it is wide -- adjust the left and right sides in + for( int corner = 0; corner < 4; ++corner ) + { + float temp = base_vertex_pos[corner * 2]; + + if(temp < 0.5f) + temp += 0.5f - (0.5f * aspect); + else + temp -= 0.5f - (0.5f * aspect); + + base_vertex_pos[corner * 2] = temp; + } + } + } + + glBegin( GL_QUADS ); + for( int corner = 0; corner < 4; ++corner ) + { + glTexCoord2f( texture_coords[ corner * 2 ], texture_coords[ corner * 2 + 1 ] ); + GLfloat x = base_vertex_pos[ corner * 2 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f; + GLfloat y = base_vertex_pos[ corner * 2 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f; + + glVertex3f( x, y, 0.0f ); + }; + glEnd(); +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::startPanelHighlight( float red, float green, float blue, float line_width ) +{ + glPushAttrib( GL_ALL_ATTRIB_BITS ); + glEnable( GL_POLYGON_OFFSET_FILL ); + glPolygonOffset( -2.5f, -2.5f ); + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + glLineWidth( line_width ); + glColor3f( red, green, blue ); + glDisable( GL_TEXTURE_2D ); +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::endPanelHighlight() +{ + glPopAttrib(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::draw( int draw_type ) +{ + for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) + { + // drawing pick texture + if ( draw_type == DrawTypePickTexture ) + { + // only bother with pick if we have something to render + // Actually, we need to pick even if we're not ready to render. + // Otherwise you can't select and remove a panel which has gone bad. + //if ( mMediaPanels[ panel ]->mReadyToRender ) + { + glMatrixMode( GL_TEXTURE ); + glPushMatrix(); + + // pick texture is a power of 2 so no need to scale + glLoadIdentity(); + + // bind to media texture + glLoadIdentity(); + bindTexture( mMediaPanels[ panel ]->mPickTextureHandle ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + + // draw geometry using pick texture + drawGeometry( panel ); + + glMatrixMode( GL_TEXTURE ); + glPopMatrix(); + }; + } + else + if ( draw_type == DrawTypeMediaTexture ) + { + bool texture_valid = false; + bool plugin_exited = false; + + if(mMediaPanels[ panel ]->mMediaSource) + { + texture_valid = mMediaPanels[ panel ]->mMediaSource->textureValid(); + plugin_exited = mMediaPanels[ panel ]->mMediaSource->isPluginExited(); + } + + // save texture matrix (changes for each panel) + glMatrixMode( GL_TEXTURE ); + glPushMatrix(); + + // only process texture if the media is ready to draw + // (we still want to draw the geometry) + if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid ) + { + // bind to media texture + bindTexture( mMediaPanels[ panel ]->mMediaTextureHandle ); + + if ( mFuzzyMedia ) + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + } + else + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + } + + // scale to fit panel + glScalef( mMediaPanels[ panel ]->mTextureScaleX, + mMediaPanels[ panel ]->mTextureScaleY, + 1.0f ); + }; + + float intensity = plugin_exited?0.25f:1.0f; + + // highlight the selected panel + if ( mSelectedPanel && ( mMediaPanels[ panel ]->mId == mSelectedPanel->mId ) ) + { + startPanelHighlight( intensity, intensity, 0.0f, 5.0f ); + drawGeometry( panel ); + endPanelHighlight(); + } + else + // this panel not able to render yet since it + // doesn't have enough information + if ( !mMediaPanels[ panel ]->mReadyToRender ) + { + startPanelHighlight( intensity, 0.0f, 0.0f, 2.0f ); + drawGeometry( panel ); + endPanelHighlight(); + } + else + // just display a border around the media + { + startPanelHighlight( 0.0f, intensity, 0.0f, 2.0f ); + drawGeometry( panel ); + endPanelHighlight(); + }; + + if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid ) + { + // draw visual geometry + drawGeometry( panel ); + } + + // restore texture matrix (changes for each panel) + glMatrixMode( GL_TEXTURE ); + glPopMatrix(); + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::display() +{ + // GLUI requires this + if ( glutGetWindow() != mAppWindow ) + glutSetWindow( mAppWindow ); + + // start with a clean slate + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + // set up OpenGL view + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -mViewportAspect * 0.04f, mViewportAspect * 0.04f, -0.04f, 0.04f, 0.1f, 50.0f ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, 0.0f ); + glTranslatef( mViewPos[ 0 ], mViewPos[ 1 ], -mViewPos[ 2 ] ); + glMultMatrixf( mViewRotation ); + + // draw pick texture + draw( DrawTypePickTexture ); + + // read colors and get coordinate values + glReadPixels( mCurMouseX, mCurMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, mPixelReadColor ); + + // clear the pick render (otherwise it may depth-fight with the textures rendered later) + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + // draw visible geometry + draw( DrawTypeMediaTexture ); + + glutSwapBuffers(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::idle() +{ +// checkGLError("LLMediaPluginTest::idle"); + + // GLUI requires this + if ( glutGetWindow() != mAppWindow ) + glutSetWindow( mAppWindow ); + + // random creation/destruction of panels enabled? + const time_t panel_timeout_time = 5; + if ( mRandomPanelCount ) + { + // time for a change + static time_t last_panel_time = 0; + if ( time( NULL ) - last_panel_time > panel_timeout_time ) + { + if ( rand() % 2 == 0 ) + { + if ( mMediaPanels.size() < 16 ) + { + std::cout << "Randomly adding new panel" << std::endl; + addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); + }; + } + else + { + if ( mMediaPanels.size() > 0 ) + { + std::cout << "Deleting selected panel" << std::endl; + remMediaPanel( mSelectedPanel ); + }; + }; + time( &last_panel_time ); + }; + }; + + // random selection of bookmarks enabled? + const time_t bookmark_timeout_time = 5; + if ( mRandomBookmarks ) + { + // time for a change + static time_t last_bookmark_time = 0; + if ( time( NULL ) - last_bookmark_time > bookmark_timeout_time ) + { + // go to a different random bookmark on each panel + for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) + { + std::string uri = mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second; + + std::cout << "Random: navigating to : " << uri << std::endl; + + std::string mime_type = mimeTypeFromUrl( uri ); + + if ( mime_type != mMediaPanels[ panel ]->mMimeType ) + { + replaceMediaPanel( mMediaPanels[ panel ], uri ); + } + else + { + mMediaPanels[ panel ]->mMediaSource->loadURI( uri ); + mMediaPanels[ panel ]->mMediaSource->start(); + }; + }; + + time( &last_bookmark_time ); + }; + }; + + // update UI + if ( mSelectedPanel ) + { + // set volume based on slider if we have time media + //if ( mGluiMediaTimeControlWindowFlag ) + //{ + // mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f ); + //}; + + // NOTE: it is absurd that we need cache the state of GLUI controls + // but enabling/disabling controls drags framerate from 500+ + // down to 15. Not a problem for plugin system - only this test + // enable/disable time based UI controls based on type of plugin + if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) + { + if ( ! mGluiMediaTimeControlWindowFlag ) + { + mGluiMediaTimeControlWindow->enable(); + mGluiMediaTimeControlWindowFlag = true; + }; + } + else + { + if ( mGluiMediaTimeControlWindowFlag ) + { + mGluiMediaTimeControlWindow->disable(); + mGluiMediaTimeControlWindowFlag = false; + }; + }; + + // enable/disable browser based UI controls based on type of plugin + if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() ) + { + if ( ! mGluiMediaBrowserControlWindowFlag ) + { + mGluiMediaBrowserControlWindow->enable(); + mGluiMediaBrowserControlWindowFlag = true; + }; + } + else + { + if ( mGluiMediaBrowserControlWindowFlag ) + { + mGluiMediaBrowserControlWindow->disable(); + mGluiMediaBrowserControlWindowFlag = false; + }; + }; + + // enable/disable browser back button depending on browser history + if ( mSelectedPanel->mMediaSource->getHistoryBackAvailable() ) + { + if ( ! mMediaBrowserControlBackButtonFlag ) + { + mMediaBrowserControlBackButton->enable(); + mMediaBrowserControlBackButtonFlag = true; + }; + } + else + { + if ( mMediaBrowserControlBackButtonFlag ) + { + mMediaBrowserControlBackButton->disable(); + mMediaBrowserControlBackButtonFlag = false; + }; + }; + + // enable/disable browser forward button depending on browser history + if ( mSelectedPanel->mMediaSource->getHistoryForwardAvailable() ) + { + if ( ! mMediaBrowserControlForwardButtonFlag ) + { + mMediaBrowserControlForwardButton->enable(); + mMediaBrowserControlForwardButtonFlag = true; + }; + } + else + { + if ( mMediaBrowserControlForwardButtonFlag ) + { + mMediaBrowserControlForwardButton->disable(); + mMediaBrowserControlForwardButtonFlag = false; + }; + }; + + // NOTE: This is *very* slow and not worth optimising + updateStatusBar(); + }; + + // update all the panels + for( int panel_index = 0; panel_index < (int)mMediaPanels.size(); ++panel_index ) + { + mediaPanel *panel = mMediaPanels[ panel_index ]; + + // call plugins idle function so it can potentially update itself + panel->mMediaSource->idle(); + + // update each media panel + updateMediaPanel( panel ); + + LLRect dirty_rect; + if ( ! panel->mMediaSource->textureValid() ) + { + //std::cout << "texture invalid, skipping update..." << std::endl; + } + else + if ( panel && + ( panel->mMediaWidth != panel->mMediaSource->getWidth() || + panel->mMediaHeight != panel->mMediaSource->getHeight() ) ) + { + //std::cout << "Resize in progress, skipping update..." << std::endl; + } + else + if ( panel->mMediaSource->getDirty( &dirty_rect ) ) + { + const unsigned char* pixels = panel->mMediaSource->getBitsData(); + if ( pixels && isTexture(panel->mMediaTextureHandle)) + { + int x_offset = dirty_rect.mLeft; + int y_offset = dirty_rect.mBottom; + int width = dirty_rect.mRight - dirty_rect.mLeft; + int height = dirty_rect.mTop - dirty_rect.mBottom; + + if((dirty_rect.mRight <= panel->mTextureWidth) && (dirty_rect.mTop <= panel->mTextureHeight)) + { + // Offset the pixels pointer properly + pixels += ( y_offset * panel->mMediaSource->getTextureDepth() * panel->mMediaSource->getBitsWidth() ); + pixels += ( x_offset * panel->mMediaSource->getTextureDepth() ); + + // set up texture + bindTexture( panel->mMediaTextureHandle, panel->mMediaSource->getBitsWidth() ); + if ( mFuzzyMedia ) + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + } + else + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + }; + + checkGLError("glTexParameteri"); + + if(panel->mMediaSource->getTextureFormatSwapBytes()) + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); + checkGLError("glPixelStorei"); + } + + // draw portion that changes into texture + glTexSubImage2D( GL_TEXTURE_2D, 0, + x_offset, + y_offset, + width, + height, + panel->mMediaSource->getTextureFormatPrimary(), + panel->mMediaSource->getTextureFormatType(), + pixels ); + + if(checkGLError("glTexSubImage2D")) + { + std::cerr << " panel ID=" << panel->mId << std::endl; + std::cerr << " texture size = " << panel->mTextureWidth << " x " << panel->mTextureHeight << std::endl; + std::cerr << " media size = " << panel->mMediaWidth << " x " << panel->mMediaHeight << std::endl; + std::cerr << " dirty rect = " << dirty_rect.mLeft << ", " << dirty_rect.mBottom << ", " << dirty_rect.mRight << ", " << dirty_rect.mTop << std::endl; + std::cerr << " texture width = " << panel->mMediaSource->getBitsWidth() << std::endl; + std::cerr << " format primary = 0x" << std::hex << panel->mMediaSource->getTextureFormatPrimary() << std::dec << std::endl; + std::cerr << " format type = 0x" << std::hex << panel->mMediaSource->getTextureFormatType() << std::dec << std::endl; + std::cerr << " pixels = " << (void*)pixels << std::endl; + } + + if(panel->mMediaSource->getTextureFormatSwapBytes()) + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); + checkGLError("glPixelStorei"); + } + + panel->mMediaSource->resetDirty(); + + panel->mReadyToRender = true; + } + else + { + std::cerr << "dirty rect is outside current media size, skipping update" << std::endl; + } + }; + }; + }; + + // GLUI requires this + if ( glutGetWindow() != mAppWindow ) + glutSetWindow( mAppWindow ); + + // trigger re-display + glutPostRedisplay(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::windowPosToTexturePos( int window_x, int window_y, + int& media_x, int& media_y, + int& id ) +{ + if ( ! mSelectedPanel ) + { + media_x = 0; + media_y = 0; + id = 0; + return; + }; + + // record cursor poisiton for a readback next frame + mCurMouseX = window_x; + // OpenGL app == coordinate system this way + // NOTE: unrelated to settings in plugin - this + // is just for this app + mCurMouseY = mWindowHeight - window_y; + + // extract x (0..1023, y (0..1023) and id (0..15) from RGB components + unsigned long pixel_read_color_bits = ( mPixelReadColor[ 0 ] << 16 ) | ( mPixelReadColor[ 1 ] << 8 ) | mPixelReadColor[ 2 ]; + int texture_x = pixel_read_color_bits & 0x3ff; + int texture_y = ( pixel_read_color_bits >> 10 ) & 0x3ff; + id = ( pixel_read_color_bits >> 20 ) & 0x0f; + + // scale to size of media (1024 because we use 10 bits for X and Y from 24) + media_x = (int)( ( (float)mSelectedPanel->mMediaWidth * (float)texture_x ) / 1024.0f ); + media_y = (int)( ( (float)mSelectedPanel->mMediaHeight * (float)texture_y ) / 1024.0f ); + + // we assume the plugin uses an inverted coordinate scheme like OpenGL + // if not, the plugin code inverts the Y coordinate for us - we don't need to + media_y = mSelectedPanel->mMediaHeight - media_y; + + if ( media_x > 0 && media_y > 0 ) + { + //std::cout << " mouse coords: " << mCurMouseX << " x " << mCurMouseY << " and id = " << id << std::endl; + //std::cout << "raw texture coords: " << texture_x << " x " << texture_y << " and id = " << id << std::endl; + //std::cout << " media coords: " << media_x << " x " << media_y << " and id = " << id << std::endl; + //std::cout << std::endl; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::selectPanelById( int id ) +{ + for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) + { + if ( mMediaPanels[ panel ]->mId == id ) + { + selectPanel(mMediaPanels[ panel ]); + return; + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::selectPanel( mediaPanel* panel ) +{ + if( mSelectedPanel == panel ) + return; + + // turn off volume before we delete it + if( mSelectedPanel && mSelectedPanel->mMediaSource ) + { + mSelectedPanel->mMediaSource->setVolume( 0.0f ); + mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_LOW ); + }; + + mSelectedPanel = panel; + + if( mSelectedPanel && mSelectedPanel->mMediaSource ) + { + mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f ); + mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_NORMAL ); + + if(!mSelectedPanel->mStartUrl.empty()) + { + mUrlEdit->set_text(const_cast<char*>(mSelectedPanel->mStartUrl.c_str()) ); + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +mediaPanel* LLMediaPluginTest::findMediaPanel( LLPluginClassMedia* source ) +{ + mediaPanel *result = NULL; + + for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) + { + if ( mMediaPanels[ panel ]->mMediaSource == source ) + { + result = mMediaPanels[ panel ]; + } + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::navigateToNewURI( std::string uri ) +{ + if ( uri.length() ) + { + std::string mime_type = mimeTypeFromUrl( uri ); + + if ( !mSelectedPanel->mMediaSource->isPluginExited() && (mime_type == mSelectedPanel->mMimeType) ) + { + std::cout << "MIME type is the same" << std::endl; + mSelectedPanel->mMediaSource->loadURI( uri ); + mSelectedPanel->mMediaSource->start(); + mBookmarkList->do_selection( 0 ); + } + else + { + std::cout << "MIME type changed or plugin had exited" << std::endl; + replaceMediaPanel( mSelectedPanel, uri ); + mBookmarkList->do_selection( 0 ); + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::initUrlHistory( std::string uris ) +{ + if ( uris.length() > 0 ) + { + std::cout << "init URL : " << uris << std::endl; + LLSD historySD; + + char *cstr, *p; + cstr = new char[uris.size()+1]; + strcpy(cstr, uris.c_str()); + const char *DELIMS = " ,;"; + p = strtok(cstr, DELIMS); + while (p != NULL) { + historySD.insert(0, p); + p = strtok(NULL, DELIMS); + } + mSelectedPanel->mMediaSource->initializeUrlHistory(historySD); + delete[] cstr; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::gluiCallback( int control_id ) +{ + if ( control_id == mIdBookmarks ) + { + std::string uri = mBookmarks[ mSelBookmark ].second; + + navigateToNewURI( uri ); + } + else + if ( control_id == mIdUrlEdit) + { + std::string uri = mUrlEdit->get_text(); + + navigateToNewURI( uri ); + } + else + if ( control_id == mIdUrlInitHistoryEdit ) + { + std::string uri = mUrlInitHistoryEdit->get_text(); + + initUrlHistory( uri ); + } + else + if ( control_id == mIdControlAddPanel ) + { + addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); + } + else + if ( control_id == mIdControlRemPanel ) + { + remMediaPanel( mSelectedPanel ); + } + else + if ( control_id == mIdDisableTimeout ) + { + // Set the "disable timeout" flag for all active plugins. + for( int i = 0; i < (int)mMediaPanels.size(); ++i ) + { + mMediaPanels[ i ]->mMediaSource->setDisableTimeout(mDisableTimeout); + } + } + else + if ( control_id == mIdControlCrashPlugin ) + { + // send message to plugin and ask it to crash + // (switch out for ReleaseCandidate version :) ) + if(mSelectedPanel && mSelectedPanel->mMediaSource) + { + mSelectedPanel->mMediaSource->crashPlugin(); + } + } + else + if ( control_id == mIdControlHangPlugin ) + { + // send message to plugin and ask it to hang + // (switch out for ReleaseCandidate version :) ) + if(mSelectedPanel && mSelectedPanel->mMediaSource) + { + mSelectedPanel->mMediaSource->hangPlugin(); + } + } + else + if ( control_id == mIdControlExitApp ) + { + // text for exiting plugin system cleanly + delete this; // clean up + exit( 0 ); + } + else + if ( control_id == mIdMediaTimeControlPlay ) + { + if ( mSelectedPanel ) + { + mSelectedPanel->mMediaSource->setLoop( false ); + mSelectedPanel->mMediaSource->start(); + }; + } + else + if ( control_id == mIdMediaTimeControlLoop ) + { + if ( mSelectedPanel ) + { + mSelectedPanel->mMediaSource->setLoop( true ); + mSelectedPanel->mMediaSource->start(); + }; + } + else + if ( control_id == mIdMediaTimeControlPause ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->pause(); + } + else + if ( control_id == mIdMediaTimeControlStop ) + { + if ( mSelectedPanel ) + { + mSelectedPanel->mMediaSource->stop(); + }; + } + else + if ( control_id == mIdMediaTimeControlSeek ) + { + if ( mSelectedPanel ) + { + // get value from spinner + float seconds_to_seek = mMediaTimeControlSeekSeconds; + mSelectedPanel->mMediaSource->seek( seconds_to_seek ); + mSelectedPanel->mMediaSource->start(); + }; + } + else + if ( control_id == mIdMediaTimeControlRewind ) + { + if ( mSelectedPanel ) + { + mSelectedPanel->mMediaSource->setLoop( false ); + mSelectedPanel->mMediaSource->start(-2.0f); + }; + } + else + if ( control_id == mIdMediaTimeControlFastForward ) + { + if ( mSelectedPanel ) + { + mSelectedPanel->mMediaSource->setLoop( false ); + mSelectedPanel->mMediaSource->start(2.0f); + }; + } + else + if ( control_id == mIdMediaBrowserControlBack ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->browse_back(); + } + else + if ( control_id == mIdMediaBrowserControlStop ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->browse_stop(); + } + else + if ( control_id == mIdMediaBrowserControlForward ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->browse_forward(); + } + else + if ( control_id == mIdMediaBrowserControlHome ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->loadURI( mHomeWebUrl ); + } + else + if ( control_id == mIdMediaBrowserControlReload ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->browse_reload( true ); + } + else + if ( control_id == mIdMediaBrowserControlClearCache ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->clear_cache(); + } + else + if ( control_id == mIdMediaBrowserControlClearCookies ) + { + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->clear_cookies(); + } + else + if ( control_id == mIdMediaBrowserControlEnableCookies ) + { + if ( mSelectedPanel ) + { + if ( mMediaBrowserControlEnableCookies ) + { + mSelectedPanel->mMediaSource->enable_cookies( true ); + } + else + { + mSelectedPanel->mMediaSource->enable_cookies( false ); + } + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::keyboard( int key ) +{ + //if ( key == 'a' || key == 'A' ) + // addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); + //else + //if ( key == 'r' || key == 'R' ) + // remMediaPanel( mSelectedPanel ); + //else + //if ( key == 'd' || key == 'D' ) + // dumpPanelInfo(); + //else + if ( key == 27 ) + { + std::cout << "Application finished - exiting..." << std::endl; + delete this; + exit( 0 ); + }; + + mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 ); + mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0 ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::mouseButton( int button, int state, int x, int y ) +{ + if ( button == GLUT_LEFT_BUTTON ) + { + if ( state == GLUT_DOWN ) + { + int media_x, media_y, id; + windowPosToTexturePos( x, y, media_x, media_y, id ); + + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_DOWN, 0, media_x, media_y, 0 ); + } + else + if ( state == GLUT_UP ) + { + int media_x, media_y, id; + windowPosToTexturePos( x, y, media_x, media_y, id ); + + // only select a panel if we're on a panel + // (HACK: strictly speaking this rules out clicking on + // the origin of a panel but that's very unlikely) + if ( media_x > 0 && media_y > 0 ) + { + selectPanelById( id ); + + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_UP, 0, media_x, media_y, 0 ); + }; + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::mousePassive( int x, int y ) +{ + int media_x, media_y, id; + windowPosToTexturePos( x, y, media_x, media_y, id ); + + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::mouseMove( int x, int y ) +{ + int media_x, media_y, id; + windowPosToTexturePos( x, y, media_x, media_y, id ); + + if ( mSelectedPanel ) + mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::makeChrome() +{ + // IDs used by GLUI + int start_id = 0x1000; + + // right side window - geometry manipulators +#if __APPLE__ + // the Apple GLUT implementation doesn't seem to set the graphic offset of subwindows correctly when they overlap in certain ways. + // Use a separate controls window in this case. + // GLUI window at right containing manipulation controls and other buttons + int x = glutGet(GLUT_WINDOW_X) + glutGet(GLUT_WINDOW_WIDTH) + 4; + int y = glutGet(GLUT_WINDOW_Y); + GLUI* right_glui_window = GLUI_Master.create_glui( "", 0, x, y ); +#else + GLUI* right_glui_window = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_RIGHT ); +#endif + mViewRotationCtrl = right_glui_window->add_rotation( "Rotation", mViewRotation ); + mViewTranslationCtrl = right_glui_window->add_translation( "Translate", GLUI_TRANSLATION_XY, mViewPos ); + mViewTranslationCtrl->set_speed( 0.01f ); + mViewScaleCtrl = right_glui_window->add_translation( "Scale", GLUI_TRANSLATION_Z, &mViewPos[ 2 ] ); + mViewScaleCtrl->set_speed( 0.05f ); + right_glui_window->set_main_gfx_window( mAppWindow ); + + // right side window - app controls + mIdControlAddPanel = start_id++; + right_glui_window->add_statictext( "" ); + right_glui_window->add_separator(); + right_glui_window->add_statictext( "" ); + right_glui_window->add_button( "Add panel", mIdControlAddPanel, gluiCallbackWrapper ); + right_glui_window->add_statictext( "" ); + mIdControlRemPanel = start_id++; + right_glui_window->add_button( "Rem panel", mIdControlRemPanel, gluiCallbackWrapper ); + right_glui_window->add_statictext( "" ); + right_glui_window->add_separator(); + right_glui_window->add_statictext( "" ); + mIdControlCrashPlugin = start_id++; + right_glui_window->add_button( "Crash plugin", mIdControlCrashPlugin, gluiCallbackWrapper ); + mIdControlHangPlugin = start_id++; + right_glui_window->add_button( "Hang plugin", mIdControlHangPlugin, gluiCallbackWrapper ); + + right_glui_window->add_statictext( "" ); + right_glui_window->add_separator(); + right_glui_window->add_statictext( "" ); + mIdControlExitApp = start_id++; + right_glui_window->add_button( "Exit app", mIdControlExitApp, gluiCallbackWrapper ); + + //// top window - holds bookmark UI + mIdBookmarks = start_id++; + mSelBookmark = 0; + GLUI* glui_window_top = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); + mBookmarkList = glui_window_top->add_listbox( "", &mSelBookmark, mIdBookmarks, gluiCallbackWrapper ); + // only add the first 50 bookmarks - list can be very long sometimes (30,000+) + // when testing list of media URLs from AGNI for example + for( unsigned int each = 0; each < mBookmarks.size() && each < 50; ++each ) + mBookmarkList->add_item( each, const_cast< char* >( mBookmarks[ each ].first.c_str() ) ); + glui_window_top->set_main_gfx_window( mAppWindow ); + + glui_window_top->add_column( false ); + mIdUrlEdit = start_id++; + mUrlEdit = glui_window_top->add_edittext( "Url:", GLUI_EDITTEXT_TEXT, 0, mIdUrlEdit, gluiCallbackWrapper ); + mUrlEdit->set_w( 600 ); + GLUI* glui_window_top2 = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); + mIdUrlInitHistoryEdit = start_id++; + mUrlInitHistoryEdit = glui_window_top2->add_edittext( "Init History (separate by commas or semicolons):", + GLUI_EDITTEXT_TEXT, 0, mIdUrlInitHistoryEdit, gluiCallbackWrapper ); + mUrlInitHistoryEdit->set_w( 800 ); + + // top window - media controls for "time" media types (e.g. movies) + mGluiMediaTimeControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); + mGluiMediaTimeControlWindow->set_main_gfx_window( mAppWindow ); + mIdMediaTimeControlPlay = start_id++; + mGluiMediaTimeControlWindow->add_button( "PLAY", mIdMediaTimeControlPlay, gluiCallbackWrapper ); + mGluiMediaTimeControlWindow->add_column( false ); + mIdMediaTimeControlLoop = start_id++; + mGluiMediaTimeControlWindow->add_button( "LOOP", mIdMediaTimeControlLoop, gluiCallbackWrapper ); + mGluiMediaTimeControlWindow->add_column( false ); + mIdMediaTimeControlPause = start_id++; + mGluiMediaTimeControlWindow->add_button( "PAUSE", mIdMediaTimeControlPause, gluiCallbackWrapper ); + mGluiMediaTimeControlWindow->add_column( false ); + + GLUI_Button *button; + mIdMediaTimeControlRewind = start_id++; + button = mGluiMediaTimeControlWindow->add_button( "<<", mIdMediaTimeControlRewind, gluiCallbackWrapper ); + button->set_w(30); + mGluiMediaTimeControlWindow->add_column( false ); + mIdMediaTimeControlFastForward = start_id++; + button = mGluiMediaTimeControlWindow->add_button( ">>", mIdMediaTimeControlFastForward, gluiCallbackWrapper ); + button->set_w(30); + + mGluiMediaTimeControlWindow->add_column( true ); + + mIdMediaTimeControlStop = start_id++; + mGluiMediaTimeControlWindow->add_button( "STOP", mIdMediaTimeControlStop, gluiCallbackWrapper ); + mGluiMediaTimeControlWindow->add_column( false ); + mIdMediaTimeControlVolume = start_id++; + GLUI_Spinner* spinner = mGluiMediaTimeControlWindow->add_spinner( "Volume", 2, &mMediaTimeControlVolume, mIdMediaTimeControlVolume, gluiCallbackWrapper); + spinner->set_float_limits( 0, 100 ); + mGluiMediaTimeControlWindow->add_column( true ); + mIdMediaTimeControlSeekSeconds = start_id++; + spinner = mGluiMediaTimeControlWindow->add_spinner( "", 2, &mMediaTimeControlSeekSeconds, mIdMediaTimeControlSeekSeconds, gluiCallbackWrapper); + spinner->set_float_limits( 0, 200 ); + spinner->set_w( 32 ); + spinner->set_speed( 0.025f ); + mGluiMediaTimeControlWindow->add_column( false ); + mIdMediaTimeControlSeek = start_id++; + mGluiMediaTimeControlWindow->add_button( "SEEK", mIdMediaTimeControlSeek, gluiCallbackWrapper ); + mGluiMediaTimeControlWindow->add_column( false ); + + + // top window - media controls for "browser" media types (e.g. web browser) + mGluiMediaBrowserControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); + mGluiMediaBrowserControlWindow->set_main_gfx_window( mAppWindow ); + mIdMediaBrowserControlBack = start_id++; + mMediaBrowserControlBackButton = mGluiMediaBrowserControlWindow->add_button( "BACK", mIdMediaBrowserControlBack, gluiCallbackWrapper ); + mGluiMediaBrowserControlWindow->add_column( false ); + mIdMediaBrowserControlStop = start_id++; + mGluiMediaBrowserControlWindow->add_button( "STOP", mIdMediaBrowserControlStop, gluiCallbackWrapper ); + mGluiMediaBrowserControlWindow->add_column( false ); + mIdMediaBrowserControlForward = start_id++; + mMediaBrowserControlForwardButton = mGluiMediaBrowserControlWindow->add_button( "FORWARD", mIdMediaBrowserControlForward, gluiCallbackWrapper ); + mGluiMediaBrowserControlWindow->add_column( false ); + mIdMediaBrowserControlHome = start_id++; + mGluiMediaBrowserControlWindow->add_button( "HOME", mIdMediaBrowserControlHome, gluiCallbackWrapper ); + mGluiMediaBrowserControlWindow->add_column( false ); + mIdMediaBrowserControlReload = start_id++; + mGluiMediaBrowserControlWindow->add_button( "RELOAD", mIdMediaBrowserControlReload, gluiCallbackWrapper ); + mGluiMediaBrowserControlWindow->add_column( false ); + mIdMediaBrowserControlClearCache = start_id++; + mGluiMediaBrowserControlWindow->add_button( "CLEAR CACHE", mIdMediaBrowserControlClearCache, gluiCallbackWrapper ); + mGluiMediaBrowserControlWindow->add_column( false ); + mIdMediaBrowserControlClearCookies = start_id++; + mGluiMediaBrowserControlWindow->add_button( "CLEAR COOKIES", mIdMediaBrowserControlClearCookies, gluiCallbackWrapper ); + mGluiMediaBrowserControlWindow->add_column( false ); + mIdMediaBrowserControlEnableCookies = start_id++; + mMediaBrowserControlEnableCookies = 0; + mGluiMediaBrowserControlWindow->add_checkbox( "Enable Cookies", &mMediaBrowserControlEnableCookies, mIdMediaBrowserControlEnableCookies, gluiCallbackWrapper ); + + // top window - misc controls + GLUI* glui_window_misc_control = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); + mIdRandomPanelCount = start_id++; + mRandomPanelCount = 0; + glui_window_misc_control->add_checkbox( "Randomize panel count", &mRandomPanelCount, mIdRandomPanelCount, gluiCallbackWrapper ); + glui_window_misc_control->set_main_gfx_window( mAppWindow ); + glui_window_misc_control->add_column( true ); + mIdRandomBookmarks = start_id++; + mRandomBookmarks = 0; + glui_window_misc_control->add_checkbox( "Randomize bookmarks", &mRandomBookmarks, mIdRandomBookmarks, gluiCallbackWrapper ); + glui_window_misc_control->set_main_gfx_window( mAppWindow ); + glui_window_misc_control->add_column( true ); + + mIdDisableTimeout = start_id++; + mDisableTimeout = 0; + glui_window_misc_control->add_checkbox( "Disable plugin timeout", &mDisableTimeout, mIdDisableTimeout, gluiCallbackWrapper ); + glui_window_misc_control->set_main_gfx_window( mAppWindow ); + + // bottom window - status + mBottomGLUIWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_BOTTOM ); + mStatusText = mBottomGLUIWindow->add_statictext( "" ); + mBottomGLUIWindow->set_main_gfx_window( mAppWindow ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::resetView() +{ + mViewRotationCtrl->reset(); + + mViewScaleCtrl->set_x( 0.0f ); + mViewScaleCtrl->set_y( 0.0f ); + mViewScaleCtrl->set_z( 3.0f ); + + mViewTranslationCtrl->set_x( 0.0f ); + mViewTranslationCtrl->set_y( 0.0f ); + mViewTranslationCtrl->set_z( 0.0f ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels ) +{ + int pick_texture_width = 1024; + int pick_texture_height = 1024; + int pick_texture_depth = 3; + unsigned char* ptr = new unsigned char[ pick_texture_width * pick_texture_height * pick_texture_depth ]; + for( int y = 0; y < pick_texture_height; ++y ) + { + for( int x = 0; x < pick_texture_width * pick_texture_depth ; x += pick_texture_depth ) + { + unsigned long bits = 0L; + bits |= ( id << 20 ) | ( y << 10 ) | ( x / 3 ); + unsigned char r_component = ( bits >> 16 ) & 0xff; + unsigned char g_component = ( bits >> 8 ) & 0xff; + unsigned char b_component = bits & 0xff; + + ptr[ y * pick_texture_width * pick_texture_depth + x + 0 ] = r_component; + ptr[ y * pick_texture_width * pick_texture_depth + x + 1 ] = g_component; + ptr[ y * pick_texture_width * pick_texture_depth + x + 2 ] = b_component; + }; + }; + + glGenTextures( 1, texture_handle ); + + checkGLError("glGenTextures"); + std::cout << "glGenTextures returned " << *texture_handle << std::endl; + + bindTexture( *texture_handle ); + glTexImage2D( GL_TEXTURE_2D, 0, + GL_RGB, + pick_texture_width, pick_texture_height, + 0, GL_RGB, GL_UNSIGNED_BYTE, ptr ); + + *texture_pixels = ptr; +} + +//////////////////////////////////////////////////////////////////////////////// +// +std::string LLMediaPluginTest::mimeTypeFromUrl( std::string& url ) +{ + // default to web + std::string mime_type = "text/html"; + + // we may need a more advanced MIME type accessor later :-) + if ( url.find( ".mov" ) != std::string::npos ) // Movies + mime_type = "video/quicktime"; + else + if ( url.find( ".txt" ) != std::string::npos ) // Apple Text descriptors + mime_type = "video/quicktime"; + else + if ( url.find( ".mp3" ) != std::string::npos ) // Apple Text descriptors + mime_type = "video/quicktime"; + else + if ( url.find( "example://" ) != std::string::npos ) // Example plugin + mime_type = "example/example"; + + return mime_type; +} + +//////////////////////////////////////////////////////////////////////////////// +// +std::string LLMediaPluginTest::pluginNameFromMimeType( std::string& mime_type ) +{ +#if LL_DARWIN + std::string plugin_name( "media_plugin_null.dylib" ); + if ( mime_type == "video/quicktime" ) + plugin_name = "media_plugin_quicktime.dylib"; + else + if ( mime_type == "text/html" ) + plugin_name = "media_plugin_webkit.dylib"; + +#elif LL_WINDOWS + std::string plugin_name( "media_plugin_null.dll" ); + + if ( mime_type == "video/quicktime" ) + plugin_name = "media_plugin_quicktime.dll"; + else + if ( mime_type == "text/html" ) + plugin_name = "media_plugin_webkit.dll"; + else + if ( mime_type == "example/example" ) + plugin_name = "media_plugin_example.dll"; + +#elif LL_LINUX + std::string plugin_name( "libmedia_plugin_null.so" ); + + if ( mime_type == "video/quicktime" ) + plugin_name = "libmedia_plugin_quicktime.so"; + else + if ( mime_type == "text/html" ) + plugin_name = "libmedia_plugin_webkit.so"; +#endif + return plugin_name; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::addMediaPanel( std::string url ) +{ + // Get the plugin filename using the URL + std::string mime_type = mimeTypeFromUrl( url ); + std::string plugin_name = pluginNameFromMimeType( mime_type ); + + // create a random size for the new media + int media_width; + int media_height; + getRandomMediaSize( media_width, media_height, mime_type ); + + // make a new plugin + LLPluginClassMedia* media_source = new LLPluginClassMedia(this); + + // tell the plugin what size we asked for + media_source->setSize( media_width, media_height ); + + // Use the launcher start and initialize the plugin +#if LL_DARWIN || LL_LINUX + std::string launcher_name( "SLPlugin" ); +#elif LL_WINDOWS + std::string launcher_name( "SLPlugin.exe" ); +#endif + media_source->init( launcher_name, plugin_name ); + media_source->setDisableTimeout(mDisableTimeout); + + // make a new panel and save parameters + mediaPanel* panel = new mediaPanel; + panel->mMediaSource = media_source; + panel->mStartUrl = url; + panel->mMimeType = mime_type; + panel->mMediaWidth = media_width; + panel->mMediaHeight = media_height; + panel->mTextureWidth = 0; + panel->mTextureHeight = 0; + panel->mTextureScaleX = 0; + panel->mTextureScaleY = 0; + panel->mMediaTextureHandle = 0; + panel->mPickTextureHandle = 0; + panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too + panel->mReadyToRender = false; + + // look through current media panels to find an unused index number + bool id_exists = true; + for( int nid = 0; nid < mMaxPanels; ++nid ) + { + // does this id exist already? + id_exists = false; + for( int pid = 0; pid < (int)mMediaPanels.size(); ++pid ) + { + if ( nid == mMediaPanels[ pid ]->mId ) + { + id_exists = true; + break; + }; + }; + + // id wasn't found so we can use it + if ( ! id_exists ) + { + panel->mId = nid; + break; + }; + }; + + // if we get here and this flag is set, there is no room for any more panels + if ( id_exists ) + { + std::cout << "No room for any more panels" << std::endl; + } + else + { + // now we have the ID we can use it to make the + // pick texture (id is baked into texture pixels) + makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels ); + + // save this in the list of panels + mMediaPanels.push_back( panel ); + + // select the panel that was just created + selectPanel( panel ); + + // load and start the URL + panel->mMediaSource->loadURI( url ); + panel->mMediaSource->start(); + + std::cout << "Adding new media panel for " << url << "(" << media_width << "x" << media_height << ") with index " << panel->mId << " - total panels = " << mMediaPanels.size() << std::endl; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::updateMediaPanel( mediaPanel* panel ) +{ +// checkGLError("LLMediaPluginTest::updateMediaPanel"); + + if ( ! panel ) + return; + + if(!panel->mMediaSource || !panel->mMediaSource->textureValid()) + { + panel->mReadyToRender = false; + return; + } + + // take a reference copy of the plugin values since they + // might change during this lifetime of this function + int plugin_media_width = panel->mMediaSource->getWidth(); + int plugin_media_height = panel->mMediaSource->getHeight(); + int plugin_texture_width = panel->mMediaSource->getBitsWidth(); + int plugin_texture_height = panel->mMediaSource->getBitsHeight(); + + // If the texture isn't created or the media or texture dimensions changed AND + // the sizes are valid then we need to delete the old media texture (if necessary) + // then make a new one. + if ((panel->mMediaTextureHandle == 0 || + panel->mMediaWidth != plugin_media_width || + panel->mMediaHeight != plugin_media_height || + panel->mTextureWidth != plugin_texture_width || + panel->mTextureHeight != plugin_texture_height) && + ( plugin_media_width > 0 && plugin_media_height > 0 && + plugin_texture_width > 0 && plugin_texture_height > 0 ) ) + { + std::cout << "Valid media size (" << plugin_media_width << " x " << plugin_media_height + << ") and texture size (" << plugin_texture_width << " x " << plugin_texture_height + << ") for panel with ID=" << panel->mId << " - making texture" << std::endl; + + // delete old GL texture + if ( isTexture( panel->mMediaTextureHandle ) ) + { + std::cerr << "updateMediaPanel: deleting texture " << panel->mMediaTextureHandle << std::endl; + glDeleteTextures( 1, &panel->mMediaTextureHandle ); + panel->mMediaTextureHandle = 0; + } + + std::cerr << "before: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl; + + // make a GL texture based on the dimensions the plugin told us + GLuint new_texture = 0; + glGenTextures( 1, &new_texture ); + + checkGLError("glGenTextures"); + + std::cout << "glGenTextures returned " << new_texture << std::endl; + + panel->mMediaTextureHandle = new_texture; + + bindTexture( panel->mMediaTextureHandle ); + + std::cout << "Setting texture size to " << plugin_texture_width << " x " << plugin_texture_height << std::endl; + glTexImage2D( GL_TEXTURE_2D, 0, + GL_RGB, + plugin_texture_width, plugin_texture_height, + 0, GL_RGB, GL_UNSIGNED_BYTE, + 0 ); + + + std::cerr << "after: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl; + }; + + // update our record of the media and texture dimensions + // NOTE: do this after we we check for sizes changes + panel->mMediaWidth = plugin_media_width; + panel->mMediaHeight = plugin_media_height; + panel->mTextureWidth = plugin_texture_width; + panel->mTextureHeight = plugin_texture_height; + if ( plugin_texture_width > 0 ) + { + panel->mTextureScaleX = (double)panel->mMediaWidth / (double)panel->mTextureWidth; + }; + if ( plugin_texture_height > 0 ) + { + panel->mTextureScaleY = (double)panel->mMediaHeight / (double)panel->mTextureHeight; + }; + + // update the flag which tells us if the media source uses OprnGL coords or not. + panel->mAppTextureCoordsOpenGL = panel->mMediaSource->getTextureCoordsOpenGL(); + + // Check to see if we have enough to render this panel. + // If we do, set a flag that the display functions use so + // they only render a panel with media if it's ready. + if ( panel->mMediaWidth < 0 || + panel->mMediaHeight < 0 || + panel->mTextureWidth < 1 || + panel->mTextureHeight < 1 || + panel->mMediaTextureHandle == 0 ) + { + panel->mReadyToRender = false; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::replaceMediaPanel( mediaPanel* panel, std::string url ) +{ + // no media panels so we can't change anything - have to add + if ( mMediaPanels.size() == 0 ) + return; + + // sanity check + if ( ! panel ) + return; + + int index; + for(index = 0; index < (int)mMediaPanels.size(); index++) + { + if(mMediaPanels[index] == panel) + break; + } + + if(index >= (int)mMediaPanels.size()) + { + // panel isn't in mMediaPanels + return; + } + + std::cout << "Replacing media panel with index " << panel->mId << std::endl; + + int panel_id = panel->mId; + + if(mSelectedPanel == panel) + mSelectedPanel = NULL; + + delete panel; + + // Get the plugin filename using the URL + std::string mime_type = mimeTypeFromUrl( url ); + std::string plugin_name = pluginNameFromMimeType( mime_type ); + + // create a random size for the new media + int media_width; + int media_height; + getRandomMediaSize( media_width, media_height, mime_type ); + + // make a new plugin + LLPluginClassMedia* media_source = new LLPluginClassMedia(this); + + // tell the plugin what size we asked for + media_source->setSize( media_width, media_height ); + + // Use the launcher start and initialize the plugin +#if LL_DARWIN || LL_LINUX + std::string launcher_name( "SLPlugin" ); +#elif LL_WINDOWS + std::string launcher_name( "SLPlugin.exe" ); +#endif + media_source->init( launcher_name, plugin_name ); + media_source->setDisableTimeout(mDisableTimeout); + + // make a new panel and save parameters + panel = new mediaPanel; + panel->mMediaSource = media_source; + panel->mStartUrl = url; + panel->mMimeType = mime_type; + panel->mMediaWidth = media_width; + panel->mMediaHeight = media_height; + panel->mTextureWidth = 0; + panel->mTextureHeight = 0; + panel->mTextureScaleX = 0; + panel->mTextureScaleY = 0; + panel->mMediaTextureHandle = 0; + panel->mPickTextureHandle = 0; + panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too + panel->mReadyToRender = false; + + panel->mId = panel_id; + + // Replace the entry in the panels array + mMediaPanels[index] = panel; + + // now we have the ID we can use it to make the + // pick texture (id is baked into texture pixels) + makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels ); + + // select the panel that was just created + selectPanel( panel ); + + // load and start the URL + panel->mMediaSource->loadURI( url ); + panel->mMediaSource->start(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::getRandomMediaSize( int& width, int& height, std::string mime_type ) +{ + // Make a new media source with a random size which we'll either + // directly or the media plugin will tell us what it wants later. + // Use a random size so we can test support for weird media sizes. + // (Almost everything else will get filled in later once the + // plugin responds) + // NB. Do we need to enforce that width is on 4 pixel boundary? + width = ( ( rand() % 170 ) + 30 ) * 4; + height = ( ( rand() % 170 ) + 30 ) * 4; + + // adjust this random size if it's a browser so we get + // a more useful size for testing.. + if ( mime_type == "text/html" || mime_type == "example/example" ) + { + width = ( ( rand() % 100 ) + 100 ) * 4; + height = ( width * ( ( rand() % 400 ) + 1000 ) ) / 1000; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::remMediaPanel( mediaPanel* panel ) +{ + // always leave one panel + if ( mMediaPanels.size() == 1 ) + return; + + // sanity check - don't think this can happen but see above for a case where it might... + if ( ! panel ) + return; + + std::cout << "Removing media panel with index " << panel->mId << " - total panels = " << mMediaPanels.size() - 1 << std::endl; + + if(mSelectedPanel == panel) + mSelectedPanel = NULL; + + delete panel; + + // remove from storage list + for( int i = 0; i < (int)mMediaPanels.size(); ++i ) + { + if ( mMediaPanels[ i ] == panel ) + { + mMediaPanels.erase( mMediaPanels.begin() + i ); + break; + }; + }; + + // select the first panel + selectPanel( mMediaPanels[ 0 ] ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::updateStatusBar() +{ + if ( ! mSelectedPanel ) + return; + + // cache results - this is a very slow function + static int cached_id = -1; + static int cached_media_width = -1; + static int cached_media_height = -1; + static int cached_texture_width = -1; + static int cached_texture_height = -1; + static bool cached_supports_browser_media = true; + static bool cached_supports_time_media = false; + static int cached_movie_time = -1; + + static std::string cached_plugin_version = ""; + if ( + cached_id == mSelectedPanel->mId && + cached_media_width == mSelectedPanel->mMediaWidth && + cached_media_height == mSelectedPanel->mMediaHeight && + cached_texture_width == mSelectedPanel->mTextureWidth && + cached_texture_height == mSelectedPanel->mTextureHeight && + cached_supports_browser_media == mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() && + cached_supports_time_media == mSelectedPanel->mMediaSource->pluginSupportsMediaTime() && + cached_plugin_version == mSelectedPanel->mMediaSource->getPluginVersion() && + cached_movie_time == (int)mSelectedPanel->mMediaSource->getCurrentTime() + ) + { + // nothing changed so don't spend time in this shitty function + return; + }; + + std::ostringstream stream( "" ); + + stream.str( "" ); + stream.clear(); + + stream << "Id: "; + stream << std::setw( 2 ) << std::setfill( '0' ); + stream << mSelectedPanel->mId; + stream << " | "; + stream << "Media: "; + stream << std::setw( 3 ) << std::setfill( '0' ); + stream << mSelectedPanel->mMediaWidth; + stream << " x "; + stream << std::setw( 3 ) << std::setfill( '0' ); + stream << mSelectedPanel->mMediaHeight; + stream << " | "; + stream << "Texture: "; + stream << std::setw( 4 ) << std::setfill( '0' ); + stream << mSelectedPanel->mTextureWidth; + stream << " x "; + stream << std::setw( 4 ) << std::setfill( '0' ); + stream << mSelectedPanel->mTextureHeight; + stream << " | "; + if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() ) + stream << "BROWSER"; + else + if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) + stream << "TIME "; + stream << " | "; + stream << mSelectedPanel->mMediaSource->getPluginVersion(); + stream << " | "; + if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) + { + stream << std::setw( 3 ) << std::setfill( '0' ); + stream << (int)mSelectedPanel->mMediaSource->getCurrentTime(); + stream << " / "; + stream << std::setw( 3 ) << std::setfill( '0' ); + stream << (int)mSelectedPanel->mMediaSource->getDuration(); + stream << " @ "; + stream << (int)mSelectedPanel->mMediaSource->getCurrentPlayRate(); + stream << " | "; + }; + + glutSetWindow( mBottomGLUIWindow->get_glut_window_id() ); + mStatusText->set_text( const_cast< char*>( stream.str().c_str() ) ); + glutSetWindow( mAppWindow ); + + // caching + cached_id = mSelectedPanel->mId; + cached_media_width = mSelectedPanel->mMediaWidth; + cached_media_height = mSelectedPanel->mMediaHeight; + cached_texture_width = mSelectedPanel->mTextureWidth; + cached_texture_height = mSelectedPanel->mTextureHeight; + cached_supports_browser_media = mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser(); + cached_supports_time_media = mSelectedPanel->mMediaSource->pluginSupportsMediaTime(); + cached_plugin_version = mSelectedPanel->mMediaSource->getPluginVersion(); + cached_movie_time = (int)mSelectedPanel->mMediaSource->getCurrentTime(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::dumpPanelInfo() +{ + std::cout << std::endl << "===== Media Panels =====" << std::endl; + for( int i = 0; i < (int)mMediaPanels.size(); ++i ) + { + std::cout << std::setw( 2 ) << std::setfill( '0' ); + std::cout << i + 1 << "> "; + std::cout << "Id: "; + std::cout << std::setw( 2 ) << std::setfill( '0' ); + std::cout << mMediaPanels[ i ]->mId; + std::cout << " | "; + std::cout << "Media: "; + std::cout << std::setw( 3 ) << std::setfill( '0' ); + std::cout << mMediaPanels[ i ]->mMediaWidth; + std::cout << " x "; + std::cout << std::setw( 3 ) << std::setfill( '0' ); + std::cout << mMediaPanels[ i ]->mMediaHeight; + std::cout << " | "; + std::cout << "Texture: "; + std::cout << std::setw( 4 ) << std::setfill( '0' ); + std::cout << mMediaPanels[ i ]->mTextureWidth; + std::cout << " x "; + std::cout << std::setw( 4 ) << std::setfill( '0' ); + std::cout << mMediaPanels[ i ]->mTextureHeight; + std::cout << " | "; + if ( mMediaPanels[ i ] == mSelectedPanel ) + std::cout << "(selected)"; + + std::cout << std::endl; + }; + std::cout << "========================" << std::endl; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + // Uncomment this to make things much, much quieter. +// return; + + switch(event) + { + case MEDIA_EVENT_CONTENT_UPDATED: + // too spammy -- don't log these +// std::cerr << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << std::endl; + break; + + case MEDIA_EVENT_TIME_DURATION_UPDATED: + // too spammy -- don't log these +// std::cerr << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << std::endl; + break; + + case MEDIA_EVENT_SIZE_CHANGED: + std::cerr << "Media event: MEDIA_EVENT_SIZE_CHANGED " << std::endl; + break; + + case MEDIA_EVENT_CURSOR_CHANGED: + std::cerr << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << std::endl; + break; + + case MEDIA_EVENT_NAVIGATE_BEGIN: + std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << std::endl; + break; + + case MEDIA_EVENT_NAVIGATE_COMPLETE: + std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << std::endl; + break; + + case MEDIA_EVENT_PROGRESS_UPDATED: + std::cerr << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << std::endl; + break; + + case MEDIA_EVENT_STATUS_TEXT_CHANGED: + std::cerr << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << std::endl; + break; + + case MEDIA_EVENT_NAME_CHANGED: + std::cerr << "Media event: MEDIA_EVENT_NAME_CHANGED, new name is: " << self->getMediaName() << std::endl; + glutSetWindowTitle( self->getMediaName().c_str() ); + break; + + case MEDIA_EVENT_LOCATION_CHANGED: + { + std::cerr << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << std::endl; + mediaPanel* panel = findMediaPanel(self); + if(panel != NULL) + { + panel->mStartUrl = self->getLocation(); + if(panel == mSelectedPanel) + { + mUrlEdit->set_text(const_cast<char*>(panel->mStartUrl.c_str()) ); + } + } + } + break; + + case MEDIA_EVENT_CLICK_LINK_HREF: + std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << std::endl; + break; + + case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: + std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << std::endl; + break; + + case MEDIA_EVENT_PLUGIN_FAILED: + std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << std::endl; + break; + + case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: + std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl; + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +static void gluiCallbackWrapper( int control_id ) +{ + if ( gApplication ) + gApplication->gluiCallback( control_id ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void glutReshape( int width, int height ) +{ + if ( gApplication ) + gApplication->reshape( width, height ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutDisplay() +{ + if ( gApplication ) + gApplication->display(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutIdle(int update_ms) +{ + GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms); + + if ( gApplication ) + gApplication->idle(); + +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutKeyboard( unsigned char key, int x, int y ) +{ + if ( gApplication ) + gApplication->keyboard( key ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMousePassive( int x, int y ) +{ + if ( gApplication ) + gApplication->mousePassive( x, y ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseMove( int x , int y ) +{ + if ( gApplication ) + gApplication->mouseMove( x, y ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseButton( int button, int state, int x, int y ) +{ + if ( gApplication ) + gApplication->mouseButton( button, state, x, y ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +int main( int argc, char* argv[] ) +{ +#if LL_DARWIN + // Set the current working directory to <application bundle>/Contents/Resources/ + CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); + if(resources_url != NULL) + { + CFStringRef resources_string = CFURLCopyFileSystemPath(resources_url, kCFURLPOSIXPathStyle); + CFRelease(resources_url); + if(resources_string != NULL) + { + char buffer[PATH_MAX] = ""; + if(CFStringGetCString(resources_string, buffer, sizeof(buffer), kCFStringEncodingUTF8)) + { + chdir(buffer); + } + CFRelease(resources_string); + } + } +#endif + + glutInit( &argc, argv ); + glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); + + const int app_window_x = 80; + const int app_window_y = 0; + const int app_window_width = 960; + const int app_window_height = 960; + + glutInitWindowPosition( app_window_x, app_window_y ); + glutInitWindowSize( app_window_width, app_window_height ); + + int app_window_handle = glutCreateWindow( "LLMediaPluginTest" ); + + glutDisplayFunc( glutDisplay ); + + GLUI_Master.set_glutReshapeFunc( glutReshape ); + GLUI_Master.set_glutKeyboardFunc( glutKeyboard ); + GLUI_Master.set_glutMouseFunc( glutMouseButton ); + + glutPassiveMotionFunc( glutMousePassive ); + glutMotionFunc( glutMouseMove ); + + glutSetWindow( app_window_handle ); + + gApplication = new LLMediaPluginTest( app_window_handle, app_window_width, app_window_height ); + + // update at approximately 60hz + int update_ms = 1000 / 60; + + GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms); + + glutMainLoop(); + + delete gApplication; +} diff --git a/linden/indra/test_apps/llplugintest/llmediaplugintest.h b/linden/indra/test_apps/llplugintest/llmediaplugintest.h new file mode 100644 index 000000000..c2b2baba9 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/llmediaplugintest.h @@ -0,0 +1,201 @@ +/** + * @file LLMediaPluginTest.cpp + * @brief Primary test application for LLMedia (Separate Process) Plugin system + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_MEDIA_PLUGIN_TEST_H +#define LL_MEDIA_PLUGIN_TEST_H + +#include <vector> +#include <string> +#include "llpluginclassmedia.h" +#include "llgl.h" + +// Forward declarations +class GLUI_Rotation; +class GLUI_Translation; +class GLUI_Listbox; +class GLUI_EditText; +class GLUI_StaticText; +class GLUI; +class GLUI_Button; + +//////////////////////////////////////////////////////////////////////////////// +// +struct mediaPanel +{ + public: + mediaPanel(); + ~mediaPanel(); + int mId; + std::string mStartUrl; + std::string mMimeType; + LLPluginClassMedia *mMediaSource; + int mMediaWidth; + int mMediaHeight; + int mTextureWidth; + int mTextureHeight; + double mTextureScaleX; + double mTextureScaleY; + GLuint mMediaTextureHandle; + GLuint mPickTextureHandle; + unsigned char* mPickTexturePixels; + bool mAppTextureCoordsOpenGL; + bool mReadyToRender; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +class LLMediaPluginTest : public LLPluginClassMediaOwner +{ + public: + LLMediaPluginTest( int app_window, int window_width, int window_height ); + ~LLMediaPluginTest(); + + void reshape( int width, int height ); + void display(); + void idle(); + void gluiCallback( int control_id ); + void keyboard( int key ); + void mousePassive( int x, int y ); + void mouseButton( int button, int state, int x, int y ); + void mouseMove( int x, int y ); + + void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1); + bool checkGLError(const char *name = "OpenGL"); + void drawGeometry( int panel ); + void startPanelHighlight( float red, float green, float blue, float line_width ); + void endPanelHighlight(); + enum { DrawTypePickTexture, DrawTypeMediaTexture }; + void draw( int draw_type ); + void windowPosToTexturePos( int window_x, int window_y, int& media_x, int& media_y, int& id ); + + void addMediaPanel( std::string url ); + void updateMediaPanel( mediaPanel* panel ); + void remMediaPanel( mediaPanel* panel ); + void replaceMediaPanel( mediaPanel* panel, std::string url ); + void getRandomMediaSize( int& width, int& height, std::string mime_type ); + void navigateToNewURI( std::string uri ); + void initUrlHistory( std::string uri ); + void selectPanelById( int id ); + void selectPanel( mediaPanel* panel ); + mediaPanel* findMediaPanel( LLPluginClassMedia* panel ); + void makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels ); + void makeChrome(); + void resetView(); + + void dumpPanelInfo(); + void updateStatusBar(); + + // Inherited from LLPluginClassMediaOwner + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent); + + private: + const int mVersionMajor; + const int mVersionMinor; + const int mVersionPatch; + const int mMaxPanels; + int mAppWindow; + int mWindowWidth; + int mWindowHeight; + int mCurMouseX; + int mCurMouseY; + unsigned char mPixelReadColor[ 3 ]; + bool mFuzzyMedia; + const std::string mHomeWebUrl; + + std::vector< mediaPanel* > mMediaPanels; + mediaPanel* mSelectedPanel; + std::string mimeTypeFromUrl( std::string& url ); + std::string pluginNameFromMimeType( std::string& mime_type ); + + GLUI_Rotation* mViewRotationCtrl; + GLUI_Translation* mViewScaleCtrl; + GLUI_Translation* mViewTranslationCtrl; + float mViewportAspect; + float mViewPos[ 3 ]; + float mViewRotation[ 16 ]; + + int mIdControlAddPanel; + int mIdControlRemPanel; + + std::vector< std::pair< std::string, std::string > > mBookmarks; + GLUI_Listbox* mBookmarkList; + int mIdBookmarks; + int mIdUrlEdit; + GLUI_EditText* mUrlEdit; + int mIdUrlInitHistoryEdit; + GLUI_EditText* mUrlInitHistoryEdit; + int mSelBookmark; + int mIdRandomPanelCount; + int mRandomPanelCount; + int mIdRandomBookmarks; + int mRandomBookmarks; + int mIdDisableTimeout; + int mDisableTimeout; + int mIdControlCrashPlugin; + int mIdControlHangPlugin; + int mIdControlExitApp; + + GLUI* mGluiMediaTimeControlWindow; + int mIdMediaTimeControlPlay; + int mIdMediaTimeControlLoop; + int mIdMediaTimeControlPause; + int mIdMediaTimeControlStop; + int mIdMediaTimeControlSeek; + int mIdMediaTimeControlVolume; + int mMediaTimeControlVolume; + int mIdMediaTimeControlSeekSeconds; + int mMediaTimeControlSeekSeconds; + int mIdMediaTimeControlRewind; + int mIdMediaTimeControlFastForward; + + GLUI* mGluiMediaBrowserControlWindow; + int mIdMediaBrowserControlBack; + GLUI_Button* mMediaBrowserControlBackButton; + int mIdMediaBrowserControlStop; + int mIdMediaBrowserControlForward; + GLUI_Button* mMediaBrowserControlForwardButton; + bool mGluiMediaTimeControlWindowFlag; + bool mGluiMediaBrowserControlWindowFlag; + bool mMediaBrowserControlBackButtonFlag; + bool mMediaBrowserControlForwardButtonFlag; + int mIdMediaBrowserControlHome; + int mIdMediaBrowserControlReload; + int mIdMediaBrowserControlClearCache; + int mIdMediaBrowserControlClearCookies; + int mIdMediaBrowserControlEnableCookies; + int mMediaBrowserControlEnableCookies; + + GLUI* mBottomGLUIWindow; + GLUI_StaticText* mStatusText; +}; + +#endif // LL_MEDIA_PLUGIN_TEST_H + diff --git a/linden/indra/test_apps/llplugintest/media_mappings.txt b/linden/indra/test_apps/llplugintest/media_mappings.txt new file mode 100644 index 000000000..74188bc95 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/media_mappings.txt @@ -0,0 +1,3 @@ +Flash demo_media_plugin_flash.dll +ColNoise demo_media_plugin.dll +CheckBounce demo_media_plugin_2.dll diff --git a/linden/indra/test_apps/llplugintest/media_plugin_test.cpp b/linden/indra/test_apps/llplugintest/media_plugin_test.cpp new file mode 100644 index 000000000..8e42fa7ea --- /dev/null +++ b/linden/indra/test_apps/llplugintest/media_plugin_test.cpp @@ -0,0 +1,511 @@ +/** + * @file demo_plugin.cpp + * @brief Test plugin to be loaded by the llplugin testbed. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "indra_constants.h" + +#include "lltimer.h" // for ms_sleep() +#include "llpumpio.h" +#include "llapr.h" +#include "llerrorcontrol.h" +#include "llpluginclassmedia.h" + +#include <string> +#include <iostream> +#include <stdlib.h> +#include <time.h> + +#include "llmediaplugintest.h" // for GLUT headers + + +//////////////////////////////////////////////////////////////////////////////// +// +class mediaPluginTest : public LLPluginClassMediaOwner +{ + private: + int mAppWindowWidth; + int mAppWindowHeight; + LLPluginClassMedia* mMediaSource; + int mAppTextureWidth; + int mAppTextureHeight; + bool mAppTextureCoordsOpenGL; + GLuint mAppTexture; + std::string mAppWindowName; + std::string mHomeUrl; + std::string mLauncherFilename; + std::string mPluginFilename; + + LLPluginClassMedia *mPlugin; + + public: + mediaPluginTest(const std::string &launcher_filename, const std::string &plugin_filename) : + mAppWindowWidth( 800 ), + mAppWindowHeight( 600 ), + mAppTextureWidth( 0 ), + mAppTextureHeight( 0 ), + mAppTextureCoordsOpenGL(false), + mAppTexture( 0 ), + mAppWindowName( "Media Simple Test" ), + mHomeUrl( "" ) + { + mLauncherFilename = launcher_filename; + mMediaSource = new LLPluginClassMedia(this); + mMediaSource->init(launcher_filename, plugin_filename); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + virtual ~mediaPluginTest() + { + delete mMediaSource; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void createTexture() + { + // create the texture used to display the browser data + if(mMediaSource->textureValid()) + { + mAppTextureWidth = mMediaSource->getTextureWidth(); + mAppTextureHeight = mMediaSource->getTextureHeight(); + mAppTextureCoordsOpenGL = mMediaSource->getTextureCoordsOpenGL(); + + if(mAppTexture != 0) + { + glDeleteTextures( 1, &mAppTexture ); + mAppTexture = 0; + } + + glGenTextures( 1, &mAppTexture ); + glBindTexture( GL_TEXTURE_2D, mAppTexture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexImage2D( GL_TEXTURE_2D, 0, + mMediaSource->getTextureFormatInternal(), + mAppTextureWidth, + mAppTextureHeight, + 0, + mMediaSource->getTextureFormatPrimary(), + mMediaSource->getTextureFormatType(), + NULL ); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // + void initGL() + { + // OpenGL initialization + glClearColor( 0.0f, 0.0f, 0.0f, 0.5f); + glEnable( GL_COLOR_MATERIAL ); + glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); + glEnable( GL_TEXTURE_2D ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glEnable( GL_CULL_FACE ); + } + + //////////////////////////////////////////////////////////////////////////////// + // + void reshape( int width, int height ) + { + if ( height == 0 ) + height = 1; + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + glViewport( 0, 0, width, height ); + glOrtho( 0.0f, width, height, 0.0f, -1.0f, 1.0f ); + + // we use these values elsewhere so save + mAppWindowWidth = width; + mAppWindowHeight = height; + + // Request a media size change + mMediaSource->setSize(width, height); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void idle() + { + // lots of updates for smooth motion + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void display() + { + mMediaSource->idle(); + + // Check whether the texture needs to be recreated. + if(mMediaSource->textureValid()) + { + if( + (mAppTextureWidth != mMediaSource->getTextureWidth() || mAppTextureHeight != mMediaSource->getTextureHeight()) && + (mAppWindowWidth == mMediaSource->getWidth() && mAppWindowHeight == mMediaSource->getHeight()) + ) + { + // Attempt to (re)create the texture + createTexture(); + } + } + + // clear screen + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glLoadIdentity(); + + if(mAppTexture != 0) + { + // use the browser texture + glBindTexture( GL_TEXTURE_2D, mAppTexture ); + + // If dirty, update the texture. + LLRect dirtyRect; + if(!mMediaSource->textureValid()) + { +// LL_DEBUGS("media_plugin_test") << "Resize in progress, skipping update..." << LL_ENDL; + } + else if(mAppWindowWidth != mMediaSource->getWidth() || mAppWindowHeight != mMediaSource->getHeight()) + { + // A resize is in progress. Just wait for it... + } + else if(mMediaSource->getDirty(&dirtyRect)) + { + // grab the page + const unsigned char* pixels = mMediaSource->getBitsData(); + if ( pixels ) + { + // write them into the texture + + // Paranoia: intersect dirtyRect with (0, 0, mAppTextureWidth, mAppTextureHeight)? + + int x_offset = dirtyRect.mLeft; + int y_offset = dirtyRect.mBottom; + int width = dirtyRect.mRight - dirtyRect.mLeft; + int height = dirtyRect.mTop - dirtyRect.mBottom; + + LL_DEBUGS("media_plugin_test") << "Updating, dirty rect is (" + << dirtyRect.mLeft << ", " + << dirtyRect.mTop << ", " + << dirtyRect.mRight << ", " + << dirtyRect.mBottom << "), update params are: (" + << x_offset << ", " + << y_offset << ", " + << width << ", " + << height << ")" + << LL_ENDL; + + // Offset the pixels pointer properly + pixels += (y_offset * mMediaSource->getTextureDepth() * mMediaSource->getTextureWidth()); + pixels += (x_offset * mMediaSource->getTextureDepth()); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, mMediaSource->getTextureWidth()); + + glTexSubImage2D( GL_TEXTURE_2D, 0, + x_offset, + y_offset, + width, + height, + mMediaSource->getTextureFormatPrimary(), + mMediaSource->getTextureFormatType(), + pixels ); + + mMediaSource->resetDirty(); + } + } + + // scale the texture so that it fits the screen + GLdouble media_texture_x = mAppWindowWidth / (double)mAppTextureWidth; + GLdouble media_texture_y = mAppWindowHeight / (double)mAppTextureHeight; + + // draw the single quad full screen (orthographic) + + glEnable( GL_TEXTURE_2D ); + glColor3f( 1.0f, 1.0f, 1.0f ); + glBegin( GL_QUADS ); + if(mAppTextureCoordsOpenGL) + { + // Render the texture as per opengl coords (where 0,0 is at the lower left) + glTexCoord2d( 0, 0 ); + glVertex2d( 0, 0 ); + + glTexCoord2d( 0 , media_texture_y ); + glVertex2d( 0, mAppWindowHeight); + + glTexCoord2d( media_texture_x, media_texture_y ); + glVertex2d( mAppWindowWidth , mAppWindowHeight); + + glTexCoord2d( media_texture_x, 0 ); + glVertex2d( mAppWindowWidth, 0 ); + } + else + { + // Render the texture the "other way round" (where 0,0 is at the upper left) + glTexCoord2d( 0, media_texture_y ); + glVertex2d( 0, 0 ); + + glTexCoord2d( 0 , 0 ); + glVertex2d( 0, mAppWindowHeight); + + glTexCoord2d( media_texture_x, 0 ); + glVertex2d( mAppWindowWidth , mAppWindowHeight); + + glTexCoord2d( media_texture_x, media_texture_y ); + glVertex2d( mAppWindowWidth, 0 ); + } + glEnd(); + + } + + glutSwapBuffers(); + }; + + + //////////////////////////////////////////////////////////////////////////////// + // + MASK getModifiers(void) + { + MASK result = 0; + + int modifiers = glutGetModifiers(); + + if(modifiers & GLUT_ACTIVE_SHIFT) + result |= MASK_SHIFT; + if(modifiers & GLUT_ACTIVE_CTRL) + result |= MASK_CONTROL; + if(modifiers & GLUT_ACTIVE_ALT) + result |= MASK_ALT; + + return result; + } + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseButton( int button, int state, int x, int y ) + { + // Texture has been scaled so it's 1:1 with screen pixels, so no need to scale mouse coords here. +// x = ( x * mAppTextureWidth ) / mAppWindowWidth; +// y = ( y * mAppTextureHeight ) / mAppWindowHeight; + + if ( button == GLUT_LEFT_BUTTON ) + { + if ( state == GLUT_DOWN ) + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, x, y, getModifiers()); + else if ( state == GLUT_UP ) + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, x, y, getModifiers()); + } + + // force a GLUT update + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int x , int y ) + { + // Texture has been scaled so it's 1:1 with screen pixels, so no need to scale mouse coords here. +// x = ( x * mAppTextureWidth ) / mAppWindowWidth; +// y = ( y * mAppTextureHeight ) / mAppWindowHeight; + + // GLUT complains if I get the keyboard modifiers here, so just pretend there aren't any. + mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, x, y, 0); + + // force a GLUT update + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyboard( unsigned char key ) + { + mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, getModifiers()); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowWidth() + { + return mAppWindowWidth; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowHeight() + { + return mAppWindowHeight; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + std::string getAppWindowName() + { + return mAppWindowName; + }; + +}; + +mediaPluginTest* gApplication; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutReshape( int width, int height ) +{ + if ( gApplication ) + gApplication->reshape( width, height ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutDisplay() +{ + if ( gApplication ) + gApplication->display(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutIdle() +{ + if ( gApplication ) + gApplication->idle(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutKeyboard( unsigned char key, int x, int y ) +{ + if ( key == 27 ) + { + delete gApplication; + exit( 0 ); + }; + + if ( gApplication ) + gApplication->keyboard( key ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseMove( int x, int y ) +{ + if ( gApplication ) + gApplication->mouseMove( x, y ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseButton( int button, int state, int x, int y ) +{ + if ( gApplication ) + gApplication->mouseButton( button, state, x, y ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +int main( int argc, char* argv[] ) +{ + + ll_init_apr(); + + // Set up llerror logging + { + LLError::initForApplication("."); + LLError::setDefaultLevel(LLError::LEVEL_INFO); + } + + std::string launcher_name; + std::string plugin_name; + + if(argc >= 3) + { + launcher_name = argv[1]; + plugin_name = argv[2]; + } + else + { +#if LL_DARWIN + // hardcoding the testbed arguments by default + launcher_name = "plugin_process_host"; + plugin_name = "libdemo_media_plugin_quicktime.dylib"; +#elif LL_WINDOWS + // hardcoding the testbed arguments by default + launcher_name = "plugin_process_host.exe"; + plugin_name = "demo_media_plugin_quicktime.dll"; +#else + LL_ERRS("plugin_process_launcher") << "usage: " << argv[0] << " launcher_filename plugin_filename" << LL_ENDL; +#endif + } + + gApplication = new mediaPluginTest(launcher_name, plugin_name); + + if ( gApplication ) + { + glutInit( &argc, argv ); + glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); + + glutInitWindowPosition( 80, 0 ); + glutInitWindowSize( gApplication->getAppWindowWidth(), gApplication->getAppWindowHeight() ); + + glutCreateWindow( gApplication->getAppWindowName().c_str() ); + + glutKeyboardFunc( glutKeyboard ); + + glutMouseFunc( glutMouseButton ); + glutPassiveMotionFunc( glutMouseMove ); + glutMotionFunc( glutMouseMove ); + + glutDisplayFunc( glutDisplay ); + glutReshapeFunc( glutReshape ); + + glutIdleFunc( glutIdle ); + + gApplication->initGL(); + + glutMainLoop(); + + delete gApplication; + }; + + ll_cleanup_apr(); + + return 0; +} + diff --git a/linden/indra/test_apps/llplugintest/media_simple_test.cpp b/linden/indra/test_apps/llplugintest/media_simple_test.cpp new file mode 100644 index 000000000..9a60e8e6d --- /dev/null +++ b/linden/indra/test_apps/llplugintest/media_simple_test.cpp @@ -0,0 +1,460 @@ +/** + * @file demo_plugin.cpp + * @brief Test plugin to be loaded by the llplugin testbed. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include <string> +#include <iostream> +#include <stdlib.h> +#include <time.h> + +#if LL_DARWIN + #include <GLUT/glut.h> +#elif LL_LINUX + #include <GL/glut.h> +#else + #include "glut.h" +#endif + +//////////////////////////////////////////////////////////////////////////////// +// +class mediaSource +{ + public: + //////////////////////////////////////////////////////////////////////////////// + // + mediaSource() : + mPixels( 0 ), + mIsDirty( false ), + mWidth( 200 ), + mHeight( 100 ), + mDepth( 3 ), + mPixelFormat( GL_BGR_EXT ) + { + mPixels = new unsigned char [ mWidth * mHeight * mDepth ]; + + for( int i = 0; i < mWidth * mHeight * mDepth; ++i ) + *( mPixels + i ) = rand() % 0x40; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void update() + { + const time_t interval = 1; + static time_t last_time = time( NULL ); + time_t cur_time = time( NULL ); + + if ( cur_time - last_time > interval ) + { + for( int i = 0; i < mWidth * mHeight * mDepth; ++i ) + *( mPixels + i ) = rand() % 0x40; + + mIsDirty = true; + + last_time = cur_time; + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b ) + { + // make sure we don't write outside the buffer + if((x < 0) || (x >= mWidth) || (y < 0) || (y >= mHeight)) + return; + + *( mPixels + ( mHeight - y ) * mWidth * mDepth + x * mDepth + 0 ) = b; + *( mPixels + ( mHeight - y ) * mWidth * mDepth + x * mDepth + 1 ) = g; + *( mPixels + ( mHeight - y ) * mWidth * mDepth + x * mDepth + 2 ) = r; + + mIsDirty = true; + } + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseDown( int x, int y ) + { + write_pixel( x, y, 0xff, 0x00, 0x00 ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseUp( int x, int y ) + { + write_pixel( x, y, 0xff, 0xff, 0x00 ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int x, int y ) + { + write_pixel( x, y, 0xff, 0x00, 0xff ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyPress( unsigned char key ) + { + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getWidth() { return mWidth; }; + int getHeight() { return mHeight; }; + int getDepth() { return mDepth; }; + int getPixelFormat() { return mPixelFormat; }; + bool isDirty() { return mIsDirty; }; + void ackDirty() { mIsDirty = false; }; + unsigned char* getPixels() { return mPixels; }; + + private: + unsigned char* mPixels; + bool mIsDirty; + int mWidth; + int mHeight; + int mDepth; + int mPixelFormat; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +class mediaSimpleTest +{ + public: + mediaSimpleTest() : + mAppWindowWidth( 800 ), + mAppWindowHeight( 600 ), + mAppTextureWidth( 0 ), + mAppTextureHeight( 0 ), + mAppTexture( 0 ), + mAppWindowName( "Media Simple Test" ), + mHomeUrl( "" ) + { + mMediaSource = new mediaSource; + + // calculate texture size required (next power of two above browser window size + for ( mAppTextureWidth = 1; mAppTextureWidth < mMediaSource->getWidth(); mAppTextureWidth <<= 1 ) {}; + for ( mAppTextureHeight = 1; mAppTextureHeight < mMediaSource->getHeight(); mAppTextureHeight <<= 1 ) {}; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + ~mediaSimpleTest() + { + delete mMediaSource; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void initGL() + { + // OpenGL initialization + glClearColor( 0.0f, 0.0f, 0.0f, 0.5f); + glEnable( GL_COLOR_MATERIAL ); + glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); + glEnable( GL_TEXTURE_2D ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glEnable( GL_CULL_FACE ); + + // create the texture used to display the browser data + glGenTextures( 1, &mAppTexture ); + glBindTexture( GL_TEXTURE_2D, mAppTexture ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexImage2D( GL_TEXTURE_2D, 0, + GL_RGB, + mAppTextureWidth, mAppTextureHeight, + 0, GL_RGB, GL_UNSIGNED_BYTE, 0 ); + } + + //////////////////////////////////////////////////////////////////////////////// + // + void reshape( int width, int height ) + { + if ( height == 0 ) + height = 1; + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + glViewport( 0, 0, width, height ); + glOrtho( 0.0f, width, height, 0.0f, -1.0f, 1.0f ); + + // we use these values elsewhere so save + mAppWindowWidth = width; + mAppWindowHeight = height; + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void idle() + { + // lots of updates for smooth motion + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void display() + { + // clear screen + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glLoadIdentity(); + + // use the browser texture + glBindTexture( GL_TEXTURE_2D, mAppTexture ); + + // needs to be updated? + mMediaSource->update(); + if ( mMediaSource->isDirty() ) + { + // grab the page + const unsigned char* pixels = mMediaSource->getPixels(); + if ( pixels ) + { + // write them into the texture + glTexSubImage2D( GL_TEXTURE_2D, 0, + 0, 0, + mMediaSource->getWidth(), + mMediaSource->getHeight(), + mMediaSource->getPixelFormat(), + GL_UNSIGNED_BYTE, + pixels ); + + // acknowledge we saw media was dirty and updated + mMediaSource->ackDirty(); + }; + }; + + // scale the texture so that it fits the screen + GLfloat texture_scale_x = ( GLfloat )mMediaSource->getWidth() / ( GLfloat )mAppTextureWidth; + GLfloat texture_scale_y = ( GLfloat )mMediaSource->getHeight() / ( GLfloat )mAppTextureHeight; + + // draw the single quad full screen (orthographic) + glMatrixMode( GL_TEXTURE ); + glPushMatrix(); + glScalef( texture_scale_x, texture_scale_y, 1.0f ); + + glEnable( GL_TEXTURE_2D ); + glColor3f( 1.0f, 1.0f, 1.0f ); + glBegin( GL_QUADS ); + glTexCoord2f( 1.0f, 1.0f ); + glVertex2d( mAppWindowWidth, 0 ); + + glTexCoord2f( 0.0f, 1.0f ); + glVertex2d( 0, 0 ); + + glTexCoord2f( 0.0f, 0.0f ); + glVertex2d( 0, mAppWindowHeight ); + + glTexCoord2f( 1.0f, .0f ); + glVertex2d( mAppWindowWidth, mAppWindowHeight ); + glEnd(); + + glMatrixMode( GL_TEXTURE ); + glPopMatrix(); + + glutSwapBuffers(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseButton( int button, int state, int x, int y ) + { + // texture is scaled to fit the screen so we scale mouse coords in the same way + x = ( x * mMediaSource->getWidth() ) / mAppWindowWidth; + y = ( y * mMediaSource->getHeight() ) / mAppWindowHeight; + + if ( button == GLUT_LEFT_BUTTON ) + { + if ( state == GLUT_DOWN ) + mMediaSource->mouseDown( x, y ); + else + if ( state == GLUT_UP ) + mMediaSource->mouseUp( x, y ); + }; + + // force a GLUT update + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int x , int y ) + { + // texture is scaled to fit the screen so we scale mouse coords in the same way + x = ( x * mMediaSource->getWidth() ) / mAppWindowWidth; + y = ( y * mMediaSource->getHeight() ) / mAppWindowHeight; + + mMediaSource->mouseMove( x, y ); + + // force a GLUT update + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyboard( unsigned char key ) + { + mMediaSource->keyPress( key ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowWidth() + { + return mAppWindowWidth; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowHeight() + { + return mAppWindowHeight; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + std::string getAppWindowName() + { + return mAppWindowName; + }; + + private: + int mAppWindowWidth; + int mAppWindowHeight; + mediaSource* mMediaSource; + int mAppTextureWidth; + int mAppTextureHeight; + GLuint mAppTexture; + std::string mAppWindowName; + std::string mHomeUrl; +}; + +mediaSimpleTest* gApplication; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutReshape( int width, int height ) +{ + if ( gApplication ) + gApplication->reshape( width, height ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutDisplay() +{ + if ( gApplication ) + gApplication->display(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutIdle() +{ + if ( gApplication ) + gApplication->idle(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutKeyboard( unsigned char key, int x, int y ) +{ + if ( key == 27 ) + { + delete gApplication; + exit( 0 ); + }; + + if ( gApplication ) + gApplication->keyboard( key ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseMove( int x, int y ) +{ + if ( gApplication ) + gApplication->mouseMove( x, y ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseButton( int button, int state, int x, int y ) +{ + if ( gApplication ) + gApplication->mouseButton( button, state, x, y ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +int main( int argc, char* argv[] ) +{ + gApplication = new mediaSimpleTest; + + if ( gApplication ) + { + glutInit( &argc, argv ); + glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); + + glutInitWindowPosition( 80, 0 ); + glutInitWindowSize( gApplication->getAppWindowWidth(), gApplication->getAppWindowHeight() ); + + glutCreateWindow( gApplication->getAppWindowName().c_str() ); + + glutKeyboardFunc( glutKeyboard ); + + glutMouseFunc( glutMouseButton ); + glutPassiveMotionFunc( glutMouseMove ); + glutMotionFunc( glutMouseMove ); + + glutDisplayFunc( glutDisplay ); + glutReshapeFunc( glutReshape ); + + glutIdleFunc( glutIdle ); + + gApplication->initGL(); + + glutMainLoop(); + + delete gApplication; + }; + + return 0; +} + diff --git a/linden/indra/test_apps/llplugintest/plugin_host.cpp b/linden/indra/test_apps/llplugintest/plugin_host.cpp new file mode 100644 index 000000000..5ba5d8b57 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/plugin_host.cpp @@ -0,0 +1,92 @@ +/** + * @file plugin_host.cpp + * @brief Testbed for llplugin which directly loads a plugin dynamic library. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "linden_common.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llerrorcontrol.h" + +class MessageReceiver: public LLPluginInstanceMessageListener +{ + // Inherited from LLPluginInstanceMessageListener + /* virtual */ void receivePluginMessage(const std::string &message) + { + LL_INFOS("plugin_host") << "message received from plugin: " << message << LL_ENDL; + } + +}; + +int main(int argc, char **argv) +{ + ll_init_apr(); + + // Set up llerror logging + { + LLError::initForApplication("."); + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + } + + if(argc < 2) + { + LL_ERRS("plugin_host") << "usage: " << argv[0] << " plugin_filename" << LL_ENDL; + exit(1); + } + + std::string name = argv[1]; + + MessageReceiver receiver; + LLPluginInstance *plugin = new LLPluginInstance(&receiver); + if(plugin->load(name) == 0) + { + LLPluginMessage message; + message.setMessage("base", "init"); + message.setValue("foo", "1"); + message.setValue("bar", "2"); + plugin->sendMessage(message.generate()); + + message.setMessage("base", "idle"); + message.setValue("baz", "3"); + plugin->sendMessage(message.generate()); + + message.setMessage("base", "shutdown"); + plugin->sendMessage(message.generate()); + + plugin->idle(); + } + + delete plugin; + + ll_cleanup_apr(); +} + diff --git a/linden/indra/test_apps/llplugintest/plugin_process_launcher.cpp b/linden/indra/test_apps/llplugintest/plugin_process_launcher.cpp new file mode 100644 index 000000000..82b11e3c6 --- /dev/null +++ b/linden/indra/test_apps/llplugintest/plugin_process_launcher.cpp @@ -0,0 +1,197 @@ +/** + * @file plugin_process_launcher.cpp + * @brief Testbed for llplugin which launches the plugin loader shell. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llprocesslauncher.h" +#include "lltimer.h" // for ms_sleep() +#include "llpumpio.h" +#include "llapr.h" +#include "llerrorcontrol.h" +#include "llpluginprocessparent.h" + +class PluginProcessLauncherMessageReceiver : public LLPluginProcessParentOwner +{ +LOG_CLASS(PluginProcessLauncherMessageReceiver); + +public: + virtual ~PluginProcessLauncherMessageReceiver() + { + } + + /* virtual */ void receivePluginMessage(const LLPluginMessage &message) + { + LL_INFOS("plugin_process_launcher") << "received message: \n" << message.generate() << LL_ENDL; + } +}; + +LLPumpIO* gServicePump; +LLPluginProcessParent *gPlugin; + + +#define SHARED_MEMORY_SIZE 0x10000 +#define SHARED_MEMORY_NAME "testsegment" +enum State +{ + STATE_STARTUP, + STATE_ADD_MEMORY, + STATE_RUNNING, + STATE_REMOVE_MEMORY, + STATE_SHUTDOWN, + STATE_CLEANUP, + STATE_DONE +}; + +int main(int argc, char **argv) +{ + ll_init_apr(); + + // Set up llerror logging + { + LLError::initForApplication("."); + LLError::setDefaultLevel(LLError::LEVEL_INFO); + } + + std::string launcher_name; + std::string plugin_name; + + if(argc >= 3) + { + launcher_name = argv[1]; + plugin_name = argv[2]; + } + else + { +#if LL_DARWIN + // hardcoding the testbed arguments by default + launcher_name = "plugin_process_host"; + plugin_name = "libdemo_plugin.dylib"; +#elif LL_WINDOWS + // hardcoding the testbed arguments by default + launcher_name = "plugin_process_host.exe"; + plugin_name = "demo_plugin.dll"; +#else + LL_ERRS("plugin_process_launcher") << "usage: " << argv[0] << " launcher_filename plugin_filename" << LL_ENDL; +#endif + } + + PluginProcessLauncherMessageReceiver receiver; + + gServicePump = new LLPumpIO(gAPRPoolp); + gServicePump->prime(gAPRPoolp); + + gPlugin = new LLPluginProcessParent(gServicePump, &receiver); + + State state = STATE_STARTUP; + while(state != STATE_DONE) + { + switch(state) + { + case STATE_STARTUP: + LL_INFOS("plugin_process_launcher") << "startup" << LL_ENDL; + gPlugin->init(launcher_name, plugin_name); + state = STATE_ADD_MEMORY; + break; + + case STATE_ADD_MEMORY: + if(gPlugin->isRunning()) + { + LL_INFOS("plugin_process_launcher") << "adding shared memory" << LL_ENDL; + gPlugin->addSharedMemory(SHARED_MEMORY_SIZE); + state = STATE_RUNNING; + } + break; + + case STATE_RUNNING: + { + volatile unsigned char *addr = (unsigned char*)gPlugin->getSharedMemoryAddress(SHARED_MEMORY_NAME); + if(addr != NULL) + { + int val = (int)(addr[0]); + if(val >= 16) + { + state = STATE_REMOVE_MEMORY; + } + else + { + LL_INFOS("plugin_process_launcher") << "running, value from shared memory is " << val << LL_ENDL; + } + } + } + break; + + case STATE_REMOVE_MEMORY: + LL_INFOS("plugin_process_launcher") << "removing shared memory" << LL_ENDL; + gPlugin->removeSharedMemory(SHARED_MEMORY_NAME); + state = STATE_SHUTDOWN; + break; + + case STATE_SHUTDOWN: + { + volatile unsigned char *addr = (unsigned char*)gPlugin->getSharedMemoryAddress(SHARED_MEMORY_NAME); + if(addr == NULL) + { + LL_INFOS("plugin_process_launcher") << "sending shutdown request" << LL_ENDL; + gPlugin->shutdownRequest(); + state = STATE_CLEANUP; + } + } + break; + + case STATE_CLEANUP: + if(gPlugin->isDone()) + { + LL_INFOS("plugin_process_launcher") << "plugin is done" << LL_ENDL; + state = STATE_DONE; + } + break; + + case STATE_DONE: + // should never reach here -- the while() should exit first. + break; + } + + // Do this every time through the loop + if(state != STATE_DONE) + { + gServicePump->pump(); + gServicePump->callback(); + gPlugin->idle(); + ms_sleep(100); + } + } + + delete gPlugin; + + ll_cleanup_apr(); + +} diff --git a/linden/install.xml b/linden/install.xml old mode 100755 new mode 100644 index 633224418..21180903c --- a/linden/install.xml +++ b/linden/install.xml @@ -1112,39 +1112,32 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura </map> </map> </map> - <key>llmozlib</key> + <key>llqtwebkit</key> <map> <key>license</key> - <string>mozillaPL</string> + <string>lgpl</string> <key>packages</key> <map> <key>darwin</key> <map> <key>md5sum</key> - <string>c951587726618d33646f2b169c290bd3</string> + <string>b40a13847ee773c9ee06f641fe0dd1c2</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llmozlib-2_0_0_21-darwin-20090304.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-darwin-20091023.tar.bz2</uri> </map> <key>linux</key> <map> <key>md5sum</key> - <string>b7ebcf0fb764ed4fa57c62d068b4a769</string> - <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llmozlib-linux-20090304prfhk.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>afa946a118d3d71123003785189a31f2</string> + <string>ffede2775355676096b1085cbb9d0da7</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/llmozlib-linux64-20091231.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20091117.tar.bz2</uri> </map> <key>windows</key> <map> <key>md5sum</key> - <string>e9454e258b99668782d8570481b5eda1</string> + <string>6f2f911545e5906edc87f4f3cda423a1</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llmozlib-windows-20090306.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-windows-20091023.tar.bz2</uri> </map> </map> </map> From 09b7d25b1d24b5b6d5bb1ce31544d8f4abaa3bb7 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Tue, 7 Sep 2010 10:08:26 +0200 Subject: [PATCH 002/239] lost in merge: 1 debug setting, some member variables from llpanellandmedia todo: review llpanellandmedia; port flotervoicelicense --- .../indra/newview/app_settings/settings.xml | 11 +++++ linden/indra/newview/llpanellandmedia.cpp | 40 +++++++++---------- linden/indra/newview/llpanellandmedia.h | 7 ++++ 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 4d8084598..f70c0fc69 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -4135,6 +4135,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DebugPluginDisableTimeout</key> + <map> + <key>Comment</key> + <string>Disable the code which watches for plugins that are crashed or hung</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DebugShowColor</key> <map> <key>Comment</key> diff --git a/linden/indra/newview/llpanellandmedia.cpp b/linden/indra/newview/llpanellandmedia.cpp index a8e7c4aea..fc84bb51c 100644 --- a/linden/indra/newview/llpanellandmedia.cpp +++ b/linden/indra/newview/llpanellandmedia.cpp @@ -171,8 +171,8 @@ void LLPanelLandMedia::refresh() // Display options BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); -//imprudence fixme mCheckSoundLocal->set( parcel->getSoundLocal() ); -//imprudence fixme mCheckSoundLocal->setEnabled( can_change_media ); + mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->setEnabled( can_change_media ); LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); if (!region) @@ -188,39 +188,39 @@ void LLPanelLandMedia::refresh() { if (region && region->isVoiceEnabled()) // estate-wide voice-disable overrides all { -//imprudence fixme mCheckEnableVoiceChatIsEstateDisabled->setVisible(false); + mCheckEnableVoiceChatIsEstateDisabled->setVisible(false); -//imprudence fixme mCheckEnableVoiceChat->setVisible(true); -//imprudence fixme mCheckEnableVoiceChat->setEnabled( can_change_media ); -//imprudence fixme mCheckEnableVoiceChat->set(allow_voice); + mCheckEnableVoiceChat->setVisible(true); + mCheckEnableVoiceChat->setEnabled( can_change_media ); + mCheckEnableVoiceChat->set(allow_voice); -//imprudence fixme mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); + mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); } else // disabled at region level { -//imprudence fixme mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); // always disabled -//imprudence fixme mCheckEnableVoiceChat->setVisible(false); -//imprudence fixme mCheckEnableVoiceChat->setEnabled(false); -//imprudence fixme mCheckEnableVoiceChat->set(false); + mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); // always disabled + mCheckEnableVoiceChat->setVisible(false); + mCheckEnableVoiceChat->setEnabled(false); + mCheckEnableVoiceChat->set(false); -//imprudence fixme mCheckEnableVoiceChatParcel->setEnabled(false); + mCheckEnableVoiceChatParcel->setEnabled(false); } } else { -//imprudence fixme mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); + mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); -//imprudence fixme mCheckEnableVoiceChat->setVisible(true); -//imprudence fixme mCheckEnableVoiceChat->setEnabled( can_change_media ); -//imprudence fixme mCheckEnableVoiceChat->set(allow_voice); + mCheckEnableVoiceChat->setVisible(true); + mCheckEnableVoiceChat->setEnabled( can_change_media ); + mCheckEnableVoiceChat->set(allow_voice); -//imprudence fixme mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); + mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); } -//imprudence fixme mCheckEnableVoiceChatParcel->set(!parcel->getParcelFlagUseEstateVoiceChannel()); + mCheckEnableVoiceChatParcel->set(!parcel->getParcelFlagUseEstateVoiceChannel()); -//imprudence fixme mMusicURLEdit->setText(parcel->getMusicURL()); -//imprudence fixme mMusicURLEdit->setEnabled( can_change_media ); + mMusicURLEdit->setText(parcel->getMusicURL()); + mMusicURLEdit->setEnabled( can_change_media ); diff --git a/linden/indra/newview/llpanellandmedia.h b/linden/indra/newview/llpanellandmedia.h index c883d9801..d63f0f6b5 100644 --- a/linden/indra/newview/llpanellandmedia.h +++ b/linden/indra/newview/llpanellandmedia.h @@ -61,6 +61,12 @@ class LLPanelLandMedia static void onClickRemoveURLFilter(void *userdata); private: + LLCheckBoxCtrl* mCheckSoundLocal; + LLButton* mSoundHelpButton; + LLCheckBoxCtrl* mCheckEnableVoiceChat; + LLCheckBoxCtrl* mCheckEnableVoiceChatIsEstateDisabled; + LLCheckBoxCtrl* mCheckEnableVoiceChatParcel; + LLLineEditor* mMusicURLEdit; LLLineEditor* mMediaURLEdit; LLLineEditor* mMediaDescEdit; LLComboBox* mMediaTypeCombo; @@ -75,6 +81,7 @@ class LLPanelLandMedia LLCheckBoxCtrl* mMediaAutoScaleCheck; LLCheckBoxCtrl* mMediaLoopCheck; LLCheckBoxCtrl* mMediaUrlCheck; + LLCheckBoxCtrl* mMusicUrlCheck; LLHandle<LLFloater> mURLEntryFloater; LLCheckBoxCtrl* mMediaNavigateAllowCheck; LLCheckBoxCtrl* mMediaURLFilterCheck; From 9d37fb4eeb15f7ac35ebaa3fd7c5cc11e5b1a1dc Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Tue, 7 Sep 2010 10:26:01 +0200 Subject: [PATCH 003/239] First LL update of plugins, mainly documentation --- .../media_plugins/base/media_plugin_base.cpp | 57 +++++- .../media_plugins/base/media_plugin_base.h | 45 +++-- .../llmediaimplgstreamertriviallogging.h | 6 + .../llmediaimplgstreamervidplug.cpp | 35 ++-- .../llmediaimplgstreamervidplug.h | 2 +- .../media_plugin_gstreamer010.cpp | 78 ++++---- .../media_plugins/quicktime/CMakeLists.txt | 8 + .../quicktime/media_plugin_quicktime.cpp | 170 +++++++++++++++--- .../webkit/media_plugin_webkit.cpp | 53 ++++-- linden/indra/newview/llviewerparcelmedia.cpp | 7 +- 10 files changed, 358 insertions(+), 103 deletions(-) diff --git a/linden/indra/media_plugins/base/media_plugin_base.cpp b/linden/indra/media_plugins/base/media_plugin_base.cpp index 19194196d..4d5e3744e 100644 --- a/linden/indra/media_plugins/base/media_plugin_base.cpp +++ b/linden/indra/media_plugins/base/media_plugin_base.cpp @@ -2,6 +2,8 @@ * @file media_plugin_base.cpp * @brief Media plugin base class for LLMedia API plugin system * + * All plugins should be a subclass of MediaPluginBase. + * * $LicenseInfo:firstyear=2008&license=viewergpl$ * * Copyright (c) 2008-2009, Linden Research, Inc. @@ -36,7 +38,10 @@ // TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint //////////////////////////////////////////////////////////////////////////////// -// +/// Media plugin constructor. +/// +/// @param[in] host_send_func Function for sending messages from plugin to plugin loader shell +/// @param[in] host_user_data Message data for messages from plugin to plugin loader shell MediaPluginBase::MediaPluginBase( LLPluginInstance::sendMessageFunction host_send_func, @@ -54,6 +59,12 @@ MediaPluginBase::MediaPluginBase( mStatus = STATUS_NONE; } +/** + * Converts current media status enum value into string (STATUS_LOADING into "loading", etc.) + * + * @return Media status string ("loading", "playing", "paused", etc) + * + */ std::string MediaPluginBase::statusString() { std::string result; @@ -65,6 +76,7 @@ std::string MediaPluginBase::statusString() case STATUS_ERROR: result = "error"; break; case STATUS_PLAYING: result = "playing"; break; case STATUS_PAUSED: result = "paused"; break; + case STATUS_DONE: result = "done"; break; default: // keep the empty string break; @@ -73,6 +85,12 @@ std::string MediaPluginBase::statusString() return result; } +/** + * Set media status. + * + * @param[in] status Media status (STATUS_LOADING, STATUS_PLAYING, STATUS_PAUSED, etc) + * + */ void MediaPluginBase::setStatus(EStatus status) { if(mStatus != status) @@ -83,6 +101,13 @@ void MediaPluginBase::setStatus(EStatus status) } +/** + * Receive message from plugin loader shell. + * + * @param[in] message_string Message string + * @param[in] user_data Message data + * + */ void MediaPluginBase::staticReceiveMessage(const char *message_string, void **user_data) { MediaPluginBase *self = (MediaPluginBase*)*user_data; @@ -100,12 +125,27 @@ void MediaPluginBase::staticReceiveMessage(const char *message_string, void **us } } +/** + * Send message to plugin loader shell. + * + * @param[in] message Message data being sent to plugin loader shell + * + */ void MediaPluginBase::sendMessage(const LLPluginMessage &message) { std::string output = message.generate(); mHostSendFunction(output.c_str(), &mHostUserData); } +/** + * Notifies plugin loader shell that part of display area needs to be redrawn. + * + * @param[in] left Left X coordinate of area to redraw (0,0 is at top left corner) + * @param[in] top Top Y coordinate of area to redraw (0,0 is at top left corner) + * @param[in] right Right X-coordinate of area to redraw (0,0 is at top left corner) + * @param[in] bottom Bottom Y-coordinate of area to redraw (0,0 is at top left corner) + * + */ void MediaPluginBase::setDirty(int left, int top, int right, int bottom) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); @@ -118,6 +158,10 @@ void MediaPluginBase::setDirty(int left, int top, int right, int bottom) sendMessage(message); } +/** + * Sends "media_status" message to plugin loader shell ("loading", "playing", "paused", etc.) + * + */ void MediaPluginBase::sendStatus() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "media_status"); @@ -141,6 +185,17 @@ extern "C" LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); } +/** + * Plugin initialization and entry point. Establishes communication channel for messages between plugin and plugin loader shell. TODO:DOC - Please check! + * + * @param[in] host_send_func Function for sending messages from plugin to plugin loader shell + * @param[in] host_user_data Message data for messages from plugin to plugin loader shell + * @param[out] plugin_send_func Function for plugin to receive messages from plugin loader shell + * @param[out] plugin_user_data Pointer to plugin instance + * + * @return int, where 0=success + * + */ LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) { diff --git a/linden/indra/media_plugins/base/media_plugin_base.h b/linden/indra/media_plugins/base/media_plugin_base.h index 487270601..24198af81 100644 --- a/linden/indra/media_plugins/base/media_plugin_base.h +++ b/linden/indra/media_plugins/base/media_plugin_base.h @@ -41,14 +41,17 @@ class MediaPluginBase { public: MediaPluginBase(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + /** Media plugin destructor. */ virtual ~MediaPluginBase() {} + /** Handle received message from plugin loader shell. */ virtual void receiveMessage(const char *message_string) = 0; static void staticReceiveMessage(const char *message_string, void **user_data); protected: + /** Plugin status. */ typedef enum { STATUS_NONE, @@ -57,12 +60,16 @@ class MediaPluginBase STATUS_ERROR, STATUS_PLAYING, STATUS_PAUSED, + STATUS_DONE } EStatus; + /** Plugin shared memory. */ class SharedSegmentInfo { public: + /** Shared memory address. */ void *mAddress; + /** Shared memory size. */ size_t mSize; }; @@ -71,42 +78,56 @@ class MediaPluginBase std::string statusString(); void setStatus(EStatus status); - // The quicktime plugin overrides this to add current time and duration to the message... + /// Note: The quicktime plugin overrides this to add current time and duration to the message. virtual void setDirty(int left, int top, int right, int bottom); + /** Map of shared memory names to shared memory. */ typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap; + /** Function to send message from plugin to plugin loader shell. */ LLPluginInstance::sendMessageFunction mHostSendFunction; + /** Message data being sent to plugin loader shell by mHostSendFunction. */ void *mHostUserData; + /** Flag to delete plugin instance (self). */ bool mDeleteMe; + /** Pixel array to display. TODO:DOC are pixels always 24-bit RGB format, aligned on 32-bit boundary? Also: calling this a pixel array may be misleading since 1 pixel > 1 char. */ unsigned char* mPixels; + /** TODO:DOC what's this for -- does a texture have its own piece of shared memory? updated on size_change_request, cleared on shm_remove */ std::string mTextureSegmentName; + /** Width of plugin display in pixels. */ int mWidth; + /** Height of plugin display in pixels. */ int mHeight; + /** Width of plugin texture. */ int mTextureWidth; + /** Height of plugin texture. */ int mTextureHeight; + /** Pixel depth (pixel size in bytes). */ int mDepth; + /** Current status of plugin. */ EStatus mStatus; + /** Map of shared memory segments. */ SharedSegmentMap mSharedSegments; }; -// The plugin must define this function to create its instance. +/** The plugin <b>must</b> define this function to create its instance. + * It should look something like this: + * @code + * { + * MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data); + * *plugin_send_func = MediaPluginFoo::staticReceiveMessage; + * *plugin_user_data = (void*)self; + * + * return 0; + * } + * @endcode + */ int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); -// It should look something like this: -/* -{ - MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data); - *plugin_send_func = MediaPluginFoo::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; -} -*/ diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h index e31d4a328..04976b92f 100644 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h @@ -35,10 +35,16 @@ #include <cstdio> +extern "C" { +#include <sys/types.h> +#include <unistd.h> +} + ///////////////////////////////////////////////////////////////////////// // Debug/Info/Warning macros. #define MSGMODULEFOO "(media plugin)" #define STDERRMSG(...) do{\ + fprintf(stderr, " pid:%d: ", (int)getpid());\ fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\ fprintf(stderr, __VA_ARGS__);\ fputc('\n',stderr);\ diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index 25e96d412..ef8ff588c 100644 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -52,7 +52,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); #define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ( - (gchar*)"sink", + "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (SLV_ALLCAPS) @@ -106,11 +106,10 @@ gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) slvideo = GST_SLVIDEO(bsink); -#if 0 - fprintf(stderr, "\n\ntransferring a frame of %dx%d <- %p (%d)\n\n", - slvideo->width, slvideo->height, GST_BUFFER_DATA(buf), - slvideo->format); -#endif + DEBUGMSG("transferring a frame of %dx%d <- %p (%d)", + slvideo->width, slvideo->height, GST_BUFFER_DATA(buf), + slvideo->format); + if (GST_BUFFER_DATA(buf)) { // copy frame and frame info into neutral territory @@ -335,7 +334,7 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, #define MAXDEPTHHACK 4 GST_OBJECT_LOCK(slvideo); - if (slvideo->resize_forced) + if (slvideo->resize_forced_always) // app is giving us a fixed size to work with { gint slwantwidth, slwantheight; slwantwidth = slvideo->resize_try_width; @@ -384,6 +383,8 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, } } + GST_OBJECT_UNLOCK(slvideo); + if (!made_bufferdata_ptr) // need to fallback to malloc at original size { GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; @@ -392,8 +393,6 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); } - GST_OBJECT_UNLOCK(slvideo); - *buf = GST_BUFFER_CAST(newbuf); return GST_FLOW_OK; @@ -457,7 +456,7 @@ gst_slvideo_init (GstSLVideo * filter, filter->retained_frame_format = SLV_PF_UNKNOWN; GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); llgst_caps_replace (&filter->caps, caps); - filter->resize_forced = false; + filter->resize_forced_always = false; filter->resize_try_width = -1; filter->resize_try_height = -1; GST_OBJECT_UNLOCK(filter); @@ -498,12 +497,12 @@ gst_slvideo_get_property (GObject * object, guint prop_id, static gboolean plugin_init (GstPlugin * plugin) { - DEBUGMSG("\n\n\nPLUGIN INIT\n\n\n"); + DEBUGMSG("PLUGIN INIT"); GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", 0, (gchar*)"Second Life Video Sink"); - return llgst_element_register (plugin, (gchar*)"private-slvideo", + return llgst_element_register (plugin, "private-slvideo", GST_RANK_NONE, GST_TYPE_SLVIDEO); } @@ -519,14 +518,14 @@ void gst_slvideo_init_class (void) // this macro quietly refers to PACKAGE internally static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, - (gchar*)"private-slvideoplugin", - (gchar*)"SL Video sink plugin", - plugin_init, (gchar*)"0.1", (gchar*)GST_LICENSE_UNKNOWN, - (gchar*)"Second Life", - (gchar*)"http://www.secondlife.com/"); + "private-slvideoplugin", + "SL Video sink plugin", + plugin_init, "0.1", GST_LICENSE_UNKNOWN, + "Second Life", + "http://www.secondlife.com/"); #undef PACKAGE ll_gst_plugin_register_static (&gst_plugin_desc); - DEBUGMSG(stderr, "\n\n\nCLASS INIT\n\n\n"); + DEBUGMSG("CLASS INIT"); } #endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index f6d55b875..8cdc72d50 100644 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -88,7 +88,7 @@ struct _GstSLVideo int retained_frame_width, retained_frame_height; SLVPixelFormat retained_frame_format; // sticky resize info - bool resize_forced; + bool resize_forced_always; int resize_try_width; int resize_try_height; }; diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 77b7c1319..5b3152d61 100644 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -104,7 +104,7 @@ class MediaPluginGStreamer010 : public MediaPluginBase void mouseUp( int x, int y ); void mouseMove( int x, int y ); - bool sizeChanged(); + void sizeChanged(); static bool mDoneInit; @@ -114,13 +114,16 @@ class MediaPluginGStreamer010 : public MediaPluginBase int mDepth; - // media natural size + // media NATURAL size int mNaturalWidth; int mNaturalHeight; - int mNaturalRowbytes; - // previous media natural size so we can detect changes - int mPreviousNaturalWidth; - int mPreviousNaturalHeight; + // media current size + int mCurrentWidth; + int mCurrentHeight; + int mCurrentRowbytes; + // previous media size so we can detect changes + int mPreviousWidth; + int mPreviousHeight; // desired render size from host int mWidth; int mHeight; @@ -148,7 +151,7 @@ MediaPluginGStreamer010::MediaPluginGStreamer010( void *host_user_data ) : MediaPluginBase(host_send_func, host_user_data), mBusWatchID ( 0 ), - mNaturalRowbytes ( 4 ), + mCurrentRowbytes ( 4 ), mTextureFormatPrimary ( GL_RGBA ), mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ), mSeekWanted(false), @@ -194,6 +197,7 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus, } else { + // TODO: grok 'duration' message type DEBUGMSG("Got GST message type: %s", LLGST_MESSAGE_TYPE_NAME (message)); } @@ -428,8 +432,8 @@ MediaPluginGStreamer010::update(int milliseconds) { DEBUGMSG("NEW FRAME READY"); - if (mVideoSink->retained_frame_width != mNaturalWidth || - mVideoSink->retained_frame_height != mNaturalHeight) + if (mVideoSink->retained_frame_width != mCurrentWidth || + mVideoSink->retained_frame_height != mCurrentHeight) // *TODO: also check for change in format { // just resize container, don't consume frame @@ -456,39 +460,38 @@ MediaPluginGStreamer010::update(int milliseconds) GST_OBJECT_UNLOCK(mVideoSink); - mNaturalRowbytes = neww * newd; + mCurrentRowbytes = neww * newd; DEBUGMSG("video container resized to %dx%d", neww, newh); mDepth = newd; - mNaturalWidth = neww; - mNaturalHeight = newh; + mCurrentWidth = neww; + mCurrentHeight = newh; sizeChanged(); return true; } if (mPixels && - mNaturalHeight <= mHeight && - mNaturalWidth <= mWidth && + mCurrentHeight <= mHeight && + mCurrentWidth <= mWidth && !mTextureSegmentName.empty()) { - // we're gonna totally consume this frame - reset 'ready' flag - mVideoSink->retained_frame_ready = FALSE; + mVideoSink->retained_frame_ready = FALSE; int destination_rowbytes = mWidth * mDepth; - for (int row=0; row<mNaturalHeight; ++row) + for (int row=0; row<mCurrentHeight; ++row) { memcpy(&mPixels [destination_rowbytes * row], &mVideoSink->retained_frame_data - [mNaturalRowbytes * row], - mNaturalRowbytes); + [mCurrentRowbytes * row], + mCurrentRowbytes); } GST_OBJECT_UNLOCK(mVideoSink); DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); - setDirty(0,0,mNaturalWidth,mNaturalHeight); + setDirty(0,0,mCurrentWidth,mCurrentHeight); } else { @@ -835,27 +838,35 @@ MediaPluginGStreamer010::startup() } -bool +void MediaPluginGStreamer010::sizeChanged() { // the shared writing space has possibly changed size/location/whatever - // Check to see whether the movie's natural size has updated - if (mNaturalWidth != mPreviousNaturalWidth || - mNaturalHeight != mPreviousNaturalHeight) + // Check to see whether the movie's NATURAL size has been set yet + if (1 == mNaturalWidth && + 1 == mNaturalHeight) { - mPreviousNaturalWidth = mNaturalWidth; - mPreviousNaturalHeight = mNaturalHeight; + mNaturalWidth = mCurrentWidth; + mNaturalHeight = mCurrentHeight; + DEBUGMSG("Media NATURAL size better detected as %dx%d", + mNaturalWidth, mNaturalHeight); + } + + // if the size has changed then the shm has changed and the app needs telling + if (mCurrentWidth != mPreviousWidth || + mCurrentHeight != mPreviousHeight) + { + mPreviousWidth = mCurrentWidth; + mPreviousHeight = mCurrentHeight; LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); message.setValue("name", mTextureSegmentName); message.setValueS32("width", mNaturalWidth); message.setValueS32("height", mNaturalHeight); - DEBUGMSG("<--- Sending size change request to application with name: '%s' - size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); + DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); sendMessage(message); } - - return true; } @@ -940,10 +951,12 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string) // lame to have to decide this now, it depends on the movie. Oh well. mDepth = 4; + mCurrentWidth = 1; + mCurrentHeight = 1; + mPreviousWidth = 1; + mPreviousHeight = 1; mNaturalWidth = 1; mNaturalHeight = 1; - mPreviousNaturalWidth = 1; - mPreviousNaturalHeight = 1; mWidth = 1; mHeight = 1; mTextureWidth = 1; @@ -984,7 +997,6 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string) INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - } else if(message_name == "shm_remove") { @@ -1063,7 +1075,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string) INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); GST_OBJECT_LOCK(mVideoSink); - mVideoSink->resize_forced = true; + mVideoSink->resize_forced_always = true; mVideoSink->resize_try_width = texture_width; mVideoSink->resize_try_height = texture_height; GST_OBJECT_UNLOCK(mVideoSink); diff --git a/linden/indra/media_plugins/quicktime/CMakeLists.txt b/linden/indra/media_plugins/quicktime/CMakeLists.txt index db11c9ae2..f0b8f0d16 100644 --- a/linden/indra/media_plugins/quicktime/CMakeLists.txt +++ b/linden/indra/media_plugins/quicktime/CMakeLists.txt @@ -56,6 +56,14 @@ add_dependencies(media_plugin_quicktime ${LLCOMMON_LIBRARIES} ) +if (WINDOWS) + set_target_properties( + media_plugin_quicktime + PROPERTIES + LINK_FLAGS "/MANIFEST:NO" + ) +endif (WINDOWS) + if (QUICKTIME) add_definitions(-DLL_QUICKTIME_ENABLED=1) diff --git a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 51cc8dd4f..6c8c41dbb 100644 --- a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -49,6 +49,7 @@ #include "Movies.h" #include "QDoffscreen.h" #include "FixMath.h" + #include "QTLoadLibraryUtils.h" #endif // TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint @@ -72,11 +73,14 @@ class MediaPluginQuickTime : public MediaPluginBase int mCurVolume; bool mMediaSizeChanging; bool mIsLooping; + std::string mMovieTitle; + bool mReceivedTitle; const int mMinWidth; const int mMaxWidth; const int mMinHeight; const int mMaxHeight; F64 mPlayRate; + std::string mNavigateURL; enum ECommand { COMMAND_NONE, @@ -175,6 +179,11 @@ class MediaPluginQuickTime : public MediaPluginBase setStatus(STATUS_ERROR); return; }; + + mNavigateURL = url; + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + message.setValue("uri", mNavigateURL); + sendMessage(message); // do pre-roll actions (typically fired for streaming movies but not always) PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this ); @@ -199,6 +208,9 @@ class MediaPluginQuickTime : public MediaPluginBase bool unload() { + // new movie and have to get title again + mReceivedTitle = false; + if ( mMovieHandle ) { StopMovie( mMovieHandle ); @@ -382,11 +394,18 @@ class MediaPluginQuickTime : public MediaPluginBase static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) { - //MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; + MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref; // TODO: //LLMediaEvent event( self ); //self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); + + // Send a "navigate complete" event. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + message.setValue("uri", self->mNavigateURL); + message.setValueS32("result_code", 200); + message.setValue("result_string", "OK"); + self->sendMessage(message); }; @@ -400,7 +419,7 @@ class MediaPluginQuickTime : public MediaPluginBase { if ( mCommand == COMMAND_PLAY ) { - if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING ) + if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING || mStatus == STATUS_DONE ) { long state = GetMovieLoadState( mMovieHandle ); @@ -426,7 +445,7 @@ class MediaPluginQuickTime : public MediaPluginBase else if ( mCommand == COMMAND_STOP ) { - if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED ) + if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED || mStatus == STATUS_DONE ) { if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) { @@ -508,11 +527,17 @@ class MediaPluginQuickTime : public MediaPluginBase if ( ! mMovieController ) return; - // service QuickTime - // Calling it this way doesn't have good behavior on Windows... -// MoviesTask( mMovieHandle, milliseconds ); - // This was the original, but I think using both MoviesTask and MCIdle is redundant. Trying with only MCIdle. -// MoviesTask( mMovieHandle, 0 ); + // this wasn't required in 1.xx viewer but we have to manually + // work the Windows message pump now + #if defined( LL_WINDOWS ) + MSG msg; + while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + { + GetMessage( &msg, NULL, 0, 0 ); + TranslateMessage( &msg ); + DispatchMessage( &msg ); + }; + #endif MCIdle( mMovieController ); @@ -525,11 +550,14 @@ class MediaPluginQuickTime : public MediaPluginBase // update state machine processState(); - // special code for looping - need to rewind at the end of the movie - if ( mIsLooping ) + // see if title arrived and if so, update member variable with contents + checkTitle(); + + // QT call to see if we are at the end - can't do with controller + if ( IsMovieDone( mMovieHandle ) ) { - // QT call to see if we are at the end - can't do with controller - if ( IsMovieDone( mMovieHandle ) ) + // special code for looping - need to rewind at the end of the movie + if ( mIsLooping ) { // go back to start rewind(); @@ -542,8 +570,16 @@ class MediaPluginQuickTime : public MediaPluginBase // set the volume MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); }; - }; - }; + } + else + { + if(mStatus == STATUS_PLAYING) + { + setStatus(STATUS_DONE); + } + } + } + }; int getDataWidth() const @@ -586,6 +622,19 @@ class MediaPluginQuickTime : public MediaPluginBase }; }; + F64 getLoadedDuration() + { + TimeValue duration; + if(GetMaxLoadedTimeInMovie( mMovieHandle, &duration ) != noErr) + { + // If GetMaxLoadedTimeInMovie returns an error, return the full duration of the movie. + duration = GetMovieDuration( mMovieHandle ); + } + TimeValue scale = GetMovieTimeScale( mMovieHandle ); + + return (F64)duration / (F64)scale; + }; + F64 getDuration() { TimeValue duration = GetMovieDuration( mMovieHandle ); @@ -643,6 +692,77 @@ class MediaPluginQuickTime : public MediaPluginBase { }; + //////////////////////////////////////////////////////////////////////////////// + // Grab movie title into mMovieTitle - should be called repeatedly + // until it returns true since movie title takes a while to become + // available. + const bool getMovieTitle() + { + // grab meta data from movie + QTMetaDataRef media_data_ref; + OSErr result = QTCopyMovieMetaData( mMovieHandle, &media_data_ref ); + if ( noErr != result ) + return false; + + // look up "Display Name" in meta data + OSType meta_data_key = kQTMetaDataCommonKeyDisplayName; + QTMetaDataItem item = kQTMetaDataItemUninitialized; + result = QTMetaDataGetNextItem( media_data_ref, kQTMetaDataStorageFormatWildcard, + 0, kQTMetaDataKeyFormatCommon, + (const UInt8 *)&meta_data_key, + sizeof( meta_data_key ), &item ); + if ( noErr != result ) + return false; + + // find the size of the title + ByteCount size; + result = QTMetaDataGetItemValue( media_data_ref, item, NULL, 0, &size ); + if ( noErr != result || size <= 0 /*|| size > 1024 FIXME: arbitrary limit */ ) + return false; + + // allocate some space and grab it + UInt8* item_data = new UInt8( size + 1 ); + memset( item_data, 0, ( size + 1 ) * sizeof( UInt8* ) ); + result = QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL ); + if ( noErr != result ) + { + delete [] item_data; + return false; + }; + + // save it + if ( strlen( (char*)item_data ) ) + mMovieTitle = std::string( (char* )item_data ); + else + mMovieTitle = ""; + + // clean up + delete [] item_data; + + return true; + }; + + // called regularly to see if title changed + void checkTitle() + { + // we did already receive title so keep checking + if ( ! mReceivedTitle ) + { + // grab title from movie meta data + if ( getMovieTitle() ) + { + // pass back to host application + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", mMovieTitle ); + sendMessage( message ); + + // stop looking once we find a title for this movie. + // TODO: this may to be reset if movie title changes + // during playback but this is okay for now + mReceivedTitle = true; + }; + }; + }; }; MediaPluginQuickTime::MediaPluginQuickTime( @@ -664,6 +784,8 @@ MediaPluginQuickTime::MediaPluginQuickTime( mCurVolume = 0x99; mMediaSizeChanging = false; mIsLooping = false; + mMovieTitle = std::string(); + mReceivedTitle = false; mCommand = COMMAND_NONE; mPlayRate = 0.0f; mStatus = STATUS_NONE; @@ -700,22 +822,29 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; // Normally a plugin would only specify one of these two subclasses, but this is a demo... -// versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; message.setValueLLSD("versions", versions); #ifdef LL_WINDOWS - if ( InitializeQTML( 0L ) != noErr ) + + // QuickTime 7.6.4 has an issue (that was not present in 7.6.2) with initializing QuickTime + // according to this article: http://lists.apple.com/archives/QuickTime-API/2009/Sep/msg00097.html + // The solution presented there appears to work. + QTLoadLibrary("qtcf.dll"); + + // main initialization for QuickTime - only required on Windows + OSErr result = InitializeQTML( 0L ); + if ( result != noErr ) { //TODO: If no QT on Windows, this fails - respond accordingly. - //return false; } else { -// std::cerr << "QuickTime initialized" << std::endl; + //std::cerr << "QuickTime initialized" << std::endl; }; #endif + // required for both Windows and Mac EnterMovies(); std::string plugin_version = "QuickTime media plugin, QuickTime version "; @@ -773,10 +902,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) else if(message_name == "shm_added") { SharedSegmentInfo info; - U64 address_lo = message_in.getValueU32("address"); - U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0; - info.mAddress = (void*)((address_lo) | - (address_hi * (U64(1)<<31))); + info.mAddress = message_in.getValuePointer("address"); info.mSize = (size_t)message_in.getValueS32("size"); std::string name = message_in.getValue("name"); diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index f115c2885..91efdaecb 100644 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -75,6 +75,8 @@ class MediaPluginWebKit : private: + std::string mProfileDir; + enum { INIT_STATE_UNINITIALIZED, // Browser instance hasn't been set up yet @@ -95,6 +97,12 @@ class MediaPluginWebKit : int mLastMouseY; bool mFirstFocus; + void setInitState(int state) + { +// std::cerr << "changing init state to " << state << std::endl; + mInitState = state; + } + //////////////////////////////////////////////////////////////////////////////// // void update(int milliseconds) @@ -186,7 +194,6 @@ class MediaPluginWebKit : #else std::string component_dir = application_dir; #endif - std::string profileDir = application_dir + "/" + "browser_profile"; // cross platform? // window handle - needed on Windows and must be app window. #if LL_WINDOWS @@ -198,7 +205,7 @@ class MediaPluginWebKit : #endif // main browser initialization - bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, profileDir, native_window_handle ); + bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle ); if ( result ) { // create single browser window @@ -208,13 +215,15 @@ class MediaPluginWebKit : // Enable plugins LLQtWebKit::getInstance()->enablePlugins(true); #elif LL_DARWIN - // Disable plugins - LLQtWebKit::getInstance()->enablePlugins(false); + // Enable plugins + LLQtWebKit::getInstance()->enablePlugins(true); #elif LL_LINUX - // Disable plugins - LLQtWebKit::getInstance()->enablePlugins(false); + // Enable plugins + LLQtWebKit::getInstance()->enablePlugins(true); #endif - + // Enable cookies + LLQtWebKit::getInstance()->enableCookies( true ); + // tell LLQtWebKit about the size of the browser window LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); @@ -227,11 +236,11 @@ class MediaPluginWebKit : // don't flip bitmap LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); - // Set the background color to black - mostly for initial login page + // set background color to be black - mostly for initial login page LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, 0x00, 0x00, 0x00 ); // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns. - mInitState = INIT_STATE_NAVIGATING; + setInitState(INIT_STATE_NAVIGATING); // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance. // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially @@ -285,7 +294,7 @@ class MediaPluginWebKit : { if(mInitState == INIT_STATE_WAIT_REDRAW) { - mInitState = INIT_STATE_RUNNING; + setInitState(INIT_STATE_RUNNING); } // flag that an update is required @@ -307,7 +316,7 @@ class MediaPluginWebKit : if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) { - mInitState = INIT_STATE_WAIT_REDRAW; + setInitState(INIT_STATE_WAIT_REDRAW); } } @@ -330,7 +339,7 @@ class MediaPluginWebKit : } else if(mInitState == INIT_STATE_NAVIGATING) { - mInitState = INIT_STATE_NAVIGATE_COMPLETE; + setInitState(INIT_STATE_NAVIGATE_COMPLETE); } } @@ -495,7 +504,16 @@ class MediaPluginWebKit : { // std::cerr << "unicode input, code = 0x" << std::hex << (unsigned long)(wstr[i]) << std::dec << std::endl; - LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, wstr[i], modifiers); + if(wstr[i] == 32) + { + // For some reason, the webkit plugin really wants the space bar to come in through the key-event path, not the unicode path. + LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, 32, modifiers); + LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, 32, modifiers); + } + else + { + LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, wstr[i], modifiers); + } } checkEditState(); @@ -576,6 +594,9 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) { if(message_name == "init") { + std::string user_data_path = message_in.getValue("user_data_path"); // n.b. always has trailing platform-specific dir-delimiter + mProfileDir = user_data_path + "browser_profile"; + LLPluginMessage message("base", "init_response"); LLSD versions = LLSD::emptyMap(); versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; @@ -611,7 +632,11 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) } else if(message_name == "cleanup") { - // TODO: clean up here + // DTOR most likely won't be called but the recent change to the way this process + // is (not) killed means we see this message and can do what we need to here. + // Note: this cleanup is ultimately what writes cookies to the disk + LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this ); + LLQtWebKit::getInstance()->reset(); } else if(message_name == "shm_added") { diff --git a/linden/indra/newview/llviewerparcelmedia.cpp b/linden/indra/newview/llviewerparcelmedia.cpp index c7f0c4bbe..d4ebbd93e 100644 --- a/linden/indra/newview/llviewerparcelmedia.cpp +++ b/linden/indra/newview/llviewerparcelmedia.cpp @@ -193,6 +193,9 @@ void LLViewerParcelMedia::play(LLParcel* parcel) S32 media_width = parcel->getMediaWidth(); S32 media_height = parcel->getMediaHeight(); + // Debug print + // LL_DEBUGS("Media") << "Play media type : " << mime_type << ", url : " << media_url << LL_ENDL; + if(sMediaImpl) { // If the url and mime type are the same, call play again @@ -221,7 +224,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel) sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id, media_width, media_height, media_auto_scale, - media_loop); + media_loop, mime_type); } } else @@ -229,7 +232,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel) // There is no media impl, make a new one sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id, media_width, media_height, media_auto_scale, - media_loop); + media_loop, mime_type); } From c1bfe1d0a5d0cf638a69e308cb0867eb29d6bcb8 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 02:03:07 -0700 Subject: [PATCH 004/239] Added missing glui and freeglut libs on Windows --- linden/install.xml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/linden/install.xml b/linden/install.xml index 21180903c..b43d5aa73 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -516,6 +516,21 @@ </map> </map> </map> + <key>freeglut</key> + <map> + <key>license</key> + <string>mit</string> + <key>packages</key> + <map> + <key>windows</key> + <map> + <key>md5sum</key> + <string>fcbb695ff203775fad96d184bf5f34fc</string> + <key>url</key> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freeglut-2.4.0-windows-20090608.tar.bz2</uri> + </map> + </map> + </map> <key>freetype</key> <map> <key>copyright</key> @@ -634,6 +649,28 @@ </map> </map> </map> + <key>glui</key> + <map> + <key>license</key> + <string>lgpl</string> + <key>packages</key> + <map> + <key>darwin</key> + <map> + <key>md5sum</key> + <string>84f792a860691d0fad6d1de6eeb31baa</string> + <key>url</key> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glui-2.36-darwin-20090623a.tar.bz2</uri> + </map> + <key>windows</key> + <map> + <key>md5sum</key> + <string>5b8631fe510d4ebaeb965c673937e1e7</string> + <key>url</key> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glui-2.3.6-windows-freeglut-20090608.tar.bz2</uri> + </map> + </map> + </map> <key>google</key> <map> <key>license</key> From 02957499966f101c150756047bc97495eda347cd Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 02:03:44 -0700 Subject: [PATCH 005/239] Fixed newview\CMakeLists.txt not parsing on Windows --- linden/indra/newview/CMakeLists.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 15561d03b..aef0b4418 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1415,6 +1415,8 @@ if (LINUX) --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched DEPENDS imprudence-stripped ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) + + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010 media_plugin_webkit) if (NOT INSTALL) add_custom_target(package ALL DEPENDS ${product}.tar.bz2) @@ -1452,8 +1454,8 @@ if (DARWIN) --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010 media_plugin_webkit) + + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) if (PACKAGE) add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME}) @@ -1473,13 +1475,10 @@ if (DARWIN) --build=${CMAKE_CURRENT_BINARY_DIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched - - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_custom_command( TARGET package POST_BUILD COMMAND ${PYTHON_EXECUTABLE} From ac551638773309e865e384d74aff6473c5690ca7 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 14:13:17 -0700 Subject: [PATCH 006/239] Fixed Windows compile error with WIND_BUFFER_SIZE_SEC --- linden/indra/llaudio/llaudioengine_openal.cpp | 2 ++ linden/indra/llaudio/llaudioengine_openal.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/linden/indra/llaudio/llaudioengine_openal.cpp b/linden/indra/llaudio/llaudioengine_openal.cpp index 99ab18e08..93bc42b70 100644 --- a/linden/indra/llaudio/llaudioengine_openal.cpp +++ b/linden/indra/llaudio/llaudioengine_openal.cpp @@ -38,6 +38,8 @@ #include "lllistener_openal.h" +static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec + LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() : mWindGen(NULL), diff --git a/linden/indra/llaudio/llaudioengine_openal.h b/linden/indra/llaudio/llaudioengine_openal.h index 5aca03e19..900bcb32c 100644 --- a/linden/indra/llaudio/llaudioengine_openal.h +++ b/linden/indra/llaudio/llaudioengine_openal.h @@ -73,7 +73,6 @@ class LLAudioEngine_OpenAL : public LLAudioEngine int mNumEmptyWindALBuffers; static const int MAX_NUM_WIND_BUFFERS = 80; - static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec }; class LLAudioChannelOpenAL : public LLAudioChannel From fa2c390b870f5705941e36978b8a31dffb5d26db Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 16:01:42 -0700 Subject: [PATCH 007/239] Fixed CopyWinLibs. Still a bunch of CMake errors and plugins don't load on Windows --- linden/indra/cmake/CopyWinLibs.cmake | 302 ++++++++++-------- ...findra%2fcmake%2fCopyWinLibs.cmake.rej.txt | 257 --------------- 2 files changed, 173 insertions(+), 386 deletions(-) delete mode 100644 linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt diff --git a/linden/indra/cmake/CopyWinLibs.cmake b/linden/indra/cmake/CopyWinLibs.cmake index b544c15d8..72cef0c94 100644 --- a/linden/indra/cmake/CopyWinLibs.cmake +++ b/linden/indra/cmake/CopyWinLibs.cmake @@ -6,6 +6,7 @@ include(CMakeCopyIfDifferent) +# Copying vivox's alut.dll breaks inworld audio, never use it set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-win32") set(vivox_files SLVoice.exe @@ -14,76 +15,20 @@ set(vivox_files ortp.dll wrap_oal.dll ) +copy_if_different( + ${vivox_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/Debug" + out_targets + ${vivox_files} + ) +set(all_targets ${all_targets} ${out_targets}) set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") set(debug_files alut.dll - freebl3.dll - js3250.dll - nspr4.dll - nss3.dll - nssckbi.dll openal32.dll openjpegd.dll libhunspell.dll - plc4.dll - plds4.dll - smime3.dll - softokn3.dll - ssl3.dll - xpcom.dll - xul.dll - windbgdlg.exe - iconv.dll - libxml2.dll - libcairo-2.dll - libfaad-2.dll - libgio-2.0-0.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll - charset.dll - intl.dll - libgcrypt-11.dll - libgnutls-26.dll - libgpg-error-0.dll - libgstapp.dll - libgstaudio.dll - libgstaudio-0.10.dll - libgstbase-0.10.dll - libgstcdda.dll - libgstcontroller-0.10.dll - libgstdataprotocol-0.10.dll - libgstdshow.dll - libgstfft.dll - libgstinterfaces.dll - libgstnet-0.10.dll - libgstnetbuffer.dll - libgstpbutils.dll - libgstreamer-0.10.dll - libgstriff.dll - libgstrtp.dll - libgstrtsp.dll - libgstsdp.dll - libgsttag.dll - libgstvideo.dll - libjpeg.dll - libmp3lame-0.dll - libneon-27.dll - libogg-0.dll - liboil-0.3-0.dll - libopenjpeg-2.dll - libpng12-0.dll - libschroedinger-1.0-0.dll - libspeex-1.dll - libtheora-0.dll - libvorbis-0.dll - libvorbisenc-2.dll - libxml2-2.dll - glew32.dll - xvidcore.dll - zlib1.dll ) copy_if_different( @@ -94,82 +39,180 @@ copy_if_different( ) set(all_targets ${all_targets} ${out_targets}) +# Debug config runtime files required for the plugin test mule +set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") +set(plugintest_debug_files + libeay32.dll + libglib-2.0-0.dll + libgmodule-2.0-0.dll + libgobject-2.0-0.dll + libgthread-2.0-0.dll + qtcored4.dll + qtguid4.dll + qtnetworkd4.dll + qtopengld4.dll + qtwebkitd4.dll + ssleay32.dll + ) copy_if_different( - ${vivox_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Debug" - out_targets - ${vivox_files} + ${plugintest_debug_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug" + out_targets + ${plugintest_debug_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +# Debug config runtime files required for the plugin test mule (Qt image format plugins) +set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug/imageformats") +set(plugintest_debug_files + qgifd4.dll + qicod4.dll + qjpegd4.dll + qmngd4.dll + qsvgd4.dll + qtiffd4.dll + ) +copy_if_different( + ${plugintest_debug_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug/imageformats" + out_targets + ${plugintest_debug_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +copy_if_different( + ${plugintest_debug_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/llplugin/imageformats" + out_targets + ${plugintest_debug_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +# Release & ReleaseDebInfo config runtime files required for the plugin test mule +set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") +set(plugintest_release_files + libeay32.dll + libglib-2.0-0.dll + libgmodule-2.0-0.dll + libgobject-2.0-0.dll + libgthread-2.0-0.dll + qtcore4.dll + qtgui4.dll + qtnetwork4.dll + qtopengl4.dll + qtwebkit4.dll + ssleay32.dll + ) +copy_if_different( + ${plugintest_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release" + out_targets + ${plugintest_release_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +copy_if_different( + ${plugintest_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo" + out_targets + ${plugintest_release_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +# Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins) +set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release/imageformats") +set(plugintest_release_files + qgif4.dll + qico4.dll + qjpeg4.dll + qmng4.dll + qsvg4.dll + qtiff4.dll + ) +copy_if_different( + ${plugintest_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release/imageformats" + out_targets + ${plugintest_release_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +copy_if_different( + ${plugintest_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo/imageformats" + out_targets + ${plugintest_release_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +copy_if_different( + ${plugintest_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin/imageformats" + out_targets + ${plugintest_release_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +copy_if_different( + ${plugintest_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin/imageformats" + out_targets + ${plugintest_release_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +# Debug config runtime files required for the plugins +set(plugins_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") +set(plugins_debug_files + libeay32.dll + qtcored4.dll + qtguid4.dll + qtnetworkd4.dll + qtopengld4.dll + qtwebkitd4.dll + ssleay32.dll + ) +copy_if_different( + ${plugins_debug_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/Debug/llplugin" + out_targets + ${plugins_debug_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +# Release & ReleaseDebInfo config runtime files required for the plugins +set(plugins_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") +set(plugins_release_files + libeay32.dll + qtcore4.dll + qtgui4.dll + qtnetwork4.dll + qtopengl4.dll + qtwebkit4.dll + ssleay32.dll + ) +copy_if_different( + ${plugins_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin" + out_targets + ${plugins_release_files} + ) +set(all_targets ${all_targets} ${out_targets}) + +copy_if_different( + ${plugins_release_src_dir} + "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin" + out_targets + ${plugins_release_files} ) set(all_targets ${all_targets} ${out_targets}) set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") set(release_files alut.dll - freebl3.dll - js3250.dll - nspr4.dll - nss3.dll - nssckbi.dll openal32.dll openjpeg.dll libhunspell.dll - plc4.dll - plds4.dll - smime3.dll - softokn3.dll - ssl3.dll - xpcom.dll - xul.dll - iconv.dll - libxml2.dll - libcairo-2.dll - libfaad-2.dll - libgio-2.0-0.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll - charset.dll - intl.dll - libgcrypt-11.dll - libgnutls-26.dll - libgpg-error-0.dll - libgstapp.dll - libgstaudio.dll - libgstaudio-0.10.dll - libgstbase-0.10.dll - libgstcdda.dll - libgstcontroller-0.10.dll - libgstdataprotocol-0.10.dll - libgstdshow.dll - libgstfft.dll - libgstinterfaces.dll - libgstnet-0.10.dll - libgstnetbuffer.dll - libgstpbutils.dll - libgstreamer-0.10.dll - libgstriff.dll - libgstrtp.dll - libgstrtsp.dll - libgstsdp.dll - libgsttag.dll - libgstvideo.dll - libjpeg.dll - libmp3lame-0.dll - libneon-27.dll - libogg-0.dll - liboil-0.3-0.dll - libopenjpeg-2.dll - libpng12-0.dll - libschroedinger-1.0-0.dll - libspeex-1.dll - libtheora-0.dll - libvorbis-0.dll - libvorbisenc-2.dll - libxml2-2.dll - glew32.dll - xvidcore.dll - zlib1.dll ) copy_if_different( @@ -310,6 +353,7 @@ add_custom_target(copy_win_libs ALL ${relwithdebinfo_appconfig_file} ${debug_appconfig_file} ) +add_dependencies(copy_win_libs prepare) if(EXISTS ${internal_llkdu_path}) add_dependencies(copy_win_libs llkdu) diff --git a/linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt b/linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt deleted file mode 100644 index 295c9fea7..000000000 --- a/linden/indra/cmake/linden%2findra%2fcmake%2fCopyWinLibs.cmake.rej.txt +++ /dev/null @@ -1,257 +0,0 @@ -*************** -*** 15,35 **** - wrap_oal.dll - ) - - set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") - set(debug_files -- freebl3.dll -- js3250.dll -- nspr4.dll -- nss3.dll -- nssckbi.dll -- plc4.dll -- plds4.dll -- smime3.dll -- softokn3.dll -- ssl3.dll -- xpcom.dll -- xul.dll - openjpegd.dll -- windbgdlg.exe - ) - ---- 15,30 ---- - wrap_oal.dll - ) -+ copy_if_different( -+ ${vivox_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/Debug" -+ out_targets -+ ${vivox_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ - - set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") - set(debug_files - openjpegd.dll - ) - -*************** -*** 42,50 **** - set(all_targets ${all_targets} ${out_targets}) - -- copy_if_different( -- ${vivox_src_dir} -- "${CMAKE_CURRENT_BINARY_DIR}/Debug" -- out_targets -- ${vivox_files} - ) - set(all_targets ${all_targets} ${out_targets}) ---- 37,206 ---- - set(all_targets ${all_targets} ${out_targets}) - -+ # Debug config runtime files required for the plugin test mule -+ set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") -+ set(plugintest_debug_files -+ libeay32.dll -+ libglib-2.0-0.dll -+ libgmodule-2.0-0.dll -+ libgobject-2.0-0.dll -+ libgthread-2.0-0.dll -+ qtcored4.dll -+ qtguid4.dll -+ qtnetworkd4.dll -+ qtopengld4.dll -+ qtwebkitd4.dll -+ ssleay32.dll -+ ) -+ copy_if_different( -+ ${plugintest_debug_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug" -+ out_targets -+ ${plugintest_debug_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ # Debug config runtime files required for the plugin test mule (Qt image format plugins) -+ set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug/imageformats") -+ set(plugintest_debug_files -+ qgifd4.dll -+ qicod4.dll -+ qjpegd4.dll -+ qmngd4.dll -+ qsvgd4.dll -+ qtiffd4.dll -+ ) -+ copy_if_different( -+ ${plugintest_debug_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug/imageformats" -+ out_targets -+ ${plugintest_debug_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ copy_if_different( -+ ${plugintest_debug_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/llplugin/imageformats" -+ out_targets -+ ${plugintest_debug_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ # Release & ReleaseDebInfo config runtime files required for the plugin test mule -+ set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") -+ set(plugintest_release_files -+ libeay32.dll -+ libglib-2.0-0.dll -+ libgmodule-2.0-0.dll -+ libgobject-2.0-0.dll -+ libgthread-2.0-0.dll -+ # llkdu.dll (not required for plugin test) -+ qtcore4.dll -+ qtgui4.dll -+ qtnetwork4.dll -+ qtopengl4.dll -+ qtwebkit4.dll -+ ssleay32.dll -+ ) -+ copy_if_different( -+ ${plugintest_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release" -+ out_targets -+ ${plugintest_release_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ copy_if_different( -+ ${plugintest_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo" -+ out_targets -+ ${plugintest_release_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ # Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins) -+ set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release/imageformats") -+ set(plugintest_release_files -+ qgif4.dll -+ qico4.dll -+ qjpeg4.dll -+ qmng4.dll -+ qsvg4.dll -+ qtiff4.dll -+ ) -+ copy_if_different( -+ ${plugintest_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release/imageformats" -+ out_targets -+ ${plugintest_release_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ copy_if_different( -+ ${plugintest_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo/imageformats" -+ out_targets -+ ${plugintest_release_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ copy_if_different( -+ ${plugintest_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin/imageformats" -+ out_targets -+ ${plugintest_release_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ copy_if_different( -+ ${plugintest_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin/imageformats" -+ out_targets -+ ${plugintest_release_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ # Debug config runtime files required for the plugins -+ set(plugins_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") -+ set(plugins_debug_files -+ libeay32.dll -+ qtcored4.dll -+ qtguid4.dll -+ qtnetworkd4.dll -+ qtopengld4.dll -+ qtwebkitd4.dll -+ ssleay32.dll -+ ) -+ copy_if_different( -+ ${plugins_debug_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/Debug/llplugin" -+ out_targets -+ ${plugins_debug_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ # Release & ReleaseDebInfo config runtime files required for the plugins -+ set(plugins_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") -+ set(plugins_release_files -+ libeay32.dll -+ qtcore4.dll -+ qtgui4.dll -+ qtnetwork4.dll -+ qtopengl4.dll -+ qtwebkit4.dll -+ ssleay32.dll -+ ) -+ copy_if_different( -+ ${plugins_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin" -+ out_targets -+ ${plugins_release_files} -+ ) -+ set(all_targets ${all_targets} ${out_targets}) -+ -+ copy_if_different( -+ ${plugins_release_src_dir} -+ "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin" -+ out_targets -+ ${plugins_release_files} - ) - set(all_targets ${all_targets} ${out_targets}) -*************** -*** 52,67 **** - set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") - set(release_files -- freebl3.dll -- js3250.dll -- nspr4.dll -- nss3.dll -- nssckbi.dll -- plc4.dll -- plds4.dll -- smime3.dll -- softokn3.dll -- ssl3.dll -- xpcom.dll -- xul.dll - openjpeg.dll - ) ---- 208,211 ---- - set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") - set(release_files - openjpeg.dll - ) -*************** -*** 252,256 **** - ${debug_appconfig_file} - ) -- add_dependencies(copy_win_libs prepare) - - if(EXISTS ${internal_llkdu_path}) ---- 396,399 ---- - ${debug_appconfig_file} - ) - - if(EXISTS ${internal_llkdu_path}) From 1a8709f9910460a90ac1c2466d99fd0897436554 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 16:08:49 -0700 Subject: [PATCH 008/239] Removed gstreamer and gstreamer-plugins from install.xml for Windows --- linden/install.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index b43d5aa73..99d3bb204 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -720,13 +720,6 @@ <key>url</key> <uri>http://imprudenceviewer.org/download/libs/gstreamer-0.10.24-linux64-20091230.tar.bz2</uri> </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>da6c3fd73a7e5c9bef768edab8a38c2f</string> - <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/gstreamer-0.10.22-windows-20100825.tar.bz2</uri> - </map> </map> </map> <key>gstreamer-plugins</key> @@ -756,13 +749,6 @@ <key>url</key> <uri>http://imprudenceviewer.org/download/libs/gstreamer-plugins-linux64-20100827.tar.bz2</uri> </map> - <key>windows</key> - <map> - <key>md5sum</key> - <string>a5c7e5f2dbd5ed247f6e9c54f03a8b42</string> - <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/gstreamer-plugins-windows-20100825.tar.bz2</uri> - </map> </map> </map> <key>gtk-etc</key> From c8bd2bd6a92ad681fda6b8e142b86f233668c3de Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 16:21:13 -0700 Subject: [PATCH 009/239] Removed 'prepare' dependency from cmake --- linden/indra/cmake/CopyWinLibs.cmake | 1 - linden/indra/llmath/CMakeLists.txt | 1 - linden/indra/llvfs/CMakeLists.txt | 1 - 3 files changed, 3 deletions(-) diff --git a/linden/indra/cmake/CopyWinLibs.cmake b/linden/indra/cmake/CopyWinLibs.cmake index 72cef0c94..2bea40c5a 100644 --- a/linden/indra/cmake/CopyWinLibs.cmake +++ b/linden/indra/cmake/CopyWinLibs.cmake @@ -353,7 +353,6 @@ add_custom_target(copy_win_libs ALL ${relwithdebinfo_appconfig_file} ${debug_appconfig_file} ) -add_dependencies(copy_win_libs prepare) if(EXISTS ${internal_llkdu_path}) add_dependencies(copy_win_libs llkdu) diff --git a/linden/indra/llmath/CMakeLists.txt b/linden/indra/llmath/CMakeLists.txt index c05bf1da4..e5ec3e1aa 100644 --- a/linden/indra/llmath/CMakeLists.txt +++ b/linden/indra/llmath/CMakeLists.txt @@ -83,4 +83,3 @@ set_source_files_properties(${llmath_HEADER_FILES} list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) -add_dependencies(llmath prepare) diff --git a/linden/indra/llvfs/CMakeLists.txt b/linden/indra/llvfs/CMakeLists.txt index d6a0bbc08..25b57e033 100644 --- a/linden/indra/llvfs/CMakeLists.txt +++ b/linden/indra/llvfs/CMakeLists.txt @@ -57,7 +57,6 @@ set_source_files_properties(${llvfs_HEADER_FILES} list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES}) add_library (llvfs ${llvfs_SOURCE_FILES}) -add_dependencies(llvfs prepare) if (DARWIN) include(CMakeFindFrameworks) From 53c622976519614eea6a46a5c9b3e938482b170f Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 17:03:10 -0700 Subject: [PATCH 010/239] Added missing plugins notifications --- .../skins/default/xui/en-us/notifications.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/linden/indra/newview/skins/default/xui/en-us/notifications.xml b/linden/indra/newview/skins/default/xui/en-us/notifications.xml index d7b078ceb..b439dbad2 100644 --- a/linden/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/linden/indra/newview/skins/default/xui/en-us/notifications.xml @@ -5556,7 +5556,25 @@ Apple's QuickTime software does not appear to be installed on your system. If you want to view streaming media on parcels that support it you should go to the QuickTime site (http://www.apple.com/quicktime) and install the QuickTime Player. </notification> +<notification + icon="notify.tga" + name="NoPlugin" + type="notify"> +No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable. +</notification> +<notification + icon="alertmodal.tga" + name="MediaPluginFailed" + type="alertmodal"> +The following Media Plugin has failed: +[PLUGIN] +Please re-install the plugin or contact the vendor if you continue to experience problems. + <form name="form"> + <ignore name="ignore" + text="When a Media Plugin fails"/> + </form> +</notification> <notification icon="notify.tga" name="OwnedObjectsReturned" From 891b747e8b6aa0b9e4a99311804438b37c8c05b4 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 17:59:58 -0700 Subject: [PATCH 011/239] CMake now runs correctly on Windows --- linden/indra/cmake/ExamplePlugin.cmake | 16 ++++++++++++++++ linden/indra/llplugin/CMakeLists.txt | 8 ++++++++ 2 files changed, 24 insertions(+) create mode 100644 linden/indra/cmake/ExamplePlugin.cmake diff --git a/linden/indra/cmake/ExamplePlugin.cmake b/linden/indra/cmake/ExamplePlugin.cmake new file mode 100644 index 000000000..599787ad2 --- /dev/null +++ b/linden/indra/cmake/ExamplePlugin.cmake @@ -0,0 +1,16 @@ +# -*- cmake -*- +include(Linking) +include(Prebuilt) + +if (STANDALONE) + set(EXAMPLEPLUGIN OFF CACHE BOOL + "EXAMPLEPLUGIN support for the llplugin/llmedia test apps.") +else (STANDALONE) + set(EXAMPLEPLUGIN ON CACHE BOOL + "EXAMPLEPLUGIN support for the llplugin/llmedia test apps.") +endif (STANDALONE) + +if (WINDOWS) +elseif (DARWIN) +elseif (LINUX) +endif (WINDOWS) diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt index 6706775d4..e41cdf71b 100644 --- a/linden/indra/llplugin/CMakeLists.txt +++ b/linden/indra/llplugin/CMakeLists.txt @@ -48,6 +48,14 @@ set(llplugin_HEADER_FILES set_source_files_properties(${llplugin_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) +if(WORD_SIZE EQUAL 64) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif (WORD_SIZE EQUAL 64) + list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) From df82325063d61b92cac749c11b7057abf7d769e8 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 18:00:34 -0700 Subject: [PATCH 012/239] Removed some bad merge entries from newview/CMakeLists.txt --- linden/indra/newview/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index aef0b4418..b576ccde6 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1139,8 +1139,6 @@ set(viewer_XUI_FILES ) -list(APPEND viewer_XUI_FILES ${viewer_XUI_FILE_GLOB_LIST}) -list(SORT viewer_XUI_FILES) list(APPEND viewer_XUI_FILES ${viewer_XUI_FILE_GLOB_LIST}) list(SORT viewer_XUI_FILES) From 092fda55d8537e7655a545634e443c6c6c3dde0b Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 18:01:44 -0700 Subject: [PATCH 013/239] Added fix for word size from Snowglobe (only for Windows--didn't update Linux or Mac as I can't test them) --- linden/indra/cmake/Variables.cmake | 1 + .../indra/llplugin/llpluginsharedmemory.cpp | 7 ++++++ linden/indra/media_plugins/CMakeLists.txt | 2 ++ .../indra/media_plugins/base/CMakeLists.txt | 8 ++++++ .../media_plugins/example/CMakeLists.txt | 10 +++++++- .../media_plugins/quicktime/CMakeLists.txt | 3 ++- .../indra/media_plugins/webkit/CMakeLists.txt | 25 ++++++++++++++----- 7 files changed, 48 insertions(+), 8 deletions(-) diff --git a/linden/indra/cmake/Variables.cmake b/linden/indra/cmake/Variables.cmake index 5d4dffe19..cd5bfc191 100644 --- a/linden/indra/cmake/Variables.cmake +++ b/linden/indra/cmake/Variables.cmake @@ -45,6 +45,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(ARCH i686) set(LL_ARCH ${ARCH}_win32) set(LL_ARCH_DIR ${ARCH}-win32) + set(WORD_SIZE 32) endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp index 2be46481d..c9466191e 100644 --- a/linden/indra/llplugin/llpluginsharedmemory.cpp +++ b/linden/indra/llplugin/llpluginsharedmemory.cpp @@ -34,6 +34,13 @@ #include "llpluginsharedmemory.h" +#if LL_WINDOWS +#include <process.h> +#else // LL_WINDOWS +#include <sys/types.h> +#include <unistd.h> +#endif // LL_WINDOWS + // on Mac and Linux, we use the native shm_open/mmap interface by using // #define USE_SHM_OPEN_SHARED_MEMORY 1 // in the appropriate sections below. diff --git a/linden/indra/media_plugins/CMakeLists.txt b/linden/indra/media_plugins/CMakeLists.txt index d35afd8cb..cc03d9cb7 100644 --- a/linden/indra/media_plugins/CMakeLists.txt +++ b/linden/indra/media_plugins/CMakeLists.txt @@ -9,3 +9,5 @@ add_subdirectory(gstreamer010) if (WINDOWS OR DARWIN) add_subdirectory(quicktime) endif (WINDOWS OR DARWIN) + +add_subdirectory(example) diff --git a/linden/indra/media_plugins/base/CMakeLists.txt b/linden/indra/media_plugins/base/CMakeLists.txt index f8d2dabc6..a3ee02eaa 100644 --- a/linden/indra/media_plugins/base/CMakeLists.txt +++ b/linden/indra/media_plugins/base/CMakeLists.txt @@ -25,6 +25,14 @@ include_directories( ### media_plugin_base +if(WORD_SIZE EQUAL 64) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif (WORD_SIZE EQUAL 64) + set(media_plugin_base_SOURCE_FILES media_plugin_base.cpp ) diff --git a/linden/indra/media_plugins/example/CMakeLists.txt b/linden/indra/media_plugins/example/CMakeLists.txt index 4d82f2747..b074a1d20 100644 --- a/linden/indra/media_plugins/example/CMakeLists.txt +++ b/linden/indra/media_plugins/example/CMakeLists.txt @@ -29,6 +29,14 @@ include_directories( ### media_plugin_example +if(WORD_SIZE EQUAL 64) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif (WORD_SIZE EQUAL 64) + set(media_plugin_example_SOURCE_FILES media_plugin_example.cpp ) @@ -71,4 +79,4 @@ if (DARWIN) LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" ) -endif (DARWIN) \ No newline at end of file +endif (DARWIN) diff --git a/linden/indra/media_plugins/quicktime/CMakeLists.txt b/linden/indra/media_plugins/quicktime/CMakeLists.txt index f0b8f0d16..df191f543 100644 --- a/linden/indra/media_plugins/quicktime/CMakeLists.txt +++ b/linden/indra/media_plugins/quicktime/CMakeLists.txt @@ -60,7 +60,8 @@ if (WINDOWS) set_target_properties( media_plugin_quicktime PROPERTIES - LINK_FLAGS "/MANIFEST:NO" + LINK_FLAGS "/MANIFEST:NO /NODEFAULTLIB:LIBCMT" + LINK_FLAGS_DEBUG "/MANIFEST:NO /NODEFAULTLIB:\"LIBCMT;LIBCMTD\"" ) endif (WINDOWS) diff --git a/linden/indra/media_plugins/webkit/CMakeLists.txt b/linden/indra/media_plugins/webkit/CMakeLists.txt index 5bccd589d..54bc3644c 100644 --- a/linden/indra/media_plugins/webkit/CMakeLists.txt +++ b/linden/indra/media_plugins/webkit/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( ${LLIMAGE_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} + ${LLQTWEBKIT_INCLUDE_DIR} ) @@ -33,12 +34,15 @@ set(media_plugin_webkit_SOURCE_FILES media_plugin_webkit.cpp ) -add_library(media_plugin_webkit - SHARED - ${media_plugin_webkit_SOURCE_FILES} -) +if(WORD_SIZE EQUAL 64) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif (WORD_SIZE EQUAL 64) -target_link_libraries(media_plugin_webkit +set(media_plugin_webkit_LINK_LIBRARIES ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} ${LLCOMMON_LIBRARIES} @@ -46,6 +50,15 @@ target_link_libraries(media_plugin_webkit ${PLUGIN_API_WINDOWS_LIBRARIES} ) + + +add_library(media_plugin_webkit + SHARED + ${media_plugin_webkit_SOURCE_FILES} +) + +target_link_libraries(media_plugin_webkit ${media_plugin_webkit_LINK_LIBRARIES}) + add_dependencies(media_plugin_webkit ${LLPLUGIN_LIBRARIES} ${MEDIA_PLUGIN_BASE_LIBRARIES} @@ -79,4 +92,4 @@ if (DARWIN) DEPENDS media_plugin_webkit ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ) -endif (DARWIN) \ No newline at end of file +endif (DARWIN) From 0df07dde8df981c1c7ffac1aea5977dbbb386354 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 22:57:19 -0700 Subject: [PATCH 014/239] Fixed llvewermedia version info (and kept it disabled unless there's a good reason for enabling it) --- linden/indra/newview/llviewermedia.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 92ccf2597..5bdb26f04 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -40,6 +40,7 @@ #include "llviewerimage.h" #include "llviewerwindow.h" #include "llviewerimagelist.h" +//#include "viewerversion.h" #include "llpluginclassmedia.h" @@ -241,13 +242,15 @@ LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& textur // static std::string LLViewerMedia::getCurrentUserAgent() { + // Don't include version, channel, or skin -- MC + // Don't use user-visible string to avoid // punctuation and strange characters. - std::string skin_name = gSavedSettings.getString("SkinCurrent"); + //std::string skin_name = gSavedSettings.getString("SkinCurrent"); // Just in case we need to check browser differences in A/B test // builds. - std::string channel = gSavedSettings.getString("VersionChannelName"); + //std::string channel = gSavedSettings.getString("VersionChannelName"); // append our magic version number string to the browser user agent id // See the HTTP 1.0 and 1.1 specifications for allowed formats: @@ -257,9 +260,9 @@ std::string LLViewerMedia::getCurrentUserAgent() // http://www.mozilla.org/build/revised-user-agent-strings.html std::ostringstream codec; codec << "SecondLife/"; - codec << "C64 Basic V2"; //imprudence fixme : this isn't anybodys business anyway -// codec << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; -// codec << " (" << channel << "; " << skin_name << " skin)"; + codec << "C64 Basic V2"; + //codec << ViewerVersion::getImpMajorVersion() << "." << ViewerVersion::getImpMinorVersion() << "." << ViewerVersion::getImpPatchVersion() << " " << ViewerVersion::getImpTestVersion(); + //codec << " (" << channel << "; " << skin_name << " skin)"; // llinfos << codec.str() << llendl; return codec.str(); From 811e2d201bef3dd946e415789676c65e7833f80e Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 22:57:54 -0700 Subject: [PATCH 015/239] Fixed floatervicelicense not compiling with the new media changes --- linden/indra/newview/floatervoicelicense.cpp | 31 +++++++++----------- linden/indra/newview/floatervoicelicense.h | 11 +++---- linden/indra/newview/llfirstuse.cpp | 4 +-- linden/indra/newview/llprefsvoice.cpp | 4 +-- linden/indra/newview/llwebbrowserctrl.h | 1 - 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/linden/indra/newview/floatervoicelicense.cpp b/linden/indra/newview/floatervoicelicense.cpp index 74d16c35d..0697b5c71 100644 --- a/linden/indra/newview/floatervoicelicense.cpp +++ b/linden/indra/newview/floatervoicelicense.cpp @@ -27,7 +27,7 @@ * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ -/* + #include "llviewerprecompiledheaders.h" #include "floatervoicelicense.h" @@ -122,7 +122,7 @@ BOOL FloaterVoiceLicense::postBuild() LLTextEditor *editor = getChild<LLTextEditor>("license_text"); editor->setVisible( FALSE ); - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("license_html"); + LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("license_html"); if ( web_browser ) { // start to observe it so we see navigate complete events @@ -137,7 +137,7 @@ BOOL FloaterVoiceLicense::postBuild() void FloaterVoiceLicense::setSiteIsAlive( bool alive ) { - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("license_html"); + LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("license_html"); // if the contents of the site was retrieved if ( alive ) { @@ -158,12 +158,6 @@ void FloaterVoiceLicense::setSiteIsAlive( bool alive ) FloaterVoiceLicense::~FloaterVoiceLicense() { - // stop observing events - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("license_html"); - if ( web_browser ) - { - web_browser->remObserver( this ); - } // tell the responder we're not here anymore if ( gResponsePtr ) @@ -224,14 +218,17 @@ void FloaterVoiceLicense::onCancel( void* userdata ) } //virtual -void FloaterVoiceLicense::onNavigateComplete( const EventType& eventIn ) +void FloaterVoiceLicense::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event) { - // skip past the loading screen navigate complete - if ( ++mLoadCompleteCount == 2 ) + if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) { - llinfos << "NAVIGATE COMPLETE" << llendl; - // enable Agree to License radio button now that page has loaded - LLCheckBoxCtrl * license_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); - license_agreement->setEnabled( true ); + // skip past the loading screen navigate complete + if ( ++mLoadCompleteCount == 2 ) + { + llinfos << "NAVIGATE COMPLETE" << llendl; + // enable Agree to License radio button now that page has loaded + LLCheckBoxCtrl * license_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); + license_agreement->setEnabled( true ); + } } -}*/ +} diff --git a/linden/indra/newview/floatervoicelicense.h b/linden/indra/newview/floatervoicelicense.h index 9d2012d46..30dbb2fa3 100644 --- a/linden/indra/newview/floatervoicelicense.h +++ b/linden/indra/newview/floatervoicelicense.h @@ -35,8 +35,8 @@ #include "llmodaldialog.h" #include "llassetstorage.h" -//imprudence fixme: removed for media plugins #include "llwebbrowserctrl.h" -/* +#include "llmediactrl.h" + class LLButton; class LLRadioGroup; class LLVFS; @@ -45,7 +45,7 @@ class LLUUID; class FloaterVoiceLicense : public LLModalDialog, - public LLViewerMediaObserver + public LLViewerMediaObserver, public LLFloaterSingleton<FloaterVoiceLicense> { public: @@ -62,11 +62,12 @@ class FloaterVoiceLicense : void setSiteIsAlive( bool alive ); - virtual void onNavigateComplete( const EventType& eventIn ); + // inherited from LLViewerMediaObserver + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); private: int mWebBrowserWindowId; int mLoadCompleteCount; -};*/ +}; #endif // FLOATERVOICELICENSE_H diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp index ca8614c23..e82aa96a0 100644 --- a/linden/indra/newview/llfirstuse.cpp +++ b/linden/indra/newview/llfirstuse.cpp @@ -397,8 +397,8 @@ void LLFirstUse::voiceLicenseAgreement() { gSavedSettings.setWarning("FirstVoiceLicense", FALSE); -// imprudence fixme FloaterVoiceLicense::getInstance()->open(); -// FloaterVoiceLicense::getInstance()->center(); + FloaterVoiceLicense::getInstance()->open(); + FloaterVoiceLicense::getInstance()->center(); } else // currently in STATE_LOGIN_VOICE_LICENSE when arriving here { diff --git a/linden/indra/newview/llprefsvoice.cpp b/linden/indra/newview/llprefsvoice.cpp index 609d30a13..7c50f4acd 100644 --- a/linden/indra/newview/llprefsvoice.cpp +++ b/linden/indra/newview/llprefsvoice.cpp @@ -153,8 +153,8 @@ void LLPrefsVoice::apply() if (enable_voice && !gSavedSettings.getBOOL("VivoxLicenseAccepted")) { // This window enables voice chat if license is accepted -//imprudence fixme FloaterVoiceLicense::getInstance()->open(); -//imprudence fixme FloaterVoiceLicense::getInstance()->center(); + FloaterVoiceLicense::getInstance()->open(); + FloaterVoiceLicense::getInstance()->center(); } else { diff --git a/linden/indra/newview/llwebbrowserctrl.h b/linden/indra/newview/llwebbrowserctrl.h index 010080734..79b89425d 100644 --- a/linden/indra/newview/llwebbrowserctrl.h +++ b/linden/indra/newview/llwebbrowserctrl.h @@ -106,7 +106,6 @@ class LLWebBrowserCtrlObserver #include "lluictrl.h" #include "llframetimer.h" #include "lldynamictexture.h" -#include "llmediamanager.h" #include "llmediaobserver.h" class LLViewBorder; From 12810aeb0cc9c252d9295101d06dd0eb8711d8c6 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Tue, 7 Sep 2010 23:35:39 -0700 Subject: [PATCH 016/239] Fixed 'there is no media type for text/html' errors --- linden/indra/newview/llmimetypes.cpp | 18 + .../skins/default/xui/en-us/mime_types.xml | 451 ++++++++++++++++++ 2 files changed, 469 insertions(+) diff --git a/linden/indra/newview/llmimetypes.cpp b/linden/indra/newview/llmimetypes.cpp index 525e89cdf..c45e0abf5 100644 --- a/linden/indra/newview/llmimetypes.cpp +++ b/linden/indra/newview/llmimetypes.cpp @@ -56,6 +56,24 @@ bool LLMIMETypes::parseMIMETypes(const std::string& xml_filename) { LLXMLNodePtr root; bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + + if (!success) + { + // If fails, check if we can read the file from the app_settings folder + std::string settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, xml_filename); + success = LLUICtrlFactory::getLayeredXMLNode(settings_filename, root); + + #if LL_WINDOWS + // On the windows dev builds, unpackaged, the mime_types.xml file will be located in + // indra/build-vc**/newview/<config>/app_settings. + if (!success) + { + settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", xml_filename); + success = LLUICtrlFactory::getLayeredXMLNode(settings_filename, root); + } + #endif + } + if ( ! success || root.isNull() || ! root->hasName( "mimetypes" ) ) { llwarns << "Unable to read MIME type file: " diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml index e69de29bb..9f0c631df 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml @@ -0,0 +1,451 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<mimetypes name="default"> + <defaultlabel> + (Unknown) + </defaultlabel> + <defaultwidget> + none + </defaultwidget> + <defaultimpl> + media_plugin_webkit + </defaultimpl> + <widgetset name="web"> + <label name="web_label"> + Web Content + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + text/html + </default_type> + <tooltip name="web_tooltip"> + This location has Web content + </tooltip> + <playtip name="web_playtip"> + Show Web content + </playtip> + <allow_resize> + true + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="movie"> + <label name="movie_label"> + Movie + </label> + <default_type> + video/* + </default_type> + <icon> + icn_media_movie.tga + </icon> + <tooltip name="movie_tooltip"> + There is a movie to play here + </tooltip> + <playtip name="movie_playtip"> + Play movie + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <widgetset name="image"> + <label name="image_label"> + Image + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + image/* + </default_type> + <tooltip name="image_tooltip"> + There is an image at this location + </tooltip> + <playtip name="image_playtip"> + View this location's image + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + false + </allow_looping> + </widgetset> + <widgetset name="audio"> + <label name="audio_label"> + Audio + </label> + <icon> + icn_media_web.tga + </icon> + <default_type> + audio/* + </default_type> + <tooltip name="audio_tooltip"> + There is audio at this location + </tooltip> + <playtip name="audio_playtip"> + Play this location's audio + </playtip> + <allow_resize> + false + </allow_resize> + <allow_looping> + true + </allow_looping> + </widgetset> + <scheme name="rtsp"> + <label name="rtsp_label"> + Real Time Streaming + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </scheme> + <mimetype name="blank"> + <label name="blank_label"> + - None - + </label> + <widgettype> + none + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="none/none"> + <label name="none/none_label"> + - None - + </label> + <widgettype> + none + </widgettype> + </mimetype> + <mimetype name="audio/*"> + <label name="audio2_label"> + Audio + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/*"> + <label name="video2_label"> + Video + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="image/*"> + <label name="image2_label"> + Image + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> + <label name="vnd.secondlife.qt.legacy_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="application/javascript"> + <label name="application/javascript_label"> + Javascript + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/ogg"> + <label name="application/ogg_label"> + Ogg Audio/Video + </label> + <widgettype> + audio + </widgettype> + </mimetype> + <mimetype name="application/pdf"> + <label name="application/pdf_label"> + PDF Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/postscript"> + <label name="application/postscript_label"> + Postscript Document + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/rtf"> + <label name="application/rtf_label"> + Rich Text (RTF) + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="application/smil"> + <label name="application/smil_label"> + Synchronized Multimedia Integration Language (SMIL) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="application/xhtml+xml"> + <label name="application/xhtml+xml_label"> + Web Page (XHTML) + </label> + <widgettype> + web + </widgettype> + </mimetype> + <mimetype name="application/x-director"> + <label name="application/x-director_label"> + Macromedia Director + </label> + <widgettype> + image + </widgettype> + </mimetype> + <mimetype name="audio/mid"> + <label name="audio/mid_label"> + Audio (MIDI) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/mpeg"> + <label name="audio/mpeg_label"> + Audio (MP3) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/x-aiff"> + <label name="audio/x-aiff_label"> + Audio (AIFF) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="audio/x-wav"> + <label name="audio/x-wav_label"> + Audio (WAV) + </label> + <widgettype> + audio + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="image/bmp"> + <label name="image/bmp_label"> + Image (BMP) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/gif"> + <label name="image/gif_label"> + Image (GIF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/jpeg"> + <label name="image/jpeg_label"> + Image (JPEG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/png"> + <label name="image/png_label"> + Image (PNG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="image/svg+xml"> + <label name="image/svg+xml_label"> + Image (SVG) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="image/tiff"> + <label name="image/tiff_label"> + Image (TIFF) + </label> + <widgettype> + image + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/html"> + <label name="text/html_label"> + Web Page + </label> + <widgettype> + web + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="text/plain"> + <label name="text/plain_label"> + Text + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype name="text/xml"> + <label name="text/xml_label"> + XML + </label> + <widgettype> + text + </widgettype> + <impl> + media_plugin_webkit + </impl> + </mimetype> + <mimetype menu="1" name="video/mpeg"> + <label name="video/mpeg_label"> + Movie (MPEG) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/mp4"> + <label name="video/mp4_label"> + Movie (MP4) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/x-ms-asf"> + <label name="video/x-ms-asf_label"> + Movie (Windows Media ASF) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype name="video/x-ms-wmv"> + <label name="video/x-ms-wmv_label"> + Movie (Windows Media WMV) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> + <mimetype menu="1" name="video/x-msvideo"> + <label name="video/x-msvideo_label"> + Movie (AVI) + </label> + <widgettype> + movie + </widgettype> + <impl> + media_plugin_quicktime + </impl> + </mimetype> +</mimetypes> From ca628a8d0bf76872cc5b7e9a3d67dc37ea554cb7 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Sat, 20 Feb 2010 18:36:56 +0100 Subject: [PATCH 017/239] remove deprecated files --- linden/indra/newview/llfloaterhtml.cpp | 1 - linden/indra/newview/llwebbrowserctrl.cpp | 1068 --------------------- linden/indra/newview/llwebbrowserctrl.h | 325 ------- 3 files changed, 1394 deletions(-) delete mode 100644 linden/indra/newview/llwebbrowserctrl.cpp delete mode 100644 linden/indra/newview/llwebbrowserctrl.h diff --git a/linden/indra/newview/llfloaterhtml.cpp b/linden/indra/newview/llfloaterhtml.cpp index a5d24f4d8..5822ed5b4 100644 --- a/linden/indra/newview/llfloaterhtml.cpp +++ b/linden/indra/newview/llfloaterhtml.cpp @@ -41,7 +41,6 @@ #include "llviewerwindow.h" #include "llweb.h" -#include "llwebbrowserctrl.h" LLFloaterHtml* LLFloaterHtml::sInstance = 0; diff --git a/linden/indra/newview/llwebbrowserctrl.cpp b/linden/indra/newview/llwebbrowserctrl.cpp deleted file mode 100644 index 453b9d297..000000000 --- a/linden/indra/newview/llwebbrowserctrl.cpp +++ /dev/null @@ -1,1068 +0,0 @@ -/** - * @file llwebbrowserctrl.cpp - * @brief Web browser UI control - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - - -#include "llwebbrowserctrl.h" - -// viewer includes -#include "llfloaterhtml.h" -#include "llfloaterworldmap.h" -#include "lluictrlfactory.h" -#include "llurldispatcher.h" -#include "llurlsimstring.h" -#include "llviewborder.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" -#include "llnotifications.h" -#include "llweb.h" -#include "llrender.h" - -// linden library includes -#include "llfocusmgr.h" - -extern BOOL gRestoreGL; - -// Setting the mozilla buffer width to 2048 exactly doesn't work, since it pads its rowbytes a bit, pushing the texture width over 2048. -// 2000 should give enough headroom for any amount of padding it cares to add. -const S32 MAX_DIMENSION = 2000; -const S32 MAX_TEXTURE_DIMENSION = 2048; - -static LLRegisterWidget<LLWebBrowserCtrl> r("web_browser"); - -LLWebBrowserCtrl::LLWebBrowserCtrl( const std::string& name, const LLRect& rect ) : - LLUICtrl( name, rect, FALSE, NULL, NULL ), - mTextureDepthBytes( 4 ), - mWebBrowserImage( 0 ), - mEmbeddedBrowserWindowId( 0 ), - mBorder(NULL), - mFrequentUpdates( true ), - mForceUpdate( false ), - mOpenLinksInExternalBrowser( false ), - mOpenLinksInInternalBrowser( false ), - mTrusted( false ), - mHomePageUrl( "" ), - mIgnoreUIScale( true ), - mAlwaysRefresh( false ), - mExternalUrl( "" ), - mMediaSource( 0 ), - mTakeFocusOnClick( true ), - mCurrentNavUrl( "about:blank" ) -{ - S32 screen_width = mIgnoreUIScale ? - llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth(); - S32 screen_height = mIgnoreUIScale ? - llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight(); - - - LLMediaManager *mgr = LLMediaManager::getInstance(); - - if (!mgr) - { - llwarns << "cannot get media manager" << llendl; - return; - } - - mMediaSource = mgr->createSourceFromMimeType("http", "text/html" ); - if ( !mMediaSource ) - { - llwarns << "media source create failed " << llendl; - // return; - } - else - { - - // mMediaSource->init(); - mMediaSource->addCommand( LLMediaBase::COMMAND_START ); - - // observe the browser so we can trap HREF events) - mMediaSource->addObserver(this); - - // create a new texture (based on LLDynamic texture) that will be used to display the output - mWebBrowserImage = new LLWebBrowserTexture( screen_width, screen_height, this, mMediaSource ); - } - - LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); - mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN ); - addChild( mBorder ); -} - -//////////////////////////////////////////////////////////////////////////////// -// note: this is now a singleton and destruction happens via initClass() now -LLWebBrowserCtrl::~LLWebBrowserCtrl() -{ - LLMediaManager *mgr = LLMediaManager::getInstance(); - - if (!mgr) - { - llwarns << "cannot get media manager" << llendl; - return; - } - - if (mMediaSource) - { - mgr->destroySource(mMediaSource); - mMediaSource = NULL; - } - - if ( mWebBrowserImage ) - { - delete mWebBrowserImage; - mWebBrowserImage = 0; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLWebBrowserCtrl::addObserver( LLWebBrowserCtrlObserver* subjectIn ) -{ - return mEventEmitter.addObserver( subjectIn ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLWebBrowserCtrl::remObserver( LLWebBrowserCtrlObserver* subjectIn ) -{ - return mEventEmitter.remObserver( subjectIn ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::setBorderVisible( BOOL border_visible ) -{ - if ( mBorder ) - { - mBorder->setVisible( border_visible ); - }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::setTakeFocusOnClick( bool take_focus ) -{ - mTakeFocusOnClick = take_focus; -} - -//////////////////////////////////////////////////////////////////////////////// -// set flag that forces the embedded browser to open links in the external system browser -void LLWebBrowserCtrl::setOpenInExternalBrowser( bool valIn ) -{ - mOpenLinksInExternalBrowser = valIn; -}; - -//////////////////////////////////////////////////////////////////////////////// -// set flag that forces the embedded browser to open links in the internal browser floater -void LLWebBrowserCtrl::setOpenInInternalBrowser( bool valIn ) -{ - mOpenLinksInInternalBrowser = valIn; -}; - -//////////////////////////////////////////////////////////////////////////////// -void LLWebBrowserCtrl::setTrusted( bool valIn ) -{ - mTrusted = valIn; -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserCtrl::handleHover( S32 x, S32 y, MASK mask ) -{ - convertInputCoords(x, y); - - if (mMediaSource) - mMediaSource->mouseMove(x, y); - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) -{ - if (mMediaSource) - mMediaSource->scrollByLines(clicks); - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - convertInputCoords(x, y); - - if (mMediaSource) - { - mMediaSource->mouseUp(x, y); - - // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, - // in addition to the onFocusReceived() call below. Undo this. JC - if (!mTakeFocusOnClick) - { - mMediaSource->focus(false); - gViewerWindow->focusClient(); - } - } - - gFocusMgr.setMouseCapture( NULL ); - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - convertInputCoords(x, y); - - if (mMediaSource) - mMediaSource->mouseDown(x, y); - - gFocusMgr.setMouseCapture( this ); - - if (mTakeFocusOnClick) - { - setFocus( TRUE ); - } - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - convertInputCoords(x, y); - - if (mMediaSource) - mMediaSource->mouseLeftDoubleClick( x, y ); - - gFocusMgr.setMouseCapture( this ); - - if (mTakeFocusOnClick) - { - setFocus( TRUE ); - } - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::onFocusReceived() -{ - if (mMediaSource) - mMediaSource->focus(true); - - - LLUICtrl::onFocusReceived(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::onFocusLost() -{ - if (mMediaSource) - mMediaSource->focus(false); - - gViewerWindow->focusClient(); - - LLUICtrl::onFocusLost(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserCtrl::handleKeyHere( KEY key, MASK mask ) -{ - unsigned long media_key; - - // First, turn SL internal keycode enum into Mozilla keycode enum - - // We don't have to deal with printable characters here - they should - // go through handleUnicodeChar(). This table could be more complete - // than it is, but I think this covers all of the important - // non-printables. - - switch (key) - { - case KEY_BACKSPACE: - media_key = LL_MEDIA_KEY_BACKSPACE; break; - case KEY_TAB: - media_key = LL_MEDIA_KEY_TAB; break; - case KEY_RETURN: - media_key = LL_MEDIA_KEY_RETURN; break; - case KEY_PAD_RETURN: - media_key = LL_MEDIA_KEY_PAD_RETURN; break; - case KEY_ESCAPE: - media_key = LL_MEDIA_KEY_ESCAPE; break; - case KEY_PAGE_UP: - media_key = LL_MEDIA_KEY_PAGE_UP; break; - case KEY_PAGE_DOWN: - media_key = LL_MEDIA_KEY_PAGE_DOWN; break; - case KEY_END: - media_key = LL_MEDIA_KEY_END; break; - case KEY_HOME: - media_key = LL_MEDIA_KEY_HOME; break; - case KEY_LEFT: - media_key = LL_MEDIA_KEY_LEFT; break; - case KEY_UP: - media_key = LL_MEDIA_KEY_UP; break; - case KEY_RIGHT: - media_key = LL_MEDIA_KEY_RIGHT; break; - case KEY_DOWN: - media_key = LL_MEDIA_KEY_DOWN; break; - case KEY_INSERT: - media_key = LL_MEDIA_KEY_INSERT; break; - case KEY_DELETE: - media_key = LL_MEDIA_KEY_DELETE; break; - default: - llinfos << "Don't know how to map LL keycode " << U32(key) - << " to DOM key. Ignoring." << llendl; - return FALSE; // don't know how to map this key. - } - - if (mMediaSource) - mMediaSource->keyPress(media_key); - - return TRUE; -} - -BOOL LLWebBrowserCtrl::handleUnicodeCharHere(llwchar uni_char) -{ - // only accept 'printable' characters, sigh... - if (uni_char >= 32 // discard 'control' characters - && uni_char != 127) // SDL thinks this is 'delete' - yuck. - { - if (mMediaSource) - mMediaSource->unicodeInput(uni_char); - } - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::onVisibilityChange ( BOOL new_visibility ) -{ - // set state of frequent updates automatically if visibility changes - if ( new_visibility ) - { - mFrequentUpdates = true; - } - else - { - mFrequentUpdates = false; - } - LLUICtrl::onVisibilityChange(new_visibility); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) -{ - S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width; - S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height; - - // when floater is minimized, these sizes are negative - if ( mWebBrowserImage && screen_height > 0 && screen_width > 0 ) - { - mWebBrowserImage->resize( screen_width, screen_height ); - mForceUpdate = true; - } - - LLUICtrl::reshape( width, height, called_from_parent ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::navigateBack() -{ - if (mMediaSource) - mMediaSource->navigateBack(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::navigateForward() -{ - if (mMediaSource) - mMediaSource->navigateForward(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLWebBrowserCtrl::canNavigateBack() -{ - if (mMediaSource) - return mMediaSource->canNavigateBack(); - else - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLWebBrowserCtrl::canNavigateForward() -{ - if (mMediaSource) - return mMediaSource->canNavigateForward(); - else - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLWebBrowserCtrl::set404RedirectUrl( std::string redirect_url ) -{ - if(mMediaSource) - return mMediaSource->set404RedirectUrl( redirect_url ); - else - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLWebBrowserCtrl::clr404RedirectUrl() -{ - if(mMediaSource) - return mMediaSource->clr404RedirectUrl(); - else - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::navigateTo( std::string urlIn ) -{ - // don't browse to anything that starts with secondlife:// or sl:// - const std::string protocol1 = "secondlife://"; - const std::string protocol2 = "sl://"; - if ((LLStringUtil::compareInsensitive(urlIn.substr(0, protocol1.length()), protocol1) == 0) || - (LLStringUtil::compareInsensitive(urlIn.substr(0, protocol2.length()), protocol2) == 0)) - { - // TODO: Print out/log this attempt? - // llinfos << "Rejecting attempt to load restricted website :" << urlIn << llendl; - return; - } - - if (mMediaSource) - { - mCurrentNavUrl = urlIn; - mMediaSource->navigateTo(urlIn); - } -} - - -void LLWebBrowserCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in ) -{ - std::string language = LLUI::getLanguage(); - std::string delim = gDirUtilp->getDirDelimiter(); - std::string filename; - - filename += subdir; - filename += delim; - filename += filename_in; - - std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename); - - if (gDirUtilp->fileExists(expanded_filename)) - { - navigateTo(expanded_filename); - return; - } - if (language != "en-us") - { - expanded_filename = gDirUtilp->findSkinnedFilename("html", "en-us", filename); - if (gDirUtilp->fileExists(expanded_filename)) - { - navigateTo(expanded_filename); - return; - } - } - - llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; -} - - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::navigateHome() -{ - if( mHomePageUrl.length() ) - { - if (mMediaSource) - mMediaSource->navigateTo(mHomePageUrl); - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::setHomePageUrl( const std::string urlIn ) -{ - mHomePageUrl = urlIn; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLWebBrowserCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue) -{ - if (mMediaSource) - return mMediaSource->setCaretColor(red, green, blue); - else - return false; -} -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLWebBrowserCtrl::getHomePageUrl() -{ - return mHomePageUrl; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserCtrl::draw() -{ - if ( ! mWebBrowserImage ) - return; - - if ( gRestoreGL == 1 ) - { - LLRect r = getRect(); - mMediaSource->updateMedia(); - reshape( r.getWidth(), r.getHeight(), FALSE ); - return; - }; - - // NOTE: optimization needed here - probably only need to do this once - // unless tearoffs change the parent which they probably do. - const LLUICtrl* ptr = findRootMostFocusRoot(); - if ( ptr && ptr->hasFocus() ) - { - setFrequentUpdates( true ); - } - else - { - setFrequentUpdates( false ); - }; - - // alpha off for this - LLGLSUIDefault gls_ui; - LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); - - gGL.pushMatrix(); - { - if (mIgnoreUIScale) - { - glLoadIdentity(); - // font system stores true screen origin, need to scale this by UI scale factor - // to get render origin for this view (with unit scale) - gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]), - floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]), - LLFontGL::sCurOrigin.mZ); - } - - // scale texture to fit the space using texture coords - gGL.getTexUnit(0)->bind(mWebBrowserImage->getTexture()); - gGL.color4fv( LLColor4::white.mV ); - F32 max_u = ( F32 )mWebBrowserImage->getBrowserWidth() / ( F32 )mWebBrowserImage->getWidth(); - F32 max_v = ( F32 )mWebBrowserImage->getBrowserHeight() / ( F32 )mWebBrowserImage->getHeight(); - - // draw the browser - gGL.setSceneBlendType(LLRender::BT_REPLACE); - gGL.begin( LLRender::QUADS ); - { - // render using web browser reported width and height, instead of trying to invert GL scale - gGL.texCoord2f( max_u, max_v ); - gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), mWebBrowserImage->getBrowserHeight() ); - - gGL.texCoord2f( 0.f, max_v ); - gGL.vertex2i( 0, mWebBrowserImage->getBrowserHeight() ); - - gGL.texCoord2f( 0.f, 0.f ); - gGL.vertex2i( 0, 0 ); - - gGL.texCoord2f( max_u, 0.f ); - gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), 0 ); - } - gGL.end(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - gGL.popMatrix(); - - // highlight if keyboard focus here. (TODO: this needs some work) - if ( mBorder->getVisible() ) - mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); - - - LLUICtrl::draw(); -} - -void LLWebBrowserCtrl::convertInputCoords(S32& x, S32& y) -{ - x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x; - y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight() - y; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onNavigateBegin( const EventType& eventIn ) -{ - LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateBegin, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onNavigateComplete( const EventType& eventIn ) -{ - // chain this event on to observers of an instance of LLWebBrowserCtrl - LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateComplete, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onUpdateProgress( const EventType& eventIn ) -{ - // chain this event on to observers of an instance of LLWebBrowserCtrl - LLWebBrowserCtrlEvent event( eventIn.getIntValue() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onUpdateProgress, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onStatusTextChange( const EventType& eventIn ) -{ - // chain this event on to observers of an instance of LLWebBrowserCtrl - LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onStatusTextChange, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onLocationChange( const EventType& eventIn ) -{ - // chain this event on to observers of an instance of LLWebBrowserCtrl - LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onLocationChange, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onMediaContentsChange( const EventType& event_in ) -{ - if ( mWebBrowserImage ) - { - mWebBrowserImage->setNeedsUpdate(); - mForceUpdate = true; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// static -bool LLWebBrowserCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response ) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if ( 0 == option ) - { - // open in external browser because we don't support - // creation of our own secondary browser windows - LLWeb::loadURLExternal( notification["payload"]["external_url"].asString() ); - } - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onClickLinkHref( const EventType& eventIn ) -{ - // if there is a value for the target (passed in stringValueEx) - if ( eventIn.getStringValueEx().length() ) - { - // if the target = "_new" - if ( eventIn.getStringValueEx() == "_external" ) - { - mExternalUrl = eventIn.getStringValue(); - LLSD payload; - payload["external_url"] = mExternalUrl; - LLNotifications::instance().add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget); - return; - } - } - - const std::string protocol1( "http://" ); - const std::string protocol2( "https://" ); - if( mOpenLinksInExternalBrowser ) - { - if ( eventIn.getStringValue().length() ) - { - if ( LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ), protocol1 ) == 0 || - LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ), protocol2 ) == 0 ) - { - LLWeb::loadURLExternal( eventIn.getStringValue() ); - } - } - } - else - if( mOpenLinksInInternalBrowser ) - { - if ( eventIn.getStringValue().length() ) - { - if ( LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ), protocol1 ) == 0 || - LLStringUtil::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ), protocol2 ) == 0 ) - { - // If we spawn a new LLFloaterHTML, assume we want it to - // follow this LLWebBrowserCtrl's trust for whether or - // not to open secondlife:///app/ links. JC. - const bool open_links_externally = false; - LLFloaterHtml::getInstance()->show( - eventIn.getStringValue(), - "Second Life Browser", - open_links_externally, - mTrusted); - } - } - } - - // chain this event on to observers of an instance of LLWebBrowserCtrl - LLWebBrowserCtrlEvent event( eventIn.getStringValue(), eventIn.getStringValueEx() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkHref, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLWebBrowserCtrl::onClickLinkNoFollow( const EventType& eventIn ) -{ - std::string url = eventIn.getStringValue(); - if (LLURLDispatcher::isSLURLCommand(url) - && !mTrusted) - { - // block handling of this secondlife:///app/ URL - LLNotifications::instance().add("UnableToOpenCommandURL"); - return; - } - - LLURLDispatcher::dispatch(url, this, mTrusted); - - // chain this event on to observers of an instance of LLWebBrowserCtrl - LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkNoFollow, event ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, LLMediaBase *media_source ) : - LLDynamicTexture( 512, 512, 4, ORDER_FIRST, TRUE ), - mLastBrowserDepth( 0 ), - mNeedsUpdate( true ), - mWebBrowserCtrl( browserCtrl ), - mMediaSource(media_source) -{ - mElapsedTime.start(); - - resize( width, height ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLWebBrowserTexture::~LLWebBrowserTexture() -{ - mElapsedTime.stop(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserTexture::needsRender() -{ - if ( mWebBrowserCtrl->getFrequentUpdates() || - mWebBrowserCtrl->getAlwaysRefresh() || - mWebBrowserCtrl->getForceUpdate() ) - { - // only update mozilla/texture occasionally - if ( mElapsedTime.getElapsedTimeF32() > ( 1.0f / 15.0f ) ) - { - return TRUE; - } - } - - return FALSE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -BOOL LLWebBrowserTexture::render() -{ - if (!mMediaSource) - return FALSE; - - // frequent updates turned on? - if ( mWebBrowserCtrl->getFrequentUpdates() || - mWebBrowserCtrl->getAlwaysRefresh() || - mWebBrowserCtrl->getForceUpdate() ) - { - - if ( mNeedsUpdate ) - { - - const unsigned char* pixels = mMediaSource->getMediaData(); - if ( ! pixels ) - return FALSE; - - mNeedsUpdate = false; - mWebBrowserCtrl->setForceUpdate(false); - - S32 media_depth = mMediaSource->getMediaDepth(); - S32 media_width = mMediaSource->getMediaWidth(); - S32 media_height = mMediaSource->getMediaHeight(); - - // these are both invalid conditions and should never happen but SL-27583 indicates it does - if ((media_width < 1) || (media_depth < 2)) - return FALSE; - - // Browser depth hasn't changed. - if(mLastBrowserDepth == media_depth) - { - S32 width = llmin(media_width, mBrowserWidth); - S32 height = llmin(media_height, mBrowserHeight); - - S32 media_data_width = mMediaSource->getMediaDataWidth(); - S32 media_data_height = mMediaSource->getMediaDataHeight(); - - // Just grab the pixels. - if ( media_data_width > 0 && media_data_height > 0 && - media_data_width < MAX_DIMENSION && media_data_height < MAX_DIMENSION ) - { - mTexture->setSubImage( pixels, - media_data_width, media_data_height, - 0, 0, - llmin(width, media_data_width), llmin(media_data_height, height) ); - }; - } - else - { - // Browser depth has changed -- need to recreate texture to match. - resize(mBrowserWidth, mBrowserHeight); - }; - }; - }; - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////////////// -// -S32 LLWebBrowserTexture::getBrowserWidth() -{ - return mBrowserWidth; -} - -//////////////////////////////////////////////////////////////////////////////// -// -S32 LLWebBrowserTexture::getBrowserHeight() -{ - return mBrowserHeight; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserTexture::setNeedsUpdate() -{ - mNeedsUpdate = true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) -{ - if (!mMediaSource) - return; - - F32 scale_ratio = 1.f; - if (new_width > MAX_DIMENSION) - { - scale_ratio = (F32)MAX_DIMENSION / (F32)new_width; - } - if (new_height > MAX_DIMENSION) - { - scale_ratio = llmin(scale_ratio, (F32)MAX_DIMENSION / (F32)new_height); - } - - mBrowserWidth = llround(scale_ratio * (F32)new_width); - mBrowserHeight = llround(scale_ratio * (F32)new_height); - - mMediaSource->setRequestedMediaSize(mBrowserWidth, mBrowserHeight); - - // HACK - this code is executing a render - resize should call render() instead - // (and render() should be refactored so it doesn't call resize()) - - mMediaSource->updateMedia(); - const unsigned char* pixels = mMediaSource->getMediaData(); - - S32 media_width = mMediaSource->getMediaWidth(); - S32 media_height = mMediaSource->getMediaHeight(); - S32 media_depth = mMediaSource->getMediaDepth(); - - // these are both invalid conditions and should never happen but SL-27583 indicates it does - if ( media_width < 1 || media_depth < 2 ) - return; - - releaseGLTexture(); - - // calculate the next power of 2 bigger than reqquested size for width and height - for ( mWidth = 1; mWidth < mBrowserWidth; mWidth <<= 1 ) - { - if ( mWidth >= MAX_TEXTURE_DIMENSION ) - { - break; - }; - }; - - for ( mHeight = 1; mHeight < mBrowserHeight; mHeight <<= 1 ) - { - if ( mHeight >= MAX_TEXTURE_DIMENSION ) - { - break; - }; - }; - - LLGLint internal_format; - LLGLenum primary_format; - LLGLenum type_format; - BOOL swap_bytes = FALSE; - - switch(media_depth) - { - default: - case 4: - internal_format = GL_RGBA8; - primary_format = GL_BGRA_EXT; - #if LL_DARWIN - #if LL_BIG_ENDIAN - type_format = GL_UNSIGNED_INT_8_8_8_8_REV; - #else - type_format = GL_UNSIGNED_INT_8_8_8_8; - #endif - #else // windows or linux - type_format = GL_UNSIGNED_BYTE; - #endif - break; - - case 2: - #if LL_DARWIN - internal_format = GL_RGBA8; - primary_format = GL_BGRA_EXT; - type_format = GL_UNSIGNED_SHORT_1_5_5_5_REV; - #if LL_LITTLE_ENDIAN - swap_bytes = TRUE; - #endif - #else // windows or linux - // MBW -- XXX -- This is just a guess on my part. Someone needs to verify which GL texture format matches the 16-bit format used on windows. - internal_format = GL_RGB8; - primary_format = GL_RGB; - type_format = GL_UNSIGNED_SHORT_5_6_5; - #endif - break; - } - - // will create mWidth * mHeight sized texture, using BGR ordering - LLDynamicTexture::generateGLTexture(internal_format, primary_format, type_format, swap_bytes); - - - S32 width = llmin(media_width, mBrowserWidth); - S32 height = llmin(media_height, mBrowserHeight); - - S32 media_data_width = mMediaSource->getMediaDataWidth(); - S32 media_data_height = mMediaSource->getMediaDataHeight(); - - if (pixels) - { - mTexture->setSubImage( pixels, media_data_width, media_data_height, - 0, 0, width, height ); - } - - mLastBrowserDepth = media_depth; -} - -// virtual -LLXMLNodePtr LLWebBrowserCtrl::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLUICtrl::getXML(); - - node->setName(LL_WEB_BROWSER_CTRL_TAG); - - return node; -} - -LLView* LLWebBrowserCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) -{ - std::string name("web_browser"); - node->getAttributeString("name", name); - - std::string start_url("start_url"); - node->getAttributeString("start_url", start_url ); - - BOOL border_visible = true; - node->getAttributeBOOL("border_visible", border_visible); - - LLRect rect; - createRect(node, rect, parent, LLRect()); - - LLWebBrowserCtrl* web_browser = new LLWebBrowserCtrl( name, rect ); - - if(node->hasAttribute("caret_color")) - { - LLColor4 color; - LLUICtrlFactory::getAttributeColor(node, "caret_color", color); - LLColor4U colorU = LLColor4U(color); - web_browser->setCaretColor( colorU.mV[0], colorU.mV[1], colorU.mV[2] ); - } - - BOOL ignore_ui_scale = web_browser->getIgnoreUIScale(); - node->getAttributeBOOL("ignore_ui_scale", ignore_ui_scale); - web_browser->setIgnoreUIScale((bool)ignore_ui_scale); - - web_browser->initFromXML(node, parent); - - web_browser->setHomePageUrl( start_url ); - - web_browser->setBorderVisible( border_visible ); - - web_browser->navigateHome(); - - return web_browser; -} - -std::string LLWebBrowserCtrl::getCurrentNavUrl() -{ - return mCurrentNavUrl; -} - diff --git a/linden/indra/newview/llwebbrowserctrl.h b/linden/indra/newview/llwebbrowserctrl.h deleted file mode 100644 index 79b89425d..000000000 --- a/linden/indra/newview/llwebbrowserctrl.h +++ /dev/null @@ -1,325 +0,0 @@ -/** - * @file llwebbrowserctrl.h - * @brief Web browser UI control - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLWEBBROWSERCTRL_H -#define LL_LLWEBBROWSERCTRL_H - -//////////////////////////////////////////////////////////////////////////////// -// data class that is passed with an event -class LLWebBrowserCtrlEvent -{ - public: - LLWebBrowserCtrlEvent() - { - }; - - LLWebBrowserCtrlEvent( int intValIn ) : - mIntVal( intValIn ) - { - }; - - LLWebBrowserCtrlEvent( std::string stringValIn ) : - mIntVal(-1), - mStringVal( stringValIn ) - { - }; - - LLWebBrowserCtrlEvent( std::string stringValIn, std::string stringValExIn ) : - mIntVal(-1), - mStringVal( stringValIn ), - mStringValEx( stringValExIn ) - { - }; - - virtual ~LLWebBrowserCtrlEvent() - { - }; - - int getIntValue() const - { - return mIntVal; - }; - - std::string getStringValue() const - { - return mStringVal; - }; - - std::string getStringValueEx() const - { - return mStringValEx; - }; - - private: - int mIntVal; - std::string mStringVal; - std::string mStringValEx; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Override these methods to observe web browser control events -// (they are chained and fired after observing LLMozLibEvents) -class LLWebBrowserCtrlObserver -{ - public: - virtual ~LLWebBrowserCtrlObserver() { }; - - typedef LLWebBrowserCtrlEvent EventType; - virtual void onNavigateBegin( const EventType& eventIn ) { }; - virtual void onNavigateComplete( const EventType& eventIn ) { }; - virtual void onUpdateProgress( const EventType& eventIn ) { }; - virtual void onStatusTextChange( const EventType& eventIn ) { }; - virtual void onLocationChange( const EventType& eventIn ) { }; - virtual void onClickLinkHref( const EventType& eventIn ) { }; - virtual void onClickLinkNoFollow( const EventType& eventIn ) { }; -}; - -#include "lluictrl.h" -#include "llframetimer.h" -#include "lldynamictexture.h" -#include "llmediaobserver.h" - -class LLViewBorder; -class LLWebBrowserTexture; - -/////////////////////////////////////////////////////////////////////////////// -// manages the process of storing and emitting events that the consumer -// of the embedding class can observe -template< class T > -class LLWebBrowserCtrlEventEmitter -{ - public: - LLWebBrowserCtrlEventEmitter() { }; - ~LLWebBrowserCtrlEventEmitter() { }; - - typedef typename T::EventType EventType; - typedef std::list< T* > ObserverContainer; - typedef void( T::*observerMethod )( const EventType& ); - - /////////////////////////////////////////////////////////////////////////////// - // - bool addObserver( T* observerIn ) - { - if ( ! observerIn ) - return false; - - if ( std::find( observers.begin(), observers.end(), observerIn ) != observers.end() ) - return false; - - observers.push_back( observerIn ); - - return true; - }; - - /////////////////////////////////////////////////////////////////////////////// - // - bool remObserver( T* observerIn ) - { - if ( ! observerIn ) - return false; - - observers.remove( observerIn ); - - return true; - }; - - /////////////////////////////////////////////////////////////////////////////// - // - void update( observerMethod method, const EventType& msgIn ) - { - typename std::list< T* >::iterator iter = observers.begin(); - - while( iter != observers.end() ) - { - ( ( *iter )->*method )( msgIn ); - - ++iter; - }; - }; - - protected: - ObserverContainer observers; -}; - -class LLUICtrlFactory; - -//////////////////////////////////////////////////////////////////////////////// -// -class LLWebBrowserCtrl : - public LLUICtrl, - public LLMediaObserver -{ - public: - LLWebBrowserCtrl( const std::string& name, const LLRect& rect ); - virtual ~LLWebBrowserCtrl(); - - void setBorderVisible( BOOL border_visible ); - - // For the tutorial window, we don't want to take focus on clicks, - // as the examples include how to move around with the arrow - // keys. Thus we keep focus on the app by setting this false. - // Defaults to true. - void setTakeFocusOnClick( bool take_focus ); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - - // handle mouse related methods - virtual BOOL handleHover( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); - - // navigation - void navigateTo( std::string urlIn ); - void navigateBack(); - void navigateHome(); - void navigateForward(); - void navigateToLocalPage( const std::string& subdir, const std::string& filename_in ); - bool canNavigateBack(); - bool canNavigateForward(); - void setOpenInExternalBrowser( bool valIn ); - void setOpenInInternalBrowser( bool valIn ); - std::string getCurrentNavUrl(); - - // By default, we do not handle "secondlife:///app/" SLURLs, because - // those can cause teleports, open windows, etc. We cannot be sure - // that each "click" is actually due to a user action, versus - // Javascript or some other mechanism. However, we need the search - // floater and login page to handle these URLs. Those are safe - // because we control the page content. See DEV-9530. JC. - void setTrusted( bool valIn ); - - void setHomePageUrl( const std::string urlIn ); - std::string getHomePageUrl(); - - // set/clear URL to visit when a 404 page is reached - bool set404RedirectUrl( std::string redirect_url ); - bool clr404RedirectUrl(); - - // accessor/mutator for flag that indicates if frequent updates to texture happen - bool getFrequentUpdates() { return mFrequentUpdates; }; - void setFrequentUpdates( bool frequentUpdatesIn ) { mFrequentUpdates = frequentUpdatesIn; }; - - void setIgnoreUIScale(bool ignore) { mIgnoreUIScale = ignore; } - bool getIgnoreUIScale() { return mIgnoreUIScale; } - - void setAlwaysRefresh(bool refresh) { mAlwaysRefresh = refresh; } - bool getAlwaysRefresh() { return mAlwaysRefresh; } - - void setForceUpdate(bool force_update) { mForceUpdate = force_update; } - bool getForceUpdate() { return mForceUpdate; } - - bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ); - - - // over-rides - virtual BOOL handleKeyHere( KEY key, MASK mask); - virtual BOOL handleUnicodeCharHere(llwchar uni_char); - virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE); - virtual void draw(); - virtual void onVisibilityChange ( BOOL curVisibilityIn ); - - // focus overrides - void onFocusLost(); - void onFocusReceived(); - - // observer interface - bool addObserver( LLWebBrowserCtrlObserver* subjectIn ); - bool remObserver( LLWebBrowserCtrlObserver* subjectIn ); - - // LLMozlib observer overrides - virtual void onNavigateBegin( const EventType& eventIn ); - virtual void onNavigateComplete( const EventType& eventIn ); - virtual void onUpdateProgress( const EventType& eventIn ); - virtual void onStatusTextChange( const EventType& eventIn ); - virtual void onLocationChange( const EventType& eventIn ); - virtual void onClickLinkHref( const EventType& eventIn ); - virtual void onClickLinkNoFollow( const EventType& eventIn ); - virtual void onMediaContentsChange( const EventType& event_in ); - - protected: - void convertInputCoords(S32& x, S32& y); - - private: - static bool onClickLinkExternalTarget( const LLSD&, const LLSD& ); - - LLWebBrowserCtrlEventEmitter< LLWebBrowserCtrlObserver > mEventEmitter; - const S32 mTextureDepthBytes; - int mEmbeddedBrowserWindowId; - LLWebBrowserTexture* mWebBrowserImage; - LLViewBorder* mBorder; - bool mFrequentUpdates; - bool mForceUpdate; - bool mOpenLinksInExternalBrowser; - bool mOpenLinksInInternalBrowser; - bool mTrusted; - std::string mHomePageUrl; - std::string mExternalUrl; - std::string mCurrentNavUrl; - bool mIgnoreUIScale; - bool mAlwaysRefresh; - LLMediaBase* mMediaSource; - bool mTakeFocusOnClick; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -class LLWebBrowserTexture : public LLDynamicTexture -{ - public: - LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, LLMediaBase *media_source ); - virtual ~LLWebBrowserTexture(); - - virtual BOOL needsRender(); - virtual void preRender( BOOL clear_depth = TRUE ) {}; - virtual void postRender( BOOL success ) {}; - virtual BOOL render(); - - S32 getBrowserWidth(); - S32 getBrowserHeight(); - void setNeedsUpdate(); - - void resize( S32 new_width, S32 new_height ); - - protected: - S32 mBrowserWidth; - S32 mBrowserHeight; - S32 mLastBrowserDepth; - bool mNeedsUpdate; - LLFrameTimer mElapsedTime; - LLWebBrowserCtrl* mWebBrowserCtrl; - LLMediaBase *mMediaSource; -}; - -#endif // LL_LLWEBBROWSERCTRL_H From dcdfa1ebab37dd78282bc95093a5f347f5846b1c Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Fri, 26 Feb 2010 17:06:16 +0100 Subject: [PATCH 018/239] port SG2.0 Mediaplugs (webkit supports flash now) --- linden/indra/llplugin/CMakeLists.txt | 0 linden/indra/llplugin/llpluginclassmedia.cpp | 51 ++++- linden/indra/llplugin/llpluginclassmedia.h | 26 ++- .../indra/llplugin/llpluginclassmediaowner.h | 4 +- linden/indra/llplugin/llplugininstance.cpp | 4 +- linden/indra/llplugin/llplugininstance.h | 5 +- linden/indra/llplugin/llpluginmessage.cpp | 4 +- linden/indra/llplugin/llpluginmessage.h | 5 +- .../indra/llplugin/llpluginmessageclasses.h | 4 +- linden/indra/llplugin/llpluginmessagepipe.cpp | 13 +- linden/indra/llplugin/llpluginmessagepipe.h | 4 +- .../indra/llplugin/llpluginprocesschild.cpp | 39 +++- linden/indra/llplugin/llpluginprocesschild.h | 7 +- .../indra/llplugin/llpluginprocessparent.cpp | 8 +- linden/indra/llplugin/llpluginprocessparent.h | 4 +- .../indra/llplugin/llpluginsharedmemory.cpp | 6 +- linden/indra/llplugin/llpluginsharedmemory.h | 5 +- linden/indra/llplugin/slplugin/CMakeLists.txt | 0 linden/indra/llplugin/slplugin/slplugin.cpp | 56 ++--- .../llplugin/slplugin/slplugin_info.plist | 0 linden/indra/llwindow/llwindow.h | 4 + linden/indra/llwindow/llwindowmacosx.cpp | 2 +- linden/indra/llwindow/llwindowmacosx.h | 4 + linden/indra/llwindow/llwindowsdl.cpp | 39 +++- linden/indra/llwindow/llwindowsdl.h | 9 +- linden/indra/llwindow/llwindowwin32.cpp | 13 ++ linden/indra/llwindow/llwindowwin32.h | 8 +- linden/indra/media_plugins/CMakeLists.txt | 0 .../indra/media_plugins/base/CMakeLists.txt | 0 .../media_plugins/base/media_plugin_base.cpp | 4 +- .../media_plugins/base/media_plugin_base.exp | 1 + .../media_plugins/base/media_plugin_base.h | 4 +- .../media_plugins/example/CMakeLists.txt | 2 +- .../example/media_plugin_example.cpp | 19 +- .../media_plugins/gstreamer010/CMakeLists.txt | 4 +- .../gstreamer010/llmediaimplgstreamer.h | 4 +- .../llmediaimplgstreamer_syms.cpp | 4 +- .../gstreamer010/llmediaimplgstreamer_syms.h | 4 +- .../llmediaimplgstreamer_syms_raw.inc | 0 .../llmediaimplgstreamer_syms_rawv.inc | 0 .../llmediaimplgstreamertriviallogging.h | 4 +- .../llmediaimplgstreamervidplug.cpp | 6 +- .../llmediaimplgstreamervidplug.h | 4 +- .../media_plugin_gstreamer010.cpp | 4 +- .../media_plugins/quicktime/CMakeLists.txt | 0 .../quicktime/media_plugin_quicktime.cpp | 84 +++---- .../indra/media_plugins/webkit/CMakeLists.txt | 7 + .../webkit/media_plugin_webkit.cpp | 213 +++++++++++------- linden/indra/newview/llviewermedia.cpp | 37 ++- linden/install.xml | 12 +- 50 files changed, 520 insertions(+), 221 deletions(-) mode change 100644 => 100755 linden/indra/llplugin/CMakeLists.txt mode change 100644 => 100755 linden/indra/llplugin/llpluginclassmedia.cpp mode change 100644 => 100755 linden/indra/llplugin/llpluginclassmedia.h mode change 100644 => 100755 linden/indra/llplugin/llpluginclassmediaowner.h mode change 100644 => 100755 linden/indra/llplugin/llplugininstance.cpp mode change 100644 => 100755 linden/indra/llplugin/llplugininstance.h mode change 100644 => 100755 linden/indra/llplugin/llpluginmessage.cpp mode change 100644 => 100755 linden/indra/llplugin/llpluginmessage.h mode change 100644 => 100755 linden/indra/llplugin/llpluginmessageclasses.h mode change 100644 => 100755 linden/indra/llplugin/llpluginmessagepipe.cpp mode change 100644 => 100755 linden/indra/llplugin/llpluginmessagepipe.h mode change 100644 => 100755 linden/indra/llplugin/llpluginprocesschild.cpp mode change 100644 => 100755 linden/indra/llplugin/llpluginprocesschild.h mode change 100644 => 100755 linden/indra/llplugin/llpluginprocessparent.cpp mode change 100644 => 100755 linden/indra/llplugin/llpluginprocessparent.h mode change 100644 => 100755 linden/indra/llplugin/llpluginsharedmemory.cpp mode change 100644 => 100755 linden/indra/llplugin/llpluginsharedmemory.h mode change 100644 => 100755 linden/indra/llplugin/slplugin/CMakeLists.txt mode change 100644 => 100755 linden/indra/llplugin/slplugin/slplugin.cpp mode change 100644 => 100755 linden/indra/llplugin/slplugin/slplugin_info.plist mode change 100644 => 100755 linden/indra/media_plugins/CMakeLists.txt mode change 100644 => 100755 linden/indra/media_plugins/base/CMakeLists.txt mode change 100644 => 100755 linden/indra/media_plugins/base/media_plugin_base.cpp mode change 100644 => 100755 linden/indra/media_plugins/base/media_plugin_base.exp mode change 100644 => 100755 linden/indra/media_plugins/base/media_plugin_base.h mode change 100644 => 100755 linden/indra/media_plugins/example/CMakeLists.txt mode change 100644 => 100755 linden/indra/media_plugins/example/media_plugin_example.cpp mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/CMakeLists.txt mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h mode change 100644 => 100755 linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp mode change 100644 => 100755 linden/indra/media_plugins/quicktime/CMakeLists.txt mode change 100644 => 100755 linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp mode change 100644 => 100755 linden/indra/media_plugins/webkit/media_plugin_webkit.cpp diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp old mode 100644 new mode 100755 index a6f6f30bf..2e8bf3fb8 --- a/linden/indra/llplugin/llpluginclassmedia.cpp +++ b/linden/indra/llplugin/llpluginclassmedia.cpp @@ -2,9 +2,10 @@ * @file llpluginclassmedia.cpp * @brief LLPluginClassMedia handles a plugin which knows about the "media" message class. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" @@ -36,6 +38,8 @@ #include "llpluginclassmedia.h" #include "llpluginmessageclasses.h" +#include "llqtwebkit.h" + static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256; static int nextPowerOf2( int value ) @@ -101,6 +105,8 @@ void LLPluginClassMedia::reset() mSetMediaHeight = -1; mRequestedMediaWidth = 0; mRequestedMediaHeight = 0; + mRequestedTextureWidth = 0; + mRequestedTextureHeight = 0; mFullMediaWidth = 0; mFullMediaHeight = 0; mTextureWidth = 0; @@ -123,7 +129,8 @@ void LLPluginClassMedia::reset() mCanPaste = false; mMediaName.clear(); mMediaDescription.clear(); - + mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f); + // media_browser class mNavigateURI.clear(); mNavigateResultCode = -1; @@ -132,6 +139,9 @@ void LLPluginClassMedia::reset() mHistoryForwardAvailable = false; mStatusText.clear(); mProgressPercent = 0; + mClickURL.clear(); + mClickTarget.clear(); + mClickTargetType = TARGET_NONE; // media_time class mCurrentTime = 0.0f; @@ -233,6 +243,10 @@ void LLPluginClassMedia::idle(void) message.setValueS32("height", mRequestedMediaHeight); message.setValueS32("texture_width", mRequestedTextureWidth); message.setValueS32("texture_height", mRequestedTextureHeight); + message.setValueReal("background_r", mBackgroundColor.mV[VX]); + message.setValueReal("background_g", mBackgroundColor.mV[VY]); + message.setValueReal("background_b", mBackgroundColor.mV[VZ]); + message.setValueReal("background_a", mBackgroundColor.mV[VW]); mPlugin->sendMessage(message); // DO NOT just use sendMessage() here -- we want this to jump ahead of the queue. LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL; @@ -370,7 +384,7 @@ bool LLPluginClassMedia::textureValid(void) bool LLPluginClassMedia::getDirty(LLRect *dirty_rect) { - bool result = !mDirtyRect.isNull(); + bool result = !mDirtyRect.isNull();//awfixme isEmpty(); if(dirty_rect != NULL) { @@ -458,7 +472,7 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int sendMessage(message); } -bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers) +bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data) { bool result = true; @@ -515,6 +529,7 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie message.setValueS32("key", key_code); message.setValue("modifiers", translateModifiers(modifiers)); + message.setValueLLSD("native_key_data", native_key_data); sendMessage(message); } @@ -533,12 +548,13 @@ void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers) sendMessage(message); } -bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers) +bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD native_key_data) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event"); message.setValue("text", text); message.setValue("modifiers", translateModifiers(modifiers)); + message.setValueLLSD("native_key_data", native_key_data); sendMessage(message); @@ -663,6 +679,26 @@ void LLPluginClassMedia::paste() sendMessage(message); } +LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) +{ + // convert a LinkTargetType value from llqtwebkit to an ETargetType + // so that we don't expose the llqtwebkit header in viewer code + switch (target_type) + { + case LLQtWebKit::LTT_TARGET_NONE: + return LLPluginClassMedia::TARGET_NONE; + + case LLQtWebKit::LTT_TARGET_BLANK: + return LLPluginClassMedia::TARGET_BLANK; + + case LLQtWebKit::LTT_TARGET_EXTERNAL: + return LLPluginClassMedia::TARGET_EXTERNAL; + + default: + return LLPluginClassMedia::TARGET_OTHER; + } +} + /* virtual */ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { @@ -710,7 +746,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) newDirtyRect.mBottom = temp; } - if(mDirtyRect.isNull()) + if(mDirtyRect.isNull())//awfixme isEmpty()) { mDirtyRect = newDirtyRect; } @@ -915,12 +951,15 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mClickURL = message.getValue("uri"); mClickTarget = message.getValue("target"); + U32 target_type = message.getValueU32("target_type"); + mClickTargetType = ::getTargetTypeFromLLQtWebkit(target_type); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); } else if(message_name == "click_nofollow") { mClickURL = message.getValue("uri"); mClickTarget.clear(); + mClickTargetType = TARGET_NONE; mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); } else diff --git a/linden/indra/llplugin/llpluginclassmedia.h b/linden/indra/llplugin/llpluginclassmedia.h old mode 100644 new mode 100755 index c45010e82..ab5434873 --- a/linden/indra/llplugin/llpluginclassmedia.h +++ b/linden/indra/llplugin/llpluginclassmedia.h @@ -2,9 +2,10 @@ * @file llpluginclassmedia.h * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINCLASSMEDIA_H @@ -38,7 +40,7 @@ #include "llrect.h" #include "llpluginclassmediaowner.h" #include <queue> - +#include "v4color.h" class LLPluginClassMedia : public LLPluginProcessParentOwner { @@ -85,6 +87,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner void setSize(int width, int height); void setAutoScale(bool auto_scale); + void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; }; + // Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent. // This will initially be false, and will also be false for some time after setSize while the resize is processed. // Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values @@ -111,12 +115,12 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner KEY_EVENT_REPEAT }EKeyEventType; - bool keyEvent(EKeyEventType type, int key_code, MASK modifiers); + bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data); void scrollEvent(int x, int y, MASK modifiers); // Text may be unicode (utf8 encoded) - bool textInput(const std::string &text, MASK modifiers); + bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data); void loadURI(const std::string &uri); @@ -211,6 +215,17 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner // This is valid after MEDIA_EVENT_CLICK_LINK_HREF std::string getClickTarget() const { return mClickTarget; }; + typedef enum + { + TARGET_NONE, // empty href target string + TARGET_BLANK, // target to open link in user's preferred browser + TARGET_EXTERNAL, // target to open link in external browser + TARGET_OTHER // nonempty and unsupported target type + }ETargetType; + + // This is valid after MEDIA_EVENT_CLICK_LINK_HREF + ETargetType getClickTargetType() const { return mClickTargetType; }; + std::string getMediaName() const { return mMediaName; }; std::string getMediaDescription() const { return mMediaDescription; }; @@ -327,6 +342,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner std::string mMediaName; std::string mMediaDescription; + LLColor4 mBackgroundColor; + ///////////////////////////////////////// // media_browser class std::string mNavigateURI; @@ -339,6 +356,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner std::string mLocation; std::string mClickURL; std::string mClickTarget; + ETargetType mClickTargetType; ///////////////////////////////////////// // media_time class diff --git a/linden/indra/llplugin/llpluginclassmediaowner.h b/linden/indra/llplugin/llpluginclassmediaowner.h old mode 100644 new mode 100755 index 182eb92d3..239f69266 --- a/linden/indra/llplugin/llpluginclassmediaowner.h +++ b/linden/indra/llplugin/llpluginclassmediaowner.h @@ -2,9 +2,10 @@ * @file llpluginclassmediaowner.h * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINCLASSMEDIAOWNER_H diff --git a/linden/indra/llplugin/llplugininstance.cpp b/linden/indra/llplugin/llplugininstance.cpp old mode 100644 new mode 100755 index 5185b3659..ce10cb638 --- a/linden/indra/llplugin/llplugininstance.cpp +++ b/linden/indra/llplugin/llplugininstance.cpp @@ -2,9 +2,10 @@ * @file llplugininstance.cpp * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/llplugin/llplugininstance.h b/linden/indra/llplugin/llplugininstance.h old mode 100644 new mode 100755 index 0b53b5fe4..baa51cc08 --- a/linden/indra/llplugin/llplugininstance.h +++ b/linden/indra/llplugin/llplugininstance.h @@ -1,10 +1,10 @@ /** * @file llplugininstance.h - * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +28,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGININSTANCE_H diff --git a/linden/indra/llplugin/llpluginmessage.cpp b/linden/indra/llplugin/llpluginmessage.cpp old mode 100644 new mode 100755 index 67ac99572..8efc774ca --- a/linden/indra/llplugin/llpluginmessage.cpp +++ b/linden/indra/llplugin/llpluginmessage.cpp @@ -2,9 +2,10 @@ * @file llpluginmessage.cpp * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/llplugin/llpluginmessage.h b/linden/indra/llplugin/llpluginmessage.h old mode 100644 new mode 100755 index 8bcb8960f..82eb89f96 --- a/linden/indra/llplugin/llpluginmessage.h +++ b/linden/indra/llplugin/llpluginmessage.h @@ -1,10 +1,10 @@ /** * @file llpluginmessage.h - * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +28,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINMESSAGE_H diff --git a/linden/indra/llplugin/llpluginmessageclasses.h b/linden/indra/llplugin/llpluginmessageclasses.h old mode 100644 new mode 100755 index 1f60d5eb8..9a39e98ca --- a/linden/indra/llplugin/llpluginmessageclasses.h +++ b/linden/indra/llplugin/llpluginmessageclasses.h @@ -2,9 +2,10 @@ * @file llpluginmessageclasses.h * @brief This file defines the versions of existing message classes for LLPluginMessage. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINMESSAGECLASSES_H diff --git a/linden/indra/llplugin/llpluginmessagepipe.cpp b/linden/indra/llplugin/llpluginmessagepipe.cpp old mode 100644 new mode 100755 index 209f49fe8..85ed2272b --- a/linden/indra/llplugin/llpluginmessagepipe.cpp +++ b/linden/indra/llplugin/llpluginmessagepipe.cpp @@ -2,9 +2,10 @@ * @file llpluginmessagepipe.cpp * @brief Classes that implement connections from the plugin system to pipes/pumps. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" @@ -303,7 +305,14 @@ void LLPluginMessagePipe::processInput(void) while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos) { // Let the owner process this message - mOwner->receiveMessageRaw(mInput.substr(start, delim - start)); + if (mOwner) + { + mOwner->receiveMessageRaw(mInput.substr(start, delim - start)); + } + else + { + LL_WARNS("Plugin") << "!mOwner" << LL_ENDL; + } start = delim + 1; } diff --git a/linden/indra/llplugin/llpluginmessagepipe.h b/linden/indra/llplugin/llpluginmessagepipe.h old mode 100644 new mode 100755 index 9bf17810c..63fd569a0 --- a/linden/indra/llplugin/llpluginmessagepipe.h +++ b/linden/indra/llplugin/llpluginmessagepipe.h @@ -2,9 +2,10 @@ * @file llpluginmessagepipe.h * @brief Classes that implement connections from the plugin system to pipes/pumps. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINMESSAGEPIPE_H diff --git a/linden/indra/llplugin/llpluginprocesschild.cpp b/linden/indra/llplugin/llpluginprocesschild.cpp old mode 100644 new mode 100755 index 9b5eafce9..e13376fc0 --- a/linden/indra/llplugin/llpluginprocesschild.cpp +++ b/linden/indra/llplugin/llpluginprocesschild.cpp @@ -2,9 +2,10 @@ * @file llpluginprocesschild.cpp * @brief LLPluginProcessChild handles the child side of the external-process plugin API. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" @@ -42,6 +44,7 @@ static const F32 PLUGIN_IDLE_SECONDS = 1.0f / 100.0f; // Each call to idle will LLPluginProcessChild::LLPluginProcessChild() { + mState = STATE_UNINITIALIZED; mInstance = NULL; mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz @@ -53,8 +56,14 @@ LLPluginProcessChild::~LLPluginProcessChild() if(mInstance != NULL) { sendMessageToPlugin(LLPluginMessage("base", "cleanup")); - delete mInstance; - mInstance = NULL; + + // IMPORTANT: under some (unknown) circumstances the apr_dso_unload() triggered when mInstance is deleted + // appears to fail and lock up which means that a given instance of the slplugin process never exits. + // This is bad, especially when users try to update their version of SL - it fails because the slplugin + // process as well as a bunch of plugin specific files are locked and cannot be overwritten. + exit( 0 ); + //delete mInstance; + //mInstance = NULL; } } @@ -270,14 +279,21 @@ bool LLPluginProcessChild::isDone(void) void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message) { - std::string buffer = message.generate(); - - LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL; - LLTimer elapsed; - - mInstance->sendMessage(buffer); - - mCPUElapsed += elapsed.getElapsedTimeF64(); + if (mInstance) + { + std::string buffer = message.generate(); + + LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL; + LLTimer elapsed; + + mInstance->sendMessage(buffer); + + mCPUElapsed += elapsed.getElapsedTimeF64(); + } + else + { + LL_WARNS("Plugin") << "mInstance == NULL" << LL_ENDL; + } } void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message) @@ -352,6 +368,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) else { LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL; + delete region; } } diff --git a/linden/indra/llplugin/llpluginprocesschild.h b/linden/indra/llplugin/llpluginprocesschild.h old mode 100644 new mode 100755 index 16a1ae84e..8e9579e04 --- a/linden/indra/llplugin/llpluginprocesschild.h +++ b/linden/indra/llplugin/llpluginprocesschild.h @@ -2,9 +2,10 @@ * @file llpluginprocesschild.h * @brief LLPluginProcessChild handles the child side of the external-process plugin API. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINPROCESSCHILD_H @@ -88,8 +90,9 @@ class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInst STATE_ERROR, // generic bailout state STATE_DONE // state machine will sit in this state after either error or normal termination. }; - EState mState; void setState(EState state); + + EState mState; LLHost mLauncherHost; LLSocket::ptr_t mSocket; diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp old mode 100644 new mode 100755 index bd36d11e8..9b8ea8b3e --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp @@ -2,9 +2,10 @@ * @file llpluginprocessparent.cpp * @brief LLPluginProcessParent handles the parent side of the external-process plugin API. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" @@ -49,11 +51,13 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) mOwner = owner; mBoundPort = 0; mState = STATE_UNINITIALIZED; + mSleepTime = 0.0; + mCPUUsage = 0.0; mDisableTimeout = false; mDebug = false; mPluginLaunchTimeout = 60.0f; - mPluginLockupTimeout = 30.0f; + mPluginLockupTimeout = 15.0f; // Don't start the timer here -- start it when we actually launch the plugin process. mHeartbeat.stop(); diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h old mode 100644 new mode 100755 index 00c60b5d8..6dbe0c174 --- a/linden/indra/llplugin/llpluginprocessparent.h +++ b/linden/indra/llplugin/llpluginprocessparent.h @@ -2,9 +2,10 @@ * @file llpluginprocessparent.h * @brief LLPluginProcessParent handles the parent side of the external-process plugin API. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINPROCESSPARENT_H diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp old mode 100644 new mode 100755 index c9466191e..a475f122d --- a/linden/indra/llplugin/llpluginsharedmemory.cpp +++ b/linden/indra/llplugin/llpluginsharedmemory.cpp @@ -1,10 +1,11 @@ /** * @file llpluginsharedmemory.cpp - * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. + * LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/llplugin/llpluginsharedmemory.h b/linden/indra/llplugin/llpluginsharedmemory.h old mode 100644 new mode 100755 index 2dc550ea8..1d23cbe57 --- a/linden/indra/llplugin/llpluginsharedmemory.h +++ b/linden/indra/llplugin/llpluginsharedmemory.h @@ -1,10 +1,10 @@ /** * @file llpluginsharedmemory.h - * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +28,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef LL_LLPLUGINSHAREDMEMORY_H diff --git a/linden/indra/llplugin/slplugin/CMakeLists.txt b/linden/indra/llplugin/slplugin/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp old mode 100644 new mode 100755 index fa3924b6f..526734ab0 --- a/linden/indra/llplugin/slplugin/slplugin.cpp +++ b/linden/indra/llplugin/slplugin/slplugin.cpp @@ -1,10 +1,12 @@ -/** +/** * @file slplugin.cpp * @brief Loader shell for plugins, intended to be launched by the plugin host application, which directly loads a plugin dynamic library. * + * @cond + * * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +30,8 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * + * @endcond */ @@ -49,15 +53,15 @@ /* On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly flag in the Info.plist. - + Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags: - + -sectcreate __TEXT __info_plist /path/to/slplugin_info.plist - + which means adding this to the gcc flags: - + -Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist - + */ #if LL_DARWIN || LL_LINUX @@ -68,7 +72,7 @@ static void crash_handler(int sig) // TODO: add our own crash reporting _exit(1); } -#endif +#endif #if LL_WINDOWS #include <windows.h> @@ -81,7 +85,7 @@ LONG WINAPI myWin32ExceptionHandler( struct _EXCEPTION_POINTERS* exception_infop //std::cerr << "intercepted an unhandled exception and will exit immediately." << std::endl; // TODO: replace exception handler before we exit? - return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_EXECUTE_HANDLER; } // Taken from : http://blog.kalmbachnet.de/?postid=75 @@ -153,7 +157,7 @@ bool checkExceptionHandler() if (prev_filter == NULL) { ok = FALSE; - if (myWin32ExceptionHandler == NULL) + if (NULL == myWin32ExceptionHandler) { LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL; } @@ -167,7 +171,7 @@ bool checkExceptionHandler() } #endif -// If this application on Windows platform is a console application, a console is always +// If this application on Windows platform is a console application, a console is always // created which is bad. Making it a Windows "application" via CMake settings but not // adding any code to explicitly create windows does the right thing. #if LL_WINDOWS @@ -178,7 +182,7 @@ int main(int argc, char **argv) { ll_init_apr(); - // Set up llerror logging + // Set up llerror logging { LLError::initForApplication("."); LLError::setDefaultLevel(LLError::LEVEL_INFO); @@ -191,14 +195,14 @@ int main(int argc, char **argv) { LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL; }; - + U32 port = 0; if(!LLStringUtil::convertToU32(lpCmdLine, port)) { LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL; }; - // Insert our exception handler into the system so this plugin doesn't + // Insert our exception handler into the system so this plugin doesn't // display a crash message if something bad happens. The host app will // see the missing heartbeat and log appropriately. initExceptionHandler(); @@ -207,7 +211,7 @@ int main(int argc, char **argv) { LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL; } - + U32 port = 0; if(!LLStringUtil::convertToU32(argv[1], port)) { @@ -228,17 +232,17 @@ int main(int argc, char **argv) LLPluginProcessChild *plugin = new LLPluginProcessChild(); plugin->init(port); - + LLTimer timer; timer.start(); #if LL_WINDOWS checkExceptionHandler(); #endif - + while(!plugin->isDone()) { - timer.reset(); + timer.reset(); plugin->idle(); #if LL_DARWIN { @@ -249,7 +253,7 @@ int main(int argc, char **argv) #endif F64 elapsed = timer.getElapsedTimeF64(); F64 remaining = plugin->getSleepTime() - elapsed; - + if(remaining <= 0.0f) { // We've already used our full allotment. @@ -262,26 +266,26 @@ int main(int argc, char **argv) { // LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL; -// timer.reset(); - +// timer.reset(); + // This also services the network as needed. plugin->sleep(remaining); - + // LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" << LL_ENDL; } #if LL_WINDOWS // More agressive checking of interfering exception handlers. - // Doesn't appear to be required so far - even for plugins - // that do crash with a single call to the intercept + // Doesn't appear to be required so far - even for plugins + // that do crash with a single call to the intercept // exception handler such as QuickTime. //checkExceptionHandler(); #endif } delete plugin; - - ll_cleanup_apr(); + + ll_cleanup_apr(); return 0; } diff --git a/linden/indra/llplugin/slplugin/slplugin_info.plist b/linden/indra/llplugin/slplugin/slplugin_info.plist old mode 100644 new mode 100755 diff --git a/linden/indra/llwindow/llwindow.h b/linden/indra/llwindow/llwindow.h index 14759cccb..2e96294cf 100644 --- a/linden/indra/llwindow/llwindow.h +++ b/linden/indra/llwindow/llwindow.h @@ -37,6 +37,7 @@ #include "llcoord.h" #include "llstring.h" #include "llcursortypes.h" +#include "llsd.h" class LLSplashScreen; @@ -208,6 +209,9 @@ class LLWindow static std::vector<std::string> getDynamicFallbackFontList(); + // Provide native key event data + virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); } + protected: LLWindow(BOOL fullscreen, U32 flags); virtual ~LLWindow() {} diff --git a/linden/indra/llwindow/llwindowmacosx.cpp b/linden/indra/llwindow/llwindowmacosx.cpp index 7efba5186..430687b6c 100644 --- a/linden/indra/llwindow/llwindowmacosx.cpp +++ b/linden/indra/llwindow/llwindowmacosx.cpp @@ -3217,7 +3217,7 @@ void LLWindowMacOSX::ShellEx(const std::string& command) } } -BOOL LLWindowMacOSX::dialog_color_picker ( F32 *r, F32 *g, F32 *b) +BOOL LLWindowMacOSX::dialog_color_picker( F32 *r, F32 *g, F32 *b) { BOOL retval = FALSE; OSErr error = noErr; diff --git a/linden/indra/llwindow/llwindowmacosx.h b/linden/indra/llwindow/llwindowmacosx.h index 9e87e9fd3..92c73e864 100644 --- a/linden/indra/llwindow/llwindowmacosx.h +++ b/linden/indra/llwindow/llwindowmacosx.h @@ -117,6 +117,10 @@ class LLWindowMacOSX : public LLWindow static std::vector<std::string> getDynamicFallbackFontList(); + // Provide native key event data + /*virtual*/ LLSD getNativeKeyData(); + + protected: LLWindowMacOSX( const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp index bf339f216..9310ff53b 100644 --- a/linden/indra/llwindow/llwindowsdl.cpp +++ b/linden/indra/llwindow/llwindowsdl.cpp @@ -250,6 +250,10 @@ LLWindowSDL::LLWindowSDL(const std::string& title, S32 x, S32 y, S32 width, #if LL_X11 mFlashing = FALSE; #endif // LL_X11 + + mKeyScanCode = 0; + mKeyVirtualKey = 0; + mKeyModifiers = KMOD_NONE; } static SDL_Surface *Load_BMP_Resource(const char *basename) @@ -2227,7 +2231,40 @@ static void color_changed_callback(GtkWidget *widget, gtk_color_selection_get_current_color(colorsel, colorp); } -BOOL LLWindowSDL::dialog_color_picker ( F32 *r, F32 *g, F32 *b) + +/* + 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(); + + U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave! + + // we go through so many levels of device abstraction that I can't really guess + // 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 + // *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["modifiers"] = (S32)modifiers; + + return result; +} + + +BOOL LLWindowSDL::dialog_color_picker( F32 *r, F32 *g, F32 *b) { BOOL rtn = FALSE; diff --git a/linden/indra/llwindow/llwindowsdl.h b/linden/indra/llwindow/llwindowsdl.h index 39a600718..37b083519 100644 --- a/linden/indra/llwindow/llwindowsdl.h +++ b/linden/indra/llwindow/llwindowsdl.h @@ -154,6 +154,8 @@ class LLWindowSDL : public LLWindow BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowSDL(); + /*virtual*/ LLSD getNativeKeyData(); + void initCursors(); void quitCursors(); BOOL isValid(); @@ -206,12 +208,17 @@ class LLWindowSDL : public LLWindow friend class LLWindowManager; -#if LL_X11 + private: +#if LL_X11 void x11_set_urgent(BOOL urgent); BOOL mFlashing; LLTimer mFlashTimer; #endif //LL_X11 + U32 mKeyScanCode; + U32 mKeyVirtualKey; + SDLMod mKeyModifiers; + }; diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp index e47cab470..12a488a6b 100644 --- a/linden/indra/llwindow/llwindowwin32.cpp +++ b/linden/indra/llwindow/llwindowwin32.cpp @@ -3052,6 +3052,19 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url ) */ } +/* + 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 LLWindowWin32::getNativeKeyData() +{ + LLSD result = LLSD::emptyMap(); + + result["scan_code"] = (S32)mKeyScanCode; + result["virtual_key"] = (S32)mKeyVirtualKey; + + return result; +} BOOL LLWindowWin32::dialog_color_picker ( F32 *r, F32 *g, F32 *b ) { diff --git a/linden/indra/llwindow/llwindowwin32.h b/linden/indra/llwindow/llwindowwin32.h index cc95993b0..0e40115da 100644 --- a/linden/indra/llwindow/llwindowwin32.h +++ b/linden/indra/llwindow/llwindowwin32.h @@ -128,7 +128,7 @@ class LLWindowWin32 : public LLWindow HCURSOR loadColorCursor(LPCTSTR name); BOOL isValid(); void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); - + LLSD getNativeKeyData(); // Changes display resolution. Returns true if successful BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); @@ -208,6 +208,12 @@ class LLWindowWin32 : public LLWindow LLPreeditor *mPreeditor; + + + U32 mKeyCharCode; + U32 mKeyScanCode; + U32 mKeyVirtualKey; + friend class LLWindowManager; }; diff --git a/linden/indra/media_plugins/CMakeLists.txt b/linden/indra/media_plugins/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/linden/indra/media_plugins/base/CMakeLists.txt b/linden/indra/media_plugins/base/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/linden/indra/media_plugins/base/media_plugin_base.cpp b/linden/indra/media_plugins/base/media_plugin_base.cpp old mode 100644 new mode 100755 index 4d5e3744e..baae68c02 --- a/linden/indra/media_plugins/base/media_plugin_base.cpp +++ b/linden/indra/media_plugins/base/media_plugin_base.cpp @@ -4,9 +4,10 @@ * * All plugins should be a subclass of MediaPluginBase. * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -30,6 +31,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/media_plugins/base/media_plugin_base.exp b/linden/indra/media_plugins/base/media_plugin_base.exp old mode 100644 new mode 100755 index 1e27d1f12..d8c7bb712 --- a/linden/indra/media_plugins/base/media_plugin_base.exp +++ b/linden/indra/media_plugins/base/media_plugin_base.exp @@ -1 +1,2 @@ _LLPluginInitEntryPoint + diff --git a/linden/indra/media_plugins/base/media_plugin_base.h b/linden/indra/media_plugins/base/media_plugin_base.h old mode 100644 new mode 100755 index 24198af81..8311e66bc --- a/linden/indra/media_plugins/base/media_plugin_base.h +++ b/linden/indra/media_plugins/base/media_plugin_base.h @@ -2,9 +2,10 @@ * @file media_plugin_base.h * @brief Media plugin base class for LLMedia API plugin system * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/media_plugins/example/CMakeLists.txt b/linden/indra/media_plugins/example/CMakeLists.txt old mode 100644 new mode 100755 index b074a1d20..6d14c1b28 --- a/linden/indra/media_plugins/example/CMakeLists.txt +++ b/linden/indra/media_plugins/example/CMakeLists.txt @@ -14,7 +14,7 @@ include(PluginAPI) include(MediaPluginBase) include(FindOpenGL) -include(ExamplePlugin) +#awfixme include(ExamplePlugin) include_directories( ${LLPLUGIN_INCLUDE_DIRS} diff --git a/linden/indra/media_plugins/example/media_plugin_example.cpp b/linden/indra/media_plugins/example/media_plugin_example.cpp old mode 100644 new mode 100755 index 99e0199a2..83abae0a7 --- a/linden/indra/media_plugins/example/media_plugin_example.cpp +++ b/linden/indra/media_plugins/example/media_plugin_example.cpp @@ -2,31 +2,34 @@ * @file media_plugin_example.cpp * @brief Example plugin for LLMedia API plugin system * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * + * Copyright (c) 2008-2010, Linden Research, Inc. + * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception - * + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. - * + * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt old mode 100644 new mode 100755 index a3a32d804..3b73e0478 --- a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -42,12 +42,12 @@ set(media_plugin_gstreamer010_HEADER_FILES llmediaimplgstreamertriviallogging.h ) -#awfixme if (${CXX_VERSION_NUMBER} MATCHES "4[23].") +if (${CXX_VERSION_NUMBER} MATCHES "4[23].") # Work around a bad interaction between broken gstreamer headers and # g++ 4.3's increased strictness. set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES COMPILE_FLAGS -Wno-write-strings) -#awfixme endif (${CXX_VERSION_NUMBER} MATCHES "4[23].") +endif (${CXX_VERSION_NUMBER} MATCHES "4[23].") add_library(media_plugin_gstreamer010 SHARED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h old mode 100644 new mode 100755 index ef41736c1..6920c3b3a --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h @@ -3,9 +3,10 @@ * @author Tofu Linden * @brief implementation that supports media playback via GStreamer. * + * @cond * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2007-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -29,6 +30,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ // header guard diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp old mode 100644 new mode 100755 index cc5223249..28960acec --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp @@ -2,9 +2,10 @@ * @file llmediaimplgstreamer_syms.cpp * @brief dynamic GStreamer symbol-grabbing code * + * @cond * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2007-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #if LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h old mode 100644 new mode 100755 index ee7473d6d..7955898d8 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h @@ -2,9 +2,10 @@ * @file llmediaimplgstreamer_syms.h * @brief dynamic GStreamer symbol-grabbing code * + * @cond * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2007-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc old mode 100644 new mode 100755 diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc old mode 100644 new mode 100755 diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h old mode 100644 new mode 100755 index 04976b92f..27f0eed6c --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h @@ -2,9 +2,10 @@ * @file llmediaimplgstreamertriviallogging.h * @brief minimal logging utilities. * + * @cond * $LicenseInfo:firstyear=2009&license=viewergpl$ * - * Copyright (c) 2009, Linden Research, Inc. + * Copyright (c) 2009-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp old mode 100644 new mode 100755 index ef8ff588c..2b10a2aa3 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -1,10 +1,11 @@ /** - * @file llmediaimplgstreamervidplug.cpp + * @file llmediaimplgstreamervidplug.h * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl * + * @cond * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2007-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #if LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h old mode 100644 new mode 100755 index 8cdc72d50..fad80cbbc --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -2,9 +2,10 @@ * @file llmediaimplgstreamervidplug.h * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl * + * @cond * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2007-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #ifndef __GST_SLVIDEO_H__ diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp old mode 100644 new mode 100755 index 5b3152d61..82e6fdc45 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -2,9 +2,10 @@ * @file media_plugin_gstreamer010.cpp * @brief GStreamer-0.10 plugin for LLMedia API plugin system * + * @cond * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2007-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" diff --git a/linden/indra/media_plugins/quicktime/CMakeLists.txt b/linden/indra/media_plugins/quicktime/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp old mode 100644 new mode 100755 index 6c8c41dbb..9b4c5314b --- a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -1,10 +1,11 @@ -/** +/** * @file media_plugin_quicktime.cpp * @brief QuickTime plugin for LLMedia API plugin system * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ #include "linden_common.h" @@ -102,14 +104,14 @@ class MediaPluginQuickTime : public MediaPluginBase message.setValueS32("top", top); message.setValueS32("right", right); message.setValueS32("bottom", bottom); - + if(mMovieHandle) { message.setValueReal("current_time", getCurrentTime()); message.setValueReal("duration", getDuration()); message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle))); } - + sendMessage(message); } @@ -117,16 +119,16 @@ class MediaPluginQuickTime : public MediaPluginBase static Rect rectFromSize(int width, int height) { Rect result; - + result.left = 0; result.top = 0; result.right = width; result.bottom = height; - + return result; } - + Fixed getPlayRate(void) { Fixed result; @@ -145,25 +147,27 @@ class MediaPluginQuickTime : public MediaPluginBase { result = X2Fix(mPlayRate); } - + return result; } - + void load( const std::string url ) { + if ( url.empty() ) return; - + // Stop and unload any existing movie before starting another one. unload(); - + setStatus(STATUS_LOADING); - + //In case std::string::c_str() makes a copy of the url data, //make sure there is memory to hold it before allocating memory for handle. //if fails, NewHandleClear(...) should return NULL. const char* url_string = url.c_str() ; Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); + if ( NULL == handle || noErr != MemError() || NULL == *handle ) { setStatus(STATUS_ERROR); @@ -202,7 +206,7 @@ class MediaPluginQuickTime : public MediaPluginBase SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); setStatus(STATUS_LOADED); - + sizeChanged(); }; @@ -239,7 +243,7 @@ class MediaPluginQuickTime : public MediaPluginBase DisposeGWorld( mGWorldHandle ); mGWorldHandle = NULL; }; - + setStatus(STATUS_NONE); return true; @@ -249,7 +253,7 @@ class MediaPluginQuickTime : public MediaPluginBase { unload(); load( url ); - + return true; }; @@ -257,7 +261,7 @@ class MediaPluginQuickTime : public MediaPluginBase { if ( ! mMovieHandle ) return false; - + // Check to see whether the movie's natural size has updated { int width, height; @@ -275,14 +279,14 @@ class MediaPluginQuickTime : public MediaPluginBase //std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl; } } - + // sanitize destination size Rect dest_rect = rectFromSize(mWidth, mHeight); // media depth won't change int depth_bits = mDepth * 8; long rowbytes = mDepth * mTextureWidth; - + GWorldPtr old_gworld_handle = mGWorldHandle; if(mPixels != NULL) @@ -314,7 +318,7 @@ class MediaPluginQuickTime : public MediaPluginBase { DisposeGWorld( old_gworld_handle ); } - + // Set up the movie display matrix { // scale movie to fit rect and invert vertically to match opengl image format @@ -327,7 +331,7 @@ class MediaPluginQuickTime : public MediaPluginBase ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) ); SetMovieMatrix( mMovieHandle, &transform ); } - + // update movie controller if ( mMovieController ) { @@ -345,7 +349,6 @@ class MediaPluginQuickTime : public MediaPluginBase return true; } - static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) { Boolean result = false; @@ -355,9 +358,9 @@ class MediaPluginQuickTime : public MediaPluginBase switch( action ) { // handle window resizing - case mcActionControllerSizeChanged: + case mcActionControllerSizeChanged: // Ensure that the movie draws correctly at the new size - self->sizeChanged(); + self->sizeChanged(); break; // Block any movie controller actions that open URLs. @@ -386,6 +389,7 @@ class MediaPluginQuickTime : public MediaPluginBase // self->updateQuickTime(); // TODO ^^^ + if ( self->mWidth > 0 && self->mHeight > 0 ) self->setDirty( 0, 0, self->mWidth, self->mHeight ); @@ -434,7 +438,7 @@ class MediaPluginQuickTime : public MediaPluginBase MCDoAction( mMovieController, mcActionPlay, (void*)rate ); rewind(); }; - + MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() ); MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); setStatus(STATUS_PLAYING); @@ -462,7 +466,7 @@ class MediaPluginQuickTime : public MediaPluginBase if ( mCommand == COMMAND_PAUSE ) { if ( mStatus == STATUS_PLAYING ) - { + { if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) { Fixed rate = X2Fix( 0.0 ); @@ -495,7 +499,7 @@ class MediaPluginQuickTime : public MediaPluginBase void getMovieNaturalSize(int *movie_width, int *movie_height) { Rect rect; - + GetMovieNaturalBoundsRect( mMovieHandle, &rect ); int width = ( rect.right - rect.left ); @@ -518,7 +522,7 @@ class MediaPluginQuickTime : public MediaPluginBase *movie_width = width; *movie_height = height; } - + void updateQuickTime(int milliseconds) { if ( ! mMovieHandle ) @@ -721,8 +725,8 @@ class MediaPluginQuickTime : public MediaPluginBase return false; // allocate some space and grab it - UInt8* item_data = new UInt8( size + 1 ); - memset( item_data, 0, ( size + 1 ) * sizeof( UInt8* ) ); + UInt8* item_data = new UInt8[ size + 1 ]; + memset( item_data, 0, ( size + 1 ) * sizeof( UInt8 ) ); result = QTMetaDataGetItemValue( media_data_ref, item, item_data, size, NULL ); if ( noErr != result ) { @@ -861,7 +865,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); #if defined(LL_WINDOWS) // Values for Windows - mDepth = 3; + mDepth = 3; message.setValueU32("format", GL_RGB); message.setValueU32("type", GL_UNSIGNED_BYTE); @@ -870,7 +874,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) message.setValueU32("padding", 32 * 3); #else // Values for Mac - mDepth = 4; + mDepth = 4; message.setValueU32("format", GL_BGRA_EXT); #ifdef __BIG_ENDIAN__ message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV ); @@ -891,7 +895,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) { // no response is necessary here. F64 time = message_in.getValueReal("time"); - + // Convert time to milliseconds for update() update((int)(time * 1000.0f)); } @@ -905,8 +909,6 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) info.mAddress = message_in.getValuePointer("address"); info.mSize = (size_t)message_in.getValueS32("size"); std::string name = message_in.getValue("name"); - - // std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name // << ", size: " << info.mSize // << ", address: " << info.mAddress @@ -929,9 +931,9 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) // This is the currently active pixel buffer. Make sure we stop drawing to it. mPixels = NULL; mTextureSegmentName.clear(); - + // Make sure the movie GWorld is no longer pointed at the shared segment. - sizeChanged(); + sizeChanged(); } mSharedSegments.erase(iter); } @@ -988,9 +990,9 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) mTextureHeight = texture_height; mMediaSizeChanging = false; - + sizeChanged(); - + update(); }; }; @@ -999,14 +1001,14 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) { std::string uri = message_in.getValue("uri"); load( uri ); - sendStatus(); + sendStatus(); } else if(message_name == "mouse_event") { std::string event = message_in.getValue("event"); S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); - + if(event == "down") { mouseDown(x, y); @@ -1099,7 +1101,7 @@ MediaPluginQuickTime::~MediaPluginQuickTime() void MediaPluginQuickTime::receiveMessage(const char *message_string) { - // no-op + // no-op } // We're building without quicktime enabled. Just refuse to initialize. diff --git a/linden/indra/media_plugins/webkit/CMakeLists.txt b/linden/indra/media_plugins/webkit/CMakeLists.txt index 54bc3644c..1c999ba78 100644 --- a/linden/indra/media_plugins/webkit/CMakeLists.txt +++ b/linden/indra/media_plugins/webkit/CMakeLists.txt @@ -9,6 +9,7 @@ include(LLPlugin) include(LLMath) include(LLRender) include(LLWindow) +include(UI) include(Linking) include(PluginAPI) include(MediaPluginBase) @@ -50,6 +51,11 @@ set(media_plugin_webkit_LINK_LIBRARIES ${PLUGIN_API_WINDOWS_LIBRARIES} ) +if(LINUX) + list(APPEND media_plugin_webkit_LINK_LIBRARIES + ${UI_LIBRARIES} # for glib/GTK + ) +endif(LINUX) add_library(media_plugin_webkit @@ -93,3 +99,4 @@ if (DARWIN) ) endif (DARWIN) + diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp old mode 100644 new mode 100755 index 91efdaecb..2e3f06d67 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -2,9 +2,10 @@ * @file media_plugin_webkit.cpp * @brief Webkit plugin for LLMedia API plugin system * + * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * - * Copyright (c) 2008-2009, Linden Research, Inc. + * Copyright (c) 2008-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -28,8 +29,9 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * @endcond */ - +#include <iomanip>//FIXME: This is included from elsewhere in SG2.0 #include "llqtwebkit.h" #include "linden_common.h" @@ -50,7 +52,7 @@ #endif #if LL_WINDOWS - // NOTE - This captures the module handle of the dll. This is used below + // *NOTE:Mani - This captures the module handle fo rthe dll. This is used below // to get the path to this dll for webkit initialization. // I don't know how/if this can be done with apr... namespace { HMODULE gModuleHandle;}; @@ -83,6 +85,7 @@ class MediaPluginWebKit : INIT_STATE_NAVIGATING, // Browser instance has been set up and initial navigate to about:blank has been issued INIT_STATE_NAVIGATE_COMPLETE, // initial navigate to about:blank has completed INIT_STATE_WAIT_REDRAW, // First real navigate begin has been received, waiting for page changed event to start handling redraws + INIT_STATE_WAIT_COMPLETE, // Waiting for first real navigate complete event INIT_STATE_RUNNING // All initialization gymnastics are complete. }; int mBrowserWindowId; @@ -96,6 +99,9 @@ class MediaPluginWebKit : int mLastMouseX; int mLastMouseY; bool mFirstFocus; + F32 mBackgroundR; + F32 mBackgroundG; + F32 mBackgroundB; void setInitState(int state) { @@ -121,7 +127,7 @@ class MediaPluginWebKit : } } - if ( (mInitState == INIT_STATE_RUNNING) && mNeedsUpdate ) + if ( (mInitState > INIT_STATE_WAIT_REDRAW) && mNeedsUpdate ) { const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId ); @@ -170,8 +176,17 @@ class MediaPluginWebKit : } std::string application_dir = std::string( cwd ); +#if LL_DARWIN + // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on. + // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger. + // This wouldn't cause any problems except for the fact that the current release version of the Flash plugin has a call to Debugger() in it + // which gets hit when the plugin is probed by webkit. + // Unsetting the environment variable here works around this issue. + unsetenv("USERBREAK"); +#endif + #if LL_WINDOWS - // NOTE - On windows, at least, the component path is the + //*NOTE:Mani - On windows, at least, the component path is the // location of this dll's image file. std::string component_dir; char dll_path[_MAX_PATH]; @@ -187,8 +202,8 @@ class MediaPluginWebKit : } else { - // NOTE - This case should be a rare exception. - // GetModuleFileNameA should always give you a full path. + // *NOTE:Mani - This case should be an rare exception. + // GetModuleFileNameA should always give you a full path, no? component_dir = application_dir; } #else @@ -210,7 +225,6 @@ class MediaPluginWebKit : { // create single browser window mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight ); - #if LL_WINDOWS // Enable plugins LLQtWebKit::getInstance()->enablePlugins(true); @@ -236,8 +250,9 @@ class MediaPluginWebKit : // don't flip bitmap LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); - // set background color to be black - mostly for initial login page - LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, 0x00, 0x00, 0x00 ); + // set background color + // convert background color channels from [0.0, 1.0] to [0, 255]; + LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) ); // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns. setInitState(INIT_STATE_NAVIGATING); @@ -245,7 +260,21 @@ class MediaPluginWebKit : // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance. // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date. - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" ); + // Build a data URL like this: "data:text/html,%3Chtml%3E%3Cbody bgcolor=%22#RRGGBB%22%3E%3C/body%3E%3C/html%3E" + // where RRGGBB is the background color in HTML style + std::stringstream url; + + url << "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#"; + // convert background color channels from [0.0, 1.0] to [0, 255]; + url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundR * 255.0f); + url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundG * 255.0f); + url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f); + url << "%22%3E%3C/body%3E%3C/html%3E"; + + lldebugs << "data url is: " << url.str() << llendl; + + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() ); +// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" ); return true; }; @@ -253,6 +282,7 @@ class MediaPluginWebKit : return false; }; + //////////////////////////////////////////////////////////////////////////////// // virtual void onCursorChanged(const EventType& event) @@ -294,7 +324,7 @@ class MediaPluginWebKit : { if(mInitState == INIT_STATE_WAIT_REDRAW) { - setInitState(INIT_STATE_RUNNING); + setInitState(INIT_STATE_WAIT_COMPLETE); } // flag that an update is required @@ -316,7 +346,9 @@ class MediaPluginWebKit : if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) { - setInitState(INIT_STATE_WAIT_REDRAW); + // Skip the WAIT_REDRAW state now -- with the right background color set, it should no longer be necessary. +// setInitState(INIT_STATE_WAIT_REDRAW); + setInitState(INIT_STATE_WAIT_COMPLETE); } } @@ -327,6 +359,14 @@ class MediaPluginWebKit : { if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) { + if(mInitState < INIT_STATE_RUNNING) + { + setInitState(INIT_STATE_RUNNING); + + // Clear the history, so the "back" button doesn't take you back to "about:blank". + LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId); + } + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); message.setValue("uri", event.getEventUri()); message.setValueS32("result_code", event.getIntValue()); @@ -399,6 +439,7 @@ class MediaPluginWebKit : LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); message.setValue("uri", event.getStringValue()); message.setValue("target", event.getStringValue2()); + message.setValueU32("target_type", event.getLinkType()); sendMessage(message); } @@ -430,92 +471,96 @@ class MediaPluginWebKit : return (LLQtWebKit::EKeyboardModifier)result; } - //////////////////////////////////////////////////////////////////////////////// // - void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers) + void deserializeKeyboardData( LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers ) { - int llqt_key; + native_scan_code = 0; + native_virtual_key = 0; + native_modifiers = 0; + if( native_key_data.isMap() ) + { +#if LL_DARWIN + native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); + native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); +#elif LL_WINDOWS + native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); + // TODO: I don't think we need to do anything with native modifiers here -- please verify +#elif LL_LINUX + native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); + native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); + native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); +#else + // Add other platforms here as needed +#endif + }; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) + { // The incoming values for 'key' will be the ones from indra_constants.h - // the outgoing values are the ones from llqtwebkit.h + std::string utf8_text; + if(key < KEY_SPECIAL) + { + // Low-ascii characters need to get passed through. + utf8_text = (char)key; + } + + // Any special-case handling we want to do for particular keys... switch((KEY)key) { - // This is the list that the llqtwebkit implementation actually maps into Qt keys. -// case KEY_XXX: llqt_key = LL_DOM_VK_CANCEL; break; -// case KEY_XXX: llqt_key = LL_DOM_VK_HELP; break; - case KEY_BACKSPACE: llqt_key = LL_DOM_VK_BACK_SPACE; break; - case KEY_TAB: llqt_key = LL_DOM_VK_TAB; break; -// case KEY_XXX: llqt_key = LL_DOM_VK_CLEAR; break; - case KEY_RETURN: llqt_key = LL_DOM_VK_RETURN; break; - case KEY_PAD_RETURN: llqt_key = LL_DOM_VK_ENTER; break; - case KEY_SHIFT: llqt_key = LL_DOM_VK_SHIFT; break; - case KEY_CONTROL: llqt_key = LL_DOM_VK_CONTROL; break; - case KEY_ALT: llqt_key = LL_DOM_VK_ALT; break; -// case KEY_XXX: llqt_key = LL_DOM_VK_PAUSE; break; - case KEY_CAPSLOCK: llqt_key = LL_DOM_VK_CAPS_LOCK; break; - case KEY_ESCAPE: llqt_key = LL_DOM_VK_ESCAPE; break; - case KEY_PAGE_UP: llqt_key = LL_DOM_VK_PAGE_UP; break; - case KEY_PAGE_DOWN: llqt_key = LL_DOM_VK_PAGE_DOWN; break; - case KEY_END: llqt_key = LL_DOM_VK_END; break; - case KEY_HOME: llqt_key = LL_DOM_VK_HOME; break; - case KEY_LEFT: llqt_key = LL_DOM_VK_LEFT; break; - case KEY_UP: llqt_key = LL_DOM_VK_UP; break; - case KEY_RIGHT: llqt_key = LL_DOM_VK_RIGHT; break; - case KEY_DOWN: llqt_key = LL_DOM_VK_DOWN; break; -// case KEY_XXX: llqt_key = LL_DOM_VK_PRINTSCREEN; break; - case KEY_INSERT: llqt_key = LL_DOM_VK_INSERT; break; - case KEY_DELETE: llqt_key = LL_DOM_VK_DELETE; break; -// case KEY_XXX: llqt_key = LL_DOM_VK_CONTEXT_MENU; break; + // ASCII codes for some standard keys + case LLQtWebKit::KEY_BACKSPACE: utf8_text = (char)8; break; + case LLQtWebKit::KEY_TAB: utf8_text = (char)9; break; + case LLQtWebKit::KEY_RETURN: utf8_text = (char)13; break; + case LLQtWebKit::KEY_PAD_RETURN: utf8_text = (char)13; break; + case LLQtWebKit::KEY_ESCAPE: utf8_text = (char)27; break; - default: - if(key < KEY_SPECIAL) - { - // Pass the incoming key through -- it should be regular ASCII, which should be correct for webkit. - llqt_key = key; - } - else - { - // Don't pass through untranslated special keys -- they'll be all wrong. - llqt_key = 0; - } + default: break; } -// std::cerr << "keypress, original code = 0x" << std::hex << key << ", converted code = 0x" << std::hex << llqt_key << std::dec << std::endl; +// std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl; - if(llqt_key != 0) - { - LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, key_event, llqt_key, modifiers); - } + uint32_t native_scan_code = 0; + uint32_t native_virtual_key = 0; + uint32_t native_modifiers = 0; + deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers ); + + LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); checkEditState(); }; //////////////////////////////////////////////////////////////////////////////// // - void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers) - { - LLWString wstr = utf8str_to_wstring(utf8str); + void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) + { + uint32_t key = LLQtWebKit::KEY_NONE; - unsigned int i; - for(i=0; i < wstr.size(); i++) +// std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl; + + if(utf8str.size() == 1) { -// std::cerr << "unicode input, code = 0x" << std::hex << (unsigned long)(wstr[i]) << std::dec << std::endl; - - if(wstr[i] == 32) - { - // For some reason, the webkit plugin really wants the space bar to come in through the key-event path, not the unicode path. - LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, 32, modifiers); - LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, 32, modifiers); - } - else - { - LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, wstr[i], modifiers); - } + // The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character. + // In this case, use it as the key value. + key = utf8str[0]; } + uint32_t native_scan_code = 0; + uint32_t native_virtual_key = 0; + uint32_t native_modifiers = 0; + deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers ); + + LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); + checkEditState(); }; @@ -568,6 +613,9 @@ MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_ mLastMouseX = 0; mLastMouseY = 0; mFirstFocus = true; + mBackgroundR = 0.0f; + mBackgroundG = 0.0f; + mBackgroundB = 0.0f; } MediaPluginWebKit::~MediaPluginWebKit() @@ -645,7 +693,6 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) info.mSize = (size_t)message_in.getValueS32("size"); std::string name = message_in.getValue("name"); - // std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name // << ", size: " << info.mSize // << ", address: " << info.mAddress @@ -695,7 +742,11 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) S32 height = message_in.getValueS32("height"); S32 texture_width = message_in.getValueS32("texture_width"); S32 texture_height = message_in.getValueS32("texture_height"); - + mBackgroundR = message_in.getValueReal("background_r"); + mBackgroundG = message_in.getValueReal("background_g"); + mBackgroundB = message_in.getValueReal("background_b"); +// mBackgroundA = message_in.setValueReal("background_a"); // Ignore any alpha + if(!name.empty()) { // Find the shared memory region with this name @@ -809,6 +860,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) std::string event = message_in.getValue("event"); S32 key = message_in.getValueS32("key"); std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); // Treat unknown events as key-up for safety. LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP; @@ -821,14 +873,15 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) key_event = LLQtWebKit::KE_KEY_REPEAT; } - keyEvent(key_event, key, decodeModifiers(modifiers)); + keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); } else if(message_name == "text_event") { std::string text = message_in.getValue("text"); std::string modifiers = message_in.getValue("modifiers"); + LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - unicodeInput(text, decodeModifiers(modifiers)); + unicodeInput(text, decodeModifiers(modifiers), native_key_data); } if(message_name == "edit_cut") { diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 5bdb26f04..c0d146081 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -770,7 +770,38 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask) if (mMediaSource) { - result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask); + // FIXME: THIS IS SO WRONG. + // Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it... + if( MASK_CONTROL & mask ) + { + if( 'C' == key ) + { + mMediaSource->copy(); + result = true; + } + else + if( 'V' == key ) + { + mMediaSource->paste(); + result = true; + } + else + if( 'X' == key ) + { + mMediaSource->cut(); + result = true; + } + } + + if(!result) + { + + LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData(); + + result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data); + // Since the viewer internal event dispatching doesn't give us key-up events, simulate one here. + (void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data); + } } return result; @@ -787,7 +818,9 @@ bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char) if (uni_char >= 32 // discard 'control' characters && uni_char != 127) // SDL thinks this is 'delete' - yuck. { - mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE)); + LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData(); + + mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE), native_key_data); } } diff --git a/linden/install.xml b/linden/install.xml index 99d3bb204..d9f400acd 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -1144,23 +1144,23 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <key>darwin</key> <map> <key>md5sum</key> - <string>b40a13847ee773c9ee06f641fe0dd1c2</string> + <string>95f44f0023dddc80be4398fc4f213861</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-darwin-20091023.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100208.tar.bz2</uri> </map> <key>linux</key> <map> <key>md5sum</key> - <string>ffede2775355676096b1085cbb9d0da7</string> + <string>4c75b2f1e8524c7844ee3ea1cd59a3db</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20091117.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20100209b.tar.bz2</uri> </map> <key>windows</key> <map> <key>md5sum</key> - <string>6f2f911545e5906edc87f4f3cda423a1</string> + <string>1e9798dc424a6f6c2bea50649bbcc7ae</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-windows-20091023.tar.bz2</uri> + <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100210.tar.bz2</uri> </map> </map> </map> From 791d4c2de7c0219392aeb625cf7940290dc1e79a Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Mon, 14 Jun 2010 12:27:35 +0200 Subject: [PATCH 019/239] port llprimitive from SG2.0 --- linden/indra/llcommon/lllslconstants.h | 2 +- linden/indra/llmath/llsdutil_math.h | 70 ++ linden/indra/llprimitive/CMakeLists.txt | 12 + linden/indra/llprimitive/llmaterialtable.cpp | 16 +- linden/indra/llprimitive/llmaterialtable.h | 87 +-- linden/indra/llprimitive/llmediaentry.cpp | 602 ++++++++++++++++++ linden/indra/llprimitive/llmediaentry.h | 228 +++++++ linden/indra/llprimitive/llprimitive.cpp | 581 ++++++++++------- linden/indra/llprimitive/llprimitive.h | 58 +- linden/indra/llprimitive/llprimlinkinfo.h | 2 +- .../indra/llprimitive/llprimtexturelist.cpp | 424 ++++++++++++ linden/indra/llprimitive/llprimtexturelist.h | 127 ++++ linden/indra/llprimitive/lltextureentry.cpp | 314 ++++++++- linden/indra/llprimitive/lltextureentry.h | 66 +- linden/indra/llprimitive/material_codes.cpp | 46 ++ linden/indra/llprimitive/material_codes.h | 21 +- .../llprimitive/tests/llmediaentry_test.cpp | 508 +++++++++++++++ .../tests/llmessagesystem_stub.cpp | 53 ++ .../llprimitive/tests/llprimitive_test.cpp | 237 +++++++ linden/indra/newview/llselectmgr.cpp | 2 +- 20 files changed, 3121 insertions(+), 335 deletions(-) mode change 100644 => 100755 linden/indra/llcommon/lllslconstants.h create mode 100755 linden/indra/llmath/llsdutil_math.h mode change 100644 => 100755 linden/indra/llprimitive/CMakeLists.txt mode change 100644 => 100755 linden/indra/llprimitive/llmaterialtable.cpp mode change 100644 => 100755 linden/indra/llprimitive/llmaterialtable.h create mode 100755 linden/indra/llprimitive/llmediaentry.cpp create mode 100755 linden/indra/llprimitive/llmediaentry.h mode change 100644 => 100755 linden/indra/llprimitive/llprimitive.cpp mode change 100644 => 100755 linden/indra/llprimitive/llprimitive.h mode change 100644 => 100755 linden/indra/llprimitive/llprimlinkinfo.h create mode 100755 linden/indra/llprimitive/llprimtexturelist.cpp create mode 100755 linden/indra/llprimitive/llprimtexturelist.h mode change 100644 => 100755 linden/indra/llprimitive/lltextureentry.cpp mode change 100644 => 100755 linden/indra/llprimitive/lltextureentry.h create mode 100755 linden/indra/llprimitive/material_codes.cpp mode change 100644 => 100755 linden/indra/llprimitive/material_codes.h create mode 100755 linden/indra/llprimitive/tests/llmediaentry_test.cpp create mode 100755 linden/indra/llprimitive/tests/llmessagesystem_stub.cpp create mode 100755 linden/indra/llprimitive/tests/llprimitive_test.cpp diff --git a/linden/indra/llcommon/lllslconstants.h b/linden/indra/llcommon/lllslconstants.h old mode 100644 new mode 100755 index fc5363fb1..222b85dc8 --- a/linden/indra/llcommon/lllslconstants.h +++ b/linden/indra/llcommon/lllslconstants.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2006&license=viewergpl$ * - * Copyright (c) 2006-2009, Linden Research, Inc. + * Copyright (c) 2006-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab diff --git a/linden/indra/llmath/llsdutil_math.h b/linden/indra/llmath/llsdutil_math.h new file mode 100755 index 000000000..5b649425d --- /dev/null +++ b/linden/indra/llmath/llsdutil_math.h @@ -0,0 +1,70 @@ +/** + * @file llsdutil_math.h + * @author Brad + * @date 2009-05-19 + * @brief Utility classes, functions, etc, for using structured data with math classes. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSDUTIL_MATH_H +#define LL_LLSDUTIL_MATH_H + +class LL_COMMON_API LLSD; + +// vector3 +class LLVector3; +LLSD ll_sd_from_vector3(const LLVector3& vec); +LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index = 0); + +// vector4 +class LLVector4; +LLSD ll_sd_from_vector4(const LLVector4& vec); +LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index = 0); + +// vector3d (double) +class LLVector3d; +LLSD ll_sd_from_vector3d(const LLVector3d& vec); +LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index = 0); + +// vector2 +class LLVector2; +LLSD ll_sd_from_vector2(const LLVector2& vec); +LLVector2 ll_vector2_from_sd(const LLSD& sd); + +// Quaternion +class LLQuaternion; +LLSD ll_sd_from_quaternion(const LLQuaternion& quat); +LLQuaternion ll_quaternion_from_sd(const LLSD& sd); + +// color4 +class LLColor4; +LLSD ll_sd_from_color4(const LLColor4& c); +LLColor4 ll_color4_from_sd(const LLSD& sd); + +#endif // LL_LLSDUTIL_MATH_H diff --git a/linden/indra/llprimitive/CMakeLists.txt b/linden/indra/llprimitive/CMakeLists.txt old mode 100644 new mode 100755 index 5dc4c701a..e7ee81141 --- a/linden/indra/llprimitive/CMakeLists.txt +++ b/linden/indra/llprimitive/CMakeLists.txt @@ -17,12 +17,15 @@ include_directories( set(llprimitive_SOURCE_FILES llmaterialtable.cpp + llmediaentry.cpp llprimitive.cpp + llprimtexturelist.cpp lltextureanim.cpp lltextureentry.cpp lltreeparams.cpp llvolumemessage.cpp llvolumexml.cpp + material_codes.cpp ) set(llprimitive_HEADER_FILES @@ -30,7 +33,9 @@ set(llprimitive_HEADER_FILES legacy_object_types.h llmaterialtable.h + llmediaentry.h llprimitive.h + llprimtexturelist.h lltextureanim.h lltextureentry.h lltreeparams.h @@ -47,3 +52,10 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) + +#add unit tests +INCLUDE(LLAddBuildTest) +SET(llprimitive_TEST_SOURCE_FILES + llmediaentry.cpp + ) +#LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}") diff --git a/linden/indra/llprimitive/llmaterialtable.cpp b/linden/indra/llprimitive/llmaterialtable.cpp old mode 100644 new mode 100755 index 4c22203eb..f06bfe82e --- a/linden/indra/llprimitive/llmaterialtable.cpp +++ b/linden/indra/llprimitive/llmaterialtable.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -92,6 +92,9 @@ F32 const LLMaterialTable::DEFAULT_FRICTION = 0.5f; F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; LLMaterialTable::LLMaterialTable() + : mCollisionSoundMatrix(NULL), + mSlidingSoundMatrix(NULL), + mRollingSoundMatrix(NULL) { } @@ -124,6 +127,17 @@ LLMaterialTable::~LLMaterialTable() mMaterialInfoList.clear(); } +void LLMaterialTable::initTableTransNames(std::map<std::string, std::string> namemap) +{ + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + std::string name = infop->mName; + infop->mName = namemap[name]; + } +} + void LLMaterialTable::initBasicTable() { // *TODO: Translate diff --git a/linden/indra/llprimitive/llmaterialtable.h b/linden/indra/llprimitive/llmaterialtable.h old mode 100644 new mode 100755 index ca9017abd..7950c406b --- a/linden/indra/llprimitive/llmaterialtable.h +++ b/linden/indra/llprimitive/llmaterialtable.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -38,6 +38,8 @@ #include <list> +class LLMaterialInfo; + const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; // We've moved toward more reasonable mass values for the Havok4 engine. @@ -64,45 +66,6 @@ const F32 LEGACY_DEFAULT_OBJECT_DENSITY = 10.0f; const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; -class LLMaterialInfo -{ -public: - U8 mMCode; - std::string mName; - LLUUID mDefaultTextureID; - LLUUID mShatterSoundID; - F32 mDensity; // kg/m^3 - F32 mFriction; - F32 mRestitution; - - // damage and energy constants - F32 mHPModifier; // modifier on mass based HP total - F32 mDamageModifier; // modifier on KE based damage - F32 mEPModifier; // modifier on mass based EP total - - LLMaterialInfo(U8 mcode, const std::string& name, const LLUUID &uuid) - { - init(mcode,name,uuid); - }; - - void init(U8 mcode, const std::string& name, const LLUUID &uuid) - { - mDensity = 1000.f; // default to 1000.0 (water) - mHPModifier = 1.f; - mDamageModifier = 1.f; - mEPModifier = 1.f; - - mMCode = mcode; - mName = name; - mDefaultTextureID = uuid; - }; - - ~LLMaterialInfo() - { - }; - -}; - class LLMaterialTable { public: @@ -147,6 +110,8 @@ class LLMaterialTable void initBasicTable(); + void initTableTransNames(std::map<std::string, std::string> namemap); + BOOL add(U8 mcode, const std::string& name, const LLUUID &uuid); BOOL addCollisionSound(U8 mcode, U8 mcode2, const LLUUID &uuid); BOOL addSlidingSound(U8 mcode, U8 mcode2, const LLUUID &uuid); @@ -183,5 +148,47 @@ class LLMaterialTable static LLMaterialTable basic; }; + +class LLMaterialInfo +{ +public: + U8 mMCode; + std::string mName; + LLUUID mDefaultTextureID; + LLUUID mShatterSoundID; + F32 mDensity; // kg/m^3 + F32 mFriction; + F32 mRestitution; + + // damage and energy constants + F32 mHPModifier; // modifier on mass based HP total + F32 mDamageModifier; // modifier on KE based damage + F32 mEPModifier; // modifier on mass based EP total + + LLMaterialInfo(U8 mcode, const std::string& name, const LLUUID &uuid) + { + init(mcode,name,uuid); + }; + + void init(U8 mcode, const std::string& name, const LLUUID &uuid) + { + mDensity = 1000.f; // default to 1000.0 (water) + mFriction = LLMaterialTable::DEFAULT_FRICTION; + mRestitution = LLMaterialTable::DEFAULT_RESTITUTION; + mHPModifier = 1.f; + mDamageModifier = 1.f; + mEPModifier = 1.f; + + mMCode = mcode; + mName = name; + mDefaultTextureID = uuid; + }; + + ~LLMaterialInfo() + { + }; + +}; + #endif diff --git a/linden/indra/llprimitive/llmediaentry.cpp b/linden/indra/llprimitive/llmediaentry.cpp new file mode 100755 index 000000000..e4b31e221 --- /dev/null +++ b/linden/indra/llprimitive/llmediaentry.cpp @@ -0,0 +1,602 @@ +/** + * @file llmediaentry.cpp + * @brief This is a single instance of media data related to the face of a prim + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llmediaentry.h" +#include "lllslconstants.h" + +#include <boost/regex.hpp> + +// LLSD key defines +// DO NOT REORDER OR REMOVE THESE! + +// Some LLSD keys. Do not change! +#define MEDIA_ALT_IMAGE_ENABLE_KEY_STR "alt_image_enable" +#define MEDIA_CONTROLS_KEY_STR "controls" +#define MEDIA_CURRENT_URL_KEY_STR "current_url" +#define MEDIA_HOME_URL_KEY_STR "home_url" +#define MEDIA_AUTO_LOOP_KEY_STR "auto_loop" +#define MEDIA_AUTO_PLAY_KEY_STR "auto_play" +#define MEDIA_AUTO_SCALE_KEY_STR "auto_scale" +#define MEDIA_AUTO_ZOOM_KEY_STR "auto_zoom" +#define MEDIA_FIRST_CLICK_INTERACT_KEY_STR "first_click_interact" +#define MEDIA_WIDTH_PIXELS_KEY_STR "width_pixels" +#define MEDIA_HEIGHT_PIXELS_KEY_STR "height_pixels" + +// "security" fields +#define MEDIA_WHITELIST_ENABLE_KEY_STR "whitelist_enable" +#define MEDIA_WHITELIST_KEY_STR "whitelist" + +// "permissions" fields +#define MEDIA_PERMS_INTERACT_KEY_STR "perms_interact" +#define MEDIA_PERMS_CONTROL_KEY_STR "perms_control" + +// "general" fields +const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR; +const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR; +const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR; +const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR; +const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR; +const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR; +const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR; +const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR; +const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR; +const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR; +const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR; + +// "security" fields +const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR; +const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR; + +// "permissions" fields +const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR; +const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR; + +#define DEFAULT_URL_PREFIX "http://" + +// Constructor(s) +LLMediaEntry::LLMediaEntry() : + mAltImageEnable(false), + mControls(STANDARD), + mCurrentURL(""), + mHomeURL(""), + mAutoLoop(false), + mAutoPlay(false), + mAutoScale(false), + mAutoZoom(false), + mFirstClickInteract(false), + mWidthPixels(0), + mHeightPixels(0), + mWhiteListEnable(false), + // mWhiteList + mPermsInteract(PERM_ALL), + mPermsControl(PERM_ALL), + mMediaIDp(NULL) +{ +} + +LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) : + mMediaIDp(NULL) +{ + // "general" fields + mAltImageEnable = rhs.mAltImageEnable; + mControls = rhs.mControls; + mCurrentURL = rhs.mCurrentURL; + mHomeURL = rhs.mHomeURL; + mAutoLoop = rhs.mAutoLoop; + mAutoPlay = rhs.mAutoPlay; + mAutoScale = rhs.mAutoScale; + mAutoZoom = rhs.mAutoZoom; + mFirstClickInteract = rhs.mFirstClickInteract; + mWidthPixels = rhs.mWidthPixels; + mHeightPixels = rhs.mHeightPixels; + + // "security" fields + mWhiteListEnable = rhs.mWhiteListEnable; + mWhiteList = rhs.mWhiteList; + + // "permissions" fields + mPermsInteract = rhs.mPermsInteract; + mPermsControl = rhs.mPermsControl; +} + +LLMediaEntry::~LLMediaEntry() +{ + if (NULL != mMediaIDp) + { + delete mMediaIDp; + } +} + +LLSD LLMediaEntry::asLLSD() const +{ + LLSD sd; + asLLSD(sd); + return sd; +} + +// +// LLSD functions +// +void LLMediaEntry::asLLSD(LLSD& sd) const +{ + // "general" fields + sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable; + sd[CONTROLS_KEY] = (LLSD::Integer)mControls; + sd[CURRENT_URL_KEY] = mCurrentURL; + sd[HOME_URL_KEY] = mHomeURL; + sd[AUTO_LOOP_KEY] = mAutoLoop; + sd[AUTO_PLAY_KEY] = mAutoPlay; + sd[AUTO_SCALE_KEY] = mAutoScale; + sd[AUTO_ZOOM_KEY] = mAutoZoom; + sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract; + sd[WIDTH_PIXELS_KEY] = mWidthPixels; + sd[HEIGHT_PIXELS_KEY] = mHeightPixels; + + // "security" fields + sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable; + sd.erase(WHITELIST_KEY); + for (U32 i=0; i<mWhiteList.size(); i++) + { + sd[WHITELIST_KEY].append(mWhiteList[i]); + } + + // "permissions" fields + sd[PERMS_INTERACT_KEY] = mPermsInteract; + sd[PERMS_CONTROL_KEY] = mPermsControl; +} + +// static +bool LLMediaEntry::checkLLSD(const LLSD& sd) +{ + if (sd.isUndefined()) return true; + LLMediaEntry temp; + return temp.fromLLSDInternal(sd, true); +} + +void LLMediaEntry::fromLLSD(const LLSD& sd) +{ + (void)fromLLSDInternal(sd, true); +} + +void LLMediaEntry::mergeFromLLSD(const LLSD& sd) +{ + (void)fromLLSDInternal(sd, false); +} + +// *NOTE: returns true if NO failures to set occurred, false otherwise. +// However, be aware that if a failure to set does occur, it does +// not stop setting fields from the LLSD! +bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite) +{ + // *HACK: we sort of cheat here and assume that status is a + // bit field. We "or" into status and instead of returning + // it, we return whether it finishes off as LSL_STATUS_OK or not. + U32 status = LSL_STATUS_OK; + + // "general" fields + if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) ) + { + status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] ); + } + if ( overwrite || sd.has(CONTROLS_KEY) ) + { + status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] ); + } + if ( overwrite || sd.has(CURRENT_URL_KEY) ) + { + // Don't check whitelist + status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false ); + } + if ( overwrite || sd.has(HOME_URL_KEY) ) + { + status |= setHomeURL( sd[HOME_URL_KEY] ); + } + if ( overwrite || sd.has(AUTO_LOOP_KEY) ) + { + status |= setAutoLoop( sd[AUTO_LOOP_KEY] ); + } + if ( overwrite || sd.has(AUTO_PLAY_KEY) ) + { + status |= setAutoPlay( sd[AUTO_PLAY_KEY] ); + } + if ( overwrite || sd.has(AUTO_SCALE_KEY) ) + { + status |= setAutoScale( sd[AUTO_SCALE_KEY] ); + } + if ( overwrite || sd.has(AUTO_ZOOM_KEY) ) + { + status |= setAutoZoom( sd[AUTO_ZOOM_KEY] ); + } + if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) ) + { + status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] ); + } + if ( overwrite || sd.has(WIDTH_PIXELS_KEY) ) + { + status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] ); + } + if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) ) + { + status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] ); + } + + // "security" fields + if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) ) + { + status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] ); + } + if ( overwrite || sd.has(WHITELIST_KEY) ) + { + status |= setWhiteList( sd[WHITELIST_KEY] ); + } + + // "permissions" fields + if ( overwrite || sd.has(PERMS_INTERACT_KEY) ) + { + status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] ); + } + if ( overwrite || sd.has(PERMS_CONTROL_KEY) ) + { + status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] ); + } + + return LSL_STATUS_OK == status; +} + +LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs) +{ + if (this != &rhs) + { + // "general" fields + mAltImageEnable = rhs.mAltImageEnable; + mControls = rhs.mControls; + mCurrentURL = rhs.mCurrentURL; + mHomeURL = rhs.mHomeURL; + mAutoLoop = rhs.mAutoLoop; + mAutoPlay = rhs.mAutoPlay; + mAutoScale = rhs.mAutoScale; + mAutoZoom = rhs.mAutoZoom; + mFirstClickInteract = rhs.mFirstClickInteract; + mWidthPixels = rhs.mWidthPixels; + mHeightPixels = rhs.mHeightPixels; + + // "security" fields + mWhiteListEnable = rhs.mWhiteListEnable; + mWhiteList = rhs.mWhiteList; + + // "permissions" fields + mPermsInteract = rhs.mPermsInteract; + mPermsControl = rhs.mPermsControl; + } + + return *this; +} + +bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const +{ + return ( + // "general" fields + mAltImageEnable == rhs.mAltImageEnable && + mControls == rhs.mControls && + mCurrentURL == rhs.mCurrentURL && + mHomeURL == rhs.mHomeURL && + mAutoLoop == rhs.mAutoLoop && + mAutoPlay == rhs.mAutoPlay && + mAutoScale == rhs.mAutoScale && + mAutoZoom == rhs.mAutoZoom && + mFirstClickInteract == rhs.mFirstClickInteract && + mWidthPixels == rhs.mWidthPixels && + mHeightPixels == rhs.mHeightPixels && + + // "security" fields + mWhiteListEnable == rhs.mWhiteListEnable && + mWhiteList == rhs.mWhiteList && + + // "permissions" fields + mPermsInteract == rhs.mPermsInteract && + mPermsControl == rhs.mPermsControl + + ); +} + +bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const +{ + return ( + // "general" fields + mAltImageEnable != rhs.mAltImageEnable || + mControls != rhs.mControls || + mCurrentURL != rhs.mCurrentURL || + mHomeURL != rhs.mHomeURL || + mAutoLoop != rhs.mAutoLoop || + mAutoPlay != rhs.mAutoPlay || + mAutoScale != rhs.mAutoScale || + mAutoZoom != rhs.mAutoZoom || + mFirstClickInteract != rhs.mFirstClickInteract || + mWidthPixels != rhs.mWidthPixels || + mHeightPixels != rhs.mHeightPixels || + + // "security" fields + mWhiteListEnable != rhs.mWhiteListEnable || + mWhiteList != rhs.mWhiteList || + + // "permissions" fields + mPermsInteract != rhs.mPermsInteract || + mPermsControl != rhs.mPermsControl + + ); +} + +U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist ) +{ + // *NOTE: This code is VERY similar to the setWhitelist below. + // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER! + U32 size = 0; + U32 count = 0; + // First count to make sure the size constraint is not violated + std::vector<std::string>::const_iterator iter = whitelist.begin(); + std::vector<std::string>::const_iterator end = whitelist.end(); + for ( ; iter < end; ++iter) + { + const std::string &entry = (*iter); + size += entry.length() + 1; // Include one for \0 + count ++; + if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) + { + return LSL_STATUS_BOUNDS_ERROR; + } + } + // Next clear the vector + mWhiteList.clear(); + // Then re-iterate and copy entries + iter = whitelist.begin(); + for ( ; iter < end; ++iter) + { + const std::string &entry = (*iter); + mWhiteList.push_back(entry); + } + return LSL_STATUS_OK; +} + +U32 LLMediaEntry::setWhiteList( const LLSD &whitelist ) +{ + // If whitelist is undef, the whitelist is cleared + if (whitelist.isUndefined()) + { + mWhiteList.clear(); + return LSL_STATUS_OK; + } + + // However, if the whitelist is an empty array, erase it. + if (whitelist.isArray()) + { + // *NOTE: This code is VERY similar to the setWhitelist above. + // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER! + U32 size = 0; + U32 count = 0; + // First check to make sure the size and count constraints are not violated + LLSD::array_const_iterator iter = whitelist.beginArray(); + LLSD::array_const_iterator end = whitelist.endArray(); + for ( ; iter < end; ++iter) + { + const std::string &entry = (*iter).asString(); + size += entry.length() + 1; // Include one for \0 + count ++; + if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) + { + return LSL_STATUS_BOUNDS_ERROR; + } + } + // Next clear the vector + mWhiteList.clear(); + // Then re-iterate and copy entries + iter = whitelist.beginArray(); + for ( ; iter < end; ++iter) + { + const std::string &entry = (*iter).asString(); + mWhiteList.push_back(entry); + } + return LSL_STATUS_OK; + } + else + { + return LSL_STATUS_MALFORMED_PARAMS; + } +} + + +static void prefix_with(std::string &str, const char *chars, const char *prefix) +{ + // Given string 'str', prefix all instances of any character in 'chars' + // with 'prefix' + size_t found = str.find_first_of(chars); + size_t prefix_len = strlen(prefix); + while (found != std::string::npos) + { + str.insert(found, prefix, prefix_len); + found = str.find_first_of(chars, found+prefix_len+1); + } +} + +static bool pattern_match(const std::string &candidate_str, const std::string &pattern) +{ + // If the pattern is empty, it matches + if (pattern.empty()) return true; + + // 'pattern' is a glob pattern, we only accept '*' chars + // copy it + std::string expression = pattern; + + // Escape perl's regexp chars with a backslash, except all "*" chars + prefix_with(expression, ".[{()\\+?|^$", "\\"); + prefix_with(expression, "*", "."); + + // case-insensitive matching: + boost::regex regexp(expression, boost::regex::perl|boost::regex::icase); + return boost::regex_match(candidate_str, regexp); +} + +bool LLMediaEntry::checkCandidateUrl(const std::string& url) const +{ + if (getWhiteListEnable()) + { + return checkUrlAgainstWhitelist(url, getWhiteList()); + } + else + { + return true; + } +} + +// static +bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url, + const std::vector<std::string> &whitelist) +{ + bool passes = true; + // *NOTE: no entries? Don't check + if (whitelist.size() > 0) + { + passes = false; + + // Case insensitive: the reason why we toUpper both this and the + // filter + std::string candidate_url = url; + // Use lluri to see if there is a path part in the candidate URL. No path? Assume "/" + LLURI candidate_uri(candidate_url); + std::vector<std::string>::const_iterator iter = whitelist.begin(); + std::vector<std::string>::const_iterator end = whitelist.end(); + for ( ; iter < end; ++iter ) + { + std::string filter = *iter; + + LLURI filter_uri(filter); + bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() ); + if (filter_uri.scheme().empty()) + { + filter_uri = LLURI(DEFAULT_URL_PREFIX + filter); + } + bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() ); + bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() ); + + if (scheme_passes && authority_passes && path_passes) + { + passes = true; + break; + } + } + } + return passes; +} + +U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit ) +{ + if ( value.length() > limit ) + { + return LSL_STATUS_BOUNDS_ERROR; + } + else + { + field = value; + return LSL_STATUS_OK; + } +} + +U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls) +{ + if (controls == STANDARD || + controls == MINI) + { + mControls = controls; + return LSL_STATUS_OK; + } + return LSL_STATUS_BOUNDS_ERROR; +} + +U32 LLMediaEntry::setPermsInteract( U8 val ) +{ + mPermsInteract = val & PERM_MASK; + return LSL_STATUS_OK; +} + +U32 LLMediaEntry::setPermsControl( U8 val ) +{ + mPermsControl = val & PERM_MASK; + return LSL_STATUS_OK; +} + +U32 LLMediaEntry::setCurrentURL(const std::string& current_url) +{ + return setCurrentURLInternal( current_url, true ); +} + +U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist) +{ + if ( ! check_whitelist || checkCandidateUrl(current_url)) + { + return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH ); + } + else + { + return LSL_STATUS_WHITELIST_FAILED; + } +} + +U32 LLMediaEntry::setHomeURL(const std::string& home_url) +{ + return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH ); +} + +U32 LLMediaEntry::setWidthPixels(U16 width) +{ + if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR; + mWidthPixels = width; + return LSL_STATUS_OK; +} + +U32 LLMediaEntry::setHeightPixels(U16 height) +{ + if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR; + mHeightPixels = height; + return LSL_STATUS_OK; +} + +const LLUUID &LLMediaEntry::getMediaID() const +{ + // Lazily generate media ID + if (NULL == mMediaIDp) + { + mMediaIDp = new LLUUID(); + mMediaIDp->generate(); + } + return *mMediaIDp; +} + diff --git a/linden/indra/llprimitive/llmediaentry.h b/linden/indra/llprimitive/llmediaentry.h new file mode 100755 index 000000000..ca52e6e23 --- /dev/null +++ b/linden/indra/llprimitive/llmediaentry.h @@ -0,0 +1,228 @@ +/** + * @file llmediaentry.h + * @brief This is a single instance of media data related to the face of a prim + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLMEDIAENTRY_H +#define LL_LLMEDIAENTRY_H + +#include "llsd.h" +#include "llstring.h" + +// For return values of set* +#include "lllslconstants.h" + +class LLMediaEntry +{ +public: + enum MediaControls { + STANDARD = 0, + MINI + }; + + // Constructors + LLMediaEntry(); + LLMediaEntry(const LLMediaEntry &rhs); + + LLMediaEntry &operator=(const LLMediaEntry &rhs); + virtual ~LLMediaEntry(); + + bool operator==(const LLMediaEntry &rhs) const; + bool operator!=(const LLMediaEntry &rhs) const; + + // Render as LLSD + LLSD asLLSD() const; + void asLLSD(LLSD& sd) const; + operator LLSD() const { return asLLSD(); } + // Returns false iff the given LLSD contains fields that violate any bounds + // limits. + static bool checkLLSD(const LLSD& sd); + // This doesn't merge, it overwrites the data, so will use + // LLSD defaults if need be. Note: does not check limits! + // Use checkLLSD() above first to ensure the LLSD is valid. + void fromLLSD(const LLSD& sd); + // This merges data from the incoming LLSD into our fields. + // Note that it also does NOT check limits! Use checkLLSD() above first. + void mergeFromLLSD(const LLSD& sd); + + // "general" fields + bool getAltImageEnable() const { return mAltImageEnable; } + MediaControls getControls() const { return mControls; } + std::string getCurrentURL() const { return mCurrentURL; } + std::string getHomeURL() const { return mHomeURL; } + bool getAutoLoop() const { return mAutoLoop; } + bool getAutoPlay() const { return mAutoPlay; } + bool getAutoScale() const { return mAutoScale; } + bool getAutoZoom() const { return mAutoZoom; } + bool getFirstClickInteract() const { return mFirstClickInteract; } + U16 getWidthPixels() const { return mWidthPixels; } + U16 getHeightPixels() const { return mHeightPixels; } + + // "security" fields + bool getWhiteListEnable() const { return mWhiteListEnable; } + const std::vector<std::string> &getWhiteList() const { return mWhiteList; } + + // "permissions" fields + U8 getPermsInteract() const { return mPermsInteract; } + U8 getPermsControl() const { return mPermsControl; } + + // Setters. Those that return a U32 return a status error code + // See lllslconstants.h + + // "general" fields + U32 setAltImageEnable(bool alt_image_enable) { mAltImageEnable = alt_image_enable; return LSL_STATUS_OK; } + U32 setControls(MediaControls controls); + U32 setCurrentURL(const std::string& current_url); + U32 setHomeURL(const std::string& home_url); + U32 setAutoLoop(bool auto_loop) { mAutoLoop = auto_loop; return LSL_STATUS_OK; } + U32 setAutoPlay(bool auto_play) { mAutoPlay = auto_play; return LSL_STATUS_OK; } + U32 setAutoScale(bool auto_scale) { mAutoScale = auto_scale; return LSL_STATUS_OK; } + U32 setAutoZoom(bool auto_zoom) { mAutoZoom = auto_zoom; return LSL_STATUS_OK; } + U32 setFirstClickInteract(bool first_click) { mFirstClickInteract = first_click; return LSL_STATUS_OK; } + U32 setWidthPixels(U16 width); + U32 setHeightPixels(U16 height); + + // "security" fields + U32 setWhiteListEnable( bool whitelist_enable ) { mWhiteListEnable = whitelist_enable; return LSL_STATUS_OK; } + U32 setWhiteList( const std::vector<std::string> &whitelist ); + U32 setWhiteList( const LLSD &whitelist ); // takes an LLSD array + + // "permissions" fields + U32 setPermsInteract( U8 val ); + U32 setPermsControl( U8 val ); + + const LLUUID& getMediaID() const; + + // Helper function to check a candidate URL against the whitelist + // Returns true iff candidate URL passes (or if there is no whitelist), false otherwise + bool checkCandidateUrl(const std::string& url) const; + +public: + // Static function to check a URL against a whitelist + // Returns true iff url passes the given whitelist + static bool checkUrlAgainstWhitelist(const std::string &url, + const std::vector<std::string> &whitelist); + +public: + // LLSD key defines + // "general" fields + static const char* ALT_IMAGE_ENABLE_KEY; + static const char* CONTROLS_KEY; + static const char* CURRENT_URL_KEY; + static const char* HOME_URL_KEY; + static const char* AUTO_LOOP_KEY; + static const char* AUTO_PLAY_KEY; + static const char* AUTO_SCALE_KEY; + static const char* AUTO_ZOOM_KEY; + static const char* FIRST_CLICK_INTERACT_KEY; + static const char* WIDTH_PIXELS_KEY; + static const char* HEIGHT_PIXELS_KEY; + + // "security" fields + static const char* WHITELIST_ENABLE_KEY; + static const char* WHITELIST_KEY; + + // "permissions" fields + static const char* PERMS_INTERACT_KEY; + static const char* PERMS_CONTROL_KEY; + + // Field enumerations & constants + + // *NOTE: DO NOT change the order of these, and do not insert values + // in the middle! + // Add values to the end, and make sure to change PARAM_MAX_ID! + enum Fields { + ALT_IMAGE_ENABLE_ID = 0, + CONTROLS_ID = 1, + CURRENT_URL_ID = 2, + HOME_URL_ID = 3, + AUTO_LOOP_ID = 4, + AUTO_PLAY_ID = 5, + AUTO_SCALE_ID = 6, + AUTO_ZOOM_ID = 7, + FIRST_CLICK_INTERACT_ID = 8, + WIDTH_PIXELS_ID = 9, + HEIGHT_PIXELS_ID = 10, + WHITELIST_ENABLE_ID = 11, + WHITELIST_ID = 12, + PERMS_INTERACT_ID = 13, + PERMS_CONTROL_ID = 14, + PARAM_MAX_ID = PERMS_CONTROL_ID + }; + + // "permissions" values + // (e.g. (PERM_OWNER | PERM_GROUP) sets permissions on for OWNER and GROUP + static const U8 PERM_NONE = 0x0; + static const U8 PERM_OWNER = 0x1; + static const U8 PERM_GROUP = 0x2; + static const U8 PERM_ANYONE = 0x4; + static const U8 PERM_ALL = PERM_OWNER|PERM_GROUP|PERM_ANYONE; + static const U8 PERM_MASK = PERM_OWNER|PERM_GROUP|PERM_ANYONE; + + // Limits (in bytes) + static const U32 MAX_URL_LENGTH = 1024; + static const U32 MAX_WHITELIST_SIZE = 1024; + static const U32 MAX_WHITELIST_COUNT = 64; + static const U16 MAX_WIDTH_PIXELS = 2048; + static const U16 MAX_HEIGHT_PIXELS = 2048; + +private: + + U32 setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit ); + U32 setCurrentURLInternal( const std::string &url, bool check_whitelist); + bool fromLLSDInternal(const LLSD &sd, bool overwrite); + +private: + // "general" fields + bool mAltImageEnable; + MediaControls mControls; + std::string mCurrentURL; + std::string mHomeURL; + bool mAutoLoop; + bool mAutoPlay; + bool mAutoScale; + bool mAutoZoom; + bool mFirstClickInteract; + U16 mWidthPixels; + U16 mHeightPixels; + + // "security" fields + bool mWhiteListEnable; + std::vector<std::string> mWhiteList; + + // "permissions" fields + U8 mPermsInteract; + U8 mPermsControl; + + mutable LLUUID *mMediaIDp; // temporary id assigned to media on the viewer +}; + +#endif + diff --git a/linden/indra/llprimitive/llprimitive.cpp b/linden/indra/llprimitive/llprimitive.cpp old mode 100644 new mode 100755 index f1b7522ca..754676456 --- a/linden/indra/llprimitive/llprimitive.cpp +++ b/linden/indra/llprimitive/llprimitive.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -43,7 +43,8 @@ #include "llvolumemgr.h" #include "llstring.h" #include "lldatapacker.h" -#include "llsdutil.h" +#include "llsdutil.h"//_math.h" +#include "llprimtexturelist.h" /** * exported constants @@ -111,6 +112,7 @@ const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f; const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; +const S32 MAX_FACE_BITS = 9; const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; @@ -129,7 +131,7 @@ void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager ) { if ( !volume_manager || sVolumeManager ) { - llerrs << "Unable to set LLPrimitive::sVolumeManager to NULL" << llendl; + llerrs << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << llendl; } sVolumeManager = volume_manager; } @@ -150,7 +152,9 @@ bool LLPrimitive::cleanupVolumeManager() //=============================================================== LLPrimitive::LLPrimitive() -: mMiscFlags(0) +: mTextureList(), + mNumTEs(0), + mMiscFlags(0) { mPrimitiveCode = 0; @@ -167,20 +171,12 @@ LLPrimitive::LLPrimitive() mAngularVelocity.setVec(0.f,0.f,0.f); mScale.setVec(1.f,1.f,1.f); - - mNumTEs = 0; - mTextureList = NULL; } //=============================================================== LLPrimitive::~LLPrimitive() { - if (mTextureList) - { - delete [] mTextureList; - mTextureList = NULL; - } - + clearTextureList(); // Cleanup handled by volume manager if (mVolumep) { @@ -189,6 +185,10 @@ LLPrimitive::~LLPrimitive() mVolumep = NULL; } +void LLPrimitive::clearTextureList() +{ +} + //=============================================================== // static LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) @@ -212,15 +212,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) void LLPrimitive::init_primitive(LLPCode p_code) { LLMemType m1(LLMemType::MTYPE_PRIMITIVE); - if (mNumTEs) - { - if (mTextureList) - { - delete [] mTextureList; - } - mTextureList = new LLTextureEntry[mNumTEs]; - } - + clearTextureList(); mPrimitiveCode = p_code; } @@ -230,82 +222,30 @@ void LLPrimitive::setPCode(const U8 p_code) } //=============================================================== -const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const +LLTextureEntry* LLPrimitive::getTE(const U8 index) const { - // if we're asking for a non-existent face, return null - if (mNumTEs && (te_num< mNumTEs)) - { - return(&mTextureList[te_num]); - } - else - { - return(NULL); - } + return mTextureList.getTexture(index); } //=============================================================== void LLPrimitive::setNumTEs(const U8 num_tes) { - if (num_tes == mNumTEs) - { - return; - } - - // Right now, we don't try and preserve entries when the number of faces - // changes. - - LLMemType m1(LLMemType::MTYPE_PRIMITIVE); - if (num_tes) - { - LLTextureEntry *new_tes; - new_tes = new LLTextureEntry[num_tes]; - U32 i; - for (i = 0; i < num_tes; i++) - { - if (i < mNumTEs) - { - new_tes[i] = mTextureList[i]; - } - else if (mNumTEs) - { - new_tes[i] = mTextureList[mNumTEs - 1]; - } - else - { - new_tes[i] = LLTextureEntry(); - } - } - delete[] mTextureList; - mTextureList = new_tes; - } - else - { - delete[] mTextureList; - mTextureList = NULL; - } - - - mNumTEs = num_tes; + mTextureList.setSize(num_tes); } //=============================================================== void LLPrimitive::setAllTETextures(const LLUUID &tex_id) { - U8 i; - - for (i = 0; i < mNumTEs; i++) - { - mTextureList[i].setID(tex_id); - } + mTextureList.setAllIDs(tex_id); } //=============================================================== -void LLPrimitive::setTE(const U8 index, const LLTextureEntry &te) +void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) { - mTextureList[index] = te; + mTextureList.copyTexture(index, te); } -S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id) +S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -314,10 +254,10 @@ S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id) return 0; } - return mTextureList[te].setID(tex_id); + return mTextureList.setID(index, id); } -S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color) +S32 LLPrimitive::setTEColor(const U8 index, const LLColor4 &color) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -326,10 +266,11 @@ S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color) return 0; } - return mTextureList[te].setColor(color); + + return mTextureList.setColor(index, color); } -S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color) +S32 LLPrimitive::setTEColor(const U8 index, const LLColor3 &color) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -338,10 +279,10 @@ S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color) return 0; } - return mTextureList[te].setColor(color); + return mTextureList.setColor(index, color); } -S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha) +S32 LLPrimitive::setTEAlpha(const U8 index, const F32 alpha) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -350,117 +291,64 @@ S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha) return 0; } - return mTextureList[te].setAlpha(alpha); + return mTextureList.setAlpha(index, alpha); } //=============================================================== -S32 LLPrimitive::setTEScale(const U8 te, const F32 s, const F32 t) +S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - return mTextureList[te].setScale(s,t); + return mTextureList.setScale(index, s, t); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEScaleS(const U8 te, const F32 s) +S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 ignore, t; - mTextureList[te].getScale(&ignore, &t); - return mTextureList[te].setScale(s,t); + return mTextureList.setScaleS(index, s); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEScaleT(const U8 te, const F32 t) +S32 LLPrimitive::setTEScaleT(const U8 index, const F32 t) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 s, ignore; - mTextureList[te].getScale(&s, &ignore); - return mTextureList[te].setScale(s,t); + return mTextureList.setScaleT(index, t); } //=============================================================== -S32 LLPrimitive::setTEOffset(const U8 te, const F32 s, const F32 t) +S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - return mTextureList[te].setOffset(s,t); + return mTextureList.setOffset(index, s, t); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEOffsetS(const U8 te, const F32 s) +S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 ignore, t; - mTextureList[te].getOffset(&ignore, &t); - return mTextureList[te].setOffset(s,t); + return mTextureList.setOffsetS(index, s); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEOffsetT(const U8 te, const F32 t) +S32 LLPrimitive::setTEOffsetT(const U8 index, const F32 t) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 s, ignore; - mTextureList[te].getOffset(&s, &ignore); - return mTextureList[te].setOffset(s,t); + return mTextureList.setOffsetT(index, t); } //=============================================================== -S32 LLPrimitive::setTERotation(const U8 te, const F32 r) +S32 LLPrimitive::setTERotation(const U8 index, const F32 r) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - return mTextureList[te].setRotation(r); + return mTextureList.setRotation(index, r); } //=============================================================== -S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump) +S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -469,10 +357,10 @@ S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump) return 0; } - return mTextureList[te].setBumpShinyFullbright( bump ); + return mTextureList.setBumpShinyFullbright(index, bump); } -S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media) +S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -481,10 +369,10 @@ S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media) return 0; } - return mTextureList[te].setMediaTexGen( media ); + return mTextureList.setMediaTexGen(index, media); } -S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump) +S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -493,10 +381,10 @@ S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump) return 0; } - return mTextureList[te].setBumpmap( bump ); + return mTextureList.setBumpMap(index, bump); } -S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny) +S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -505,10 +393,10 @@ S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny) return 0; } - return mTextureList[te].setBumpShiny( bump_shiny ); + return mTextureList.setBumpShiny(index, bump_shiny); } -S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen) +S32 LLPrimitive::setTETexGen(const U8 index, const U8 texgen) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -517,10 +405,10 @@ S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen) return 0; } - return mTextureList[te].setTexGen( texgen ); + return mTextureList.setTexGen(index, texgen); } -S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny) +S32 LLPrimitive::setTEShiny(const U8 index, const U8 shiny) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -529,11 +417,13 @@ S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny) return 0; } - return mTextureList[te].setShiny( shiny ); + + return mTextureList.setShiny(index, shiny); } -S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright) +S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright) { + // if we're asking for a non-existent face, return null if (te >= mNumTEs) { @@ -541,10 +431,10 @@ S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright) return 0; } - return mTextureList[te].setFullbright( fullbright ); + return mTextureList.setFullbright(index, fullbright); } -S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags) +S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -553,10 +443,10 @@ S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags) return 0; } - return mTextureList[te].setMediaFlags( media_flags ); + return mTextureList.setMediaFlags(index, media_flags); } -S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) +S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow) { // if we're asking for a non-existent face, return null if (te >= mNumTEs) @@ -565,7 +455,7 @@ S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) return 0; } - return mTextureList[te].setGlow( glow ); + return mTextureList.setGlow(index, glow); } @@ -877,25 +767,18 @@ std::string LLPrimitive::pCodeToString(const LLPCode pcode) void LLPrimitive::copyTEs(const LLPrimitive *primitivep) { U32 i; - if (primitivep->getNumTEs() != getNumTEs()) + if (primitivep->getExpectedNumTEs() != getExpectedNumTEs()) + { + llwarns << "Primitives don't have same expected number of TE's" << llendl; + } + U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs()); + if (mTextureList.size() < getExpectedNumTEs()) { - llwarns << "Primitives don't have same number of TE's" << llendl; + mTextureList.setSize(getExpectedNumTEs()); } - U32 num_tes = llmin(primitivep->getNumTEs(), getNumTEs()); for (i = 0; i < num_tes; i++) { - const LLTextureEntry *tep = primitivep->getTE(i); - F32 s, t; - setTETexture(i, tep->getID()); - setTEColor(i, tep->getColor()); - tep->getScale(&s, &t); - setTEScale(i, s, t); - tep->getOffset(&s, &t); - setTEOffset(i, s, t); - setTERotation(i, tep->getRotation()); - setTEBumpShinyFullbright(i, tep->getBumpShinyFullbright()); - setTEMediaTexGen(i, tep->getMediaTexGen()); - setTEGlow(i, tep->getGlow()); + mTextureList.copyTexture(i, *(primitivep->getTE(i))); } } @@ -957,73 +840,209 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai U32 old_face_mask = mVolumep->mFaceMask; + + S32 face_bit = 0; + S32 cur_mask = 0; + + // Grab copies of the old faces from the original shape, ordered by type. + // We will use these to figure out what old texture info gets mapped to new + // faces in the new shape. + std::vector<LLProfile::Face> old_faces; + for (S32 face = 0; face < mVolumep->getNumFaces(); face++) + { + old_faces.push_back(mVolumep->getProfile().mFaces[face]); + } + + // Copy the old texture info off to the side, but not in the order in which + // they live in the mTextureList, rather in order of ther "face id" which + // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex. + // + // Hence, some elements of old_tes::mEntryList will be invalid. It is + // initialized to a size of 9 (max number of possible faces on a volume?) + // and only the ones with valid types are filled in. + LLPrimTextureList old_tes; + old_tes.setSize(9); + for (face_bit = 0; face_bit < 9; face_bit++) + { + cur_mask = 0x1 << face_bit; + if (old_face_mask & cur_mask) + { + S32 te_index = face_index_from_id(cur_mask, old_faces); + old_tes.copyTexture(face_bit, *(getTE(te_index))); + //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl; + } + } + + // build the new object sVolumeManager->unrefVolume(mVolumep); mVolumep = volumep; - U32 new_face_mask = mVolumep->mFaceMask; - if (old_face_mask != new_face_mask) - { - setNumTEs(mVolumep->getNumFaces()); - } - - return TRUE; -} + U32 new_face_mask = mVolumep->mFaceMask; + S32 i; -BOOL LLPrimitive::setMaterial(U8 material) -{ - if (material != mMaterial) + if (old_face_mask == new_face_mask) { - mMaterial = material; + setNumTEs(mVolumep->getNumFaces()); return TRUE; } - else - { - return FALSE; - } -} -void LLPrimitive::setTEArrays(const U8 size, - const LLUUID* image_ids, - const F32* scale_s, - const F32* scale_t) -{ - S32 cur_size = size; - if (cur_size > getNumTEs()) + // initialize face_mapping + S32 face_mapping[9]; + for (face_bit = 0; face_bit < 9; face_bit++) { - llwarns << "Trying to set more TEs than exist!" << llendl; - cur_size = getNumTEs(); + face_mapping[face_bit] = face_bit; } - S32 i; - // Copy over image information - for (i = 0; i < cur_size; i++) + // The new shape may have more faces than the original, but we can't just + // add them to the end -- the ordering matters and it may be that we must + // insert the new faces in the middle of the list. When we add a face it + // will pick up the texture/color info of one of the old faces an so we + // now figure out which old face info gets mapped to each new face, and + // store in the face_mapping lookup table. + for (face_bit = 0; face_bit < 9; face_bit++) { - // This is very BAD!!!!!! - if (image_ids != NULL) + cur_mask = 0x1 << face_bit; + if (!(new_face_mask & cur_mask)) { - setTETexture(i,image_ids[i]); + // Face doesn't exist in new map. + face_mapping[face_bit] = -1; + continue; } - if (scale_s && scale_t) + else if (old_face_mask & cur_mask) { - setTEScale(i, scale_s[i], scale_t[i]); + // Face exists in new and old map. + face_mapping[face_bit] = face_bit; + continue; } - } - if (i < getNumTEs()) - { - cur_size--; - for (i=i; i < getNumTEs(); i++) // the i=i removes a gcc warning + // OK, how we've got a mismatch, where we have to fill a new face with one from + // the old face. + if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE)) { - if (image_ids != NULL) + // It's a top/bottom/hollow interior face. + if (old_face_mask & LL_FACE_PATH_END) { - setTETexture(i, image_ids[cur_size]); + face_mapping[face_bit] = 1; + continue; } - if (scale_s && scale_t) + else { - setTEScale(i, scale_s[cur_size], scale_t[cur_size]); + S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; + for (i = 0; i < 4; i++) + { + if (old_face_mask & cur_outer_mask) + { + face_mapping[face_bit] = 5 + i; + break; + } + cur_outer_mask <<= 1; + } + if (i == 4) + { + llwarns << "No path end or outer face in volume!" << llendl; + } + continue; + } + } + + if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) + { + // A cut slice. Use the hollow interior if we have it. + if (old_face_mask & LL_FACE_INNER_SIDE) + { + face_mapping[face_bit] = 2; + continue; + } + + // No interior, use the bottom face. + // Could figure out which of the outer faces was nearest, but that would be harder. + if (old_face_mask & LL_FACE_PATH_END) + { + face_mapping[face_bit] = 1; + continue; + } + else + { + S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; + for (i = 0; i < 4; i++) + { + if (old_face_mask & cur_outer_mask) + { + face_mapping[face_bit] = 5 + i; + break; + } + cur_outer_mask <<= 1; + } + if (i == 4) + { + llwarns << "No path end or outer face in volume!" << llendl; + } + continue; + } + } + + // OK, the face that's missing is an outer face... + // Pull from the nearest adjacent outer face (there's always guaranteed to be one... + S32 cur_outer = face_bit - 5; + S32 min_dist = 5; + S32 min_outer_bit = -1; + S32 i; + for (i = 0; i < 4; i++) + { + if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i)) + { + S32 dist = abs(i - cur_outer); + if (dist < min_dist) + { + min_dist = dist; + min_outer_bit = i + 5; + } } } + if (-1 == min_outer_bit) + { + llinfos << (LLVolume *)mVolumep << llendl; + llwarns << "Bad! No outer faces, impossible!" << llendl; + } + face_mapping[face_bit] = min_outer_bit; + } + + + setNumTEs(mVolumep->getNumFaces()); + for (face_bit = 0; face_bit < 9; face_bit++) + { + // For each possible face type on the new shape we check to see if that + // face exists and if it does we create a texture entry that is a copy + // of one of the originals. Since the originals might not have a + // matching face, we use the face_mapping lookup table to figure out + // which face information to copy. + cur_mask = 0x1 << face_bit; + if (new_face_mask & cur_mask) + { + if (-1 == face_mapping[face_bit]) + { + llwarns << "No mapping from old face to new face!" << llendl; + } + + S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); + setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); + } + } +>>>>>>> 5faaca1... port llprimitive from SG2.0 + return TRUE; +} + +BOOL LLPrimitive::setMaterial(U8 material) +{ + if (material != mMaterial) + { + mMaterial = material; + return TRUE; + } + else + { + return FALSE; } } @@ -1178,6 +1197,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys, int shield) const else memcpy(&image_ids[face_index*16],LLUUID("4934f1bf-3b1f-cf4f-dbdf-a72550d05bc6").mData,16);//grey block }else memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ + // Cast LLColor4 to LLColor4U coloru.setVec( getTE(face_index)->getColor() ); @@ -1402,6 +1422,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f; retval |= setTEColor(i, color); + } return retval; @@ -1501,11 +1522,24 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) return retval; } -void LLPrimitive::setTextureList(LLTextureEntry *listp) +U8 LLPrimitive::getExpectedNumTEs() const +{ + U8 expected_face_count = 0; + if (mVolumep) + { + expected_face_count = mVolumep->getNumFaces(); + } + return expected_face_count; +} + +void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list) +{ + mTextureList.copy(other_list); +} + +void LLPrimitive::takeTextureList(LLPrimTextureList& other_list) { - LLTextureEntry* old_texture_list = mTextureList; - mTextureList = listp; - delete[] old_texture_list; + mTextureList.take(other_list); } //============================================================================ @@ -1569,6 +1603,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) return (size == 16); case PARAMS_SCULPT: return (size == 17); + case PARAMS_LIGHT_IMAGE: + return (size == 28); } return FALSE; @@ -1901,3 +1937,78 @@ bool LLSculptParams::fromLLSD(LLSD& sd) return false; } +//============================================================================ + +LLLightImageParams::LLLightImageParams() +{ + mType = PARAMS_LIGHT_IMAGE; + mParams.setVec(F_PI*0.5f, 0.f, 0.f); +} + +BOOL LLLightImageParams::pack(LLDataPacker &dp) const +{ + dp.packUUID(mLightTexture, "texture"); + dp.packVector3(mParams, "params"); + + return TRUE; +} + +BOOL LLLightImageParams::unpack(LLDataPacker &dp) +{ + dp.unpackUUID(mLightTexture, "texture"); + dp.unpackVector3(mParams, "params"); + + return TRUE; +} + +bool LLLightImageParams::operator==(const LLNetworkData& data) const +{ + if (data.mType != PARAMS_LIGHT_IMAGE) + { + return false; + } + + const LLLightImageParams *param = (const LLLightImageParams*)&data; + if ( (param->mLightTexture != mLightTexture) ) + { + return false; + } + + if ( (param->mParams != mParams ) ) + { + return false; + } + + return true; +} + +void LLLightImageParams::copy(const LLNetworkData& data) +{ + const LLLightImageParams *param = (LLLightImageParams*)&data; + mLightTexture = param->mLightTexture; + mParams = param->mParams; +} + + + +LLSD LLLightImageParams::asLLSD() const +{ + LLSD sd; + + sd["texture"] = mLightTexture; + sd["params"] = mParams.getValue(); + + return sd; +} + +bool LLLightImageParams::fromLLSD(LLSD& sd) +{ + if (sd.has("texture")) + { + setLightTexture( sd["texture"] ); + setParams( LLVector3( sd["params"] ) ); + return true; + } + + return false; +} diff --git a/linden/indra/llprimitive/llprimitive.h b/linden/indra/llprimitive/llprimitive.h old mode 100644 new mode 100755 index efabb8251..e146fbe93 --- a/linden/indra/llprimitive/llprimitive.h +++ b/linden/indra/llprimitive/llprimitive.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -37,9 +37,11 @@ #include "v3math.h" #include "xform.h" #include "message.h" -#include "llmemory.h" +#include "llmemory.h" // not in SG2.0 +//#include "llpointer.h"// instead in SG2.0 #include "llvolume.h" #include "lltextureentry.h" +#include "llprimtexturelist.h" // Moved to stdtypes.h --JC // typedef U8 LLPCode; @@ -105,7 +107,8 @@ class LLNetworkData { PARAMS_FLEXIBLE = 0x10, PARAMS_LIGHT = 0x20, - PARAMS_SCULPT = 0x30 + PARAMS_SCULPT = 0x30, + PARAMS_LIGHT_IMAGE = 0x40, }; public: @@ -260,11 +263,33 @@ class LLSculptParams : public LLNetworkData bool fromLLSD(LLSD& sd); void setSculptTexture(const LLUUID& id) { mSculptTexture = id; } - LLUUID getSculptTexture() { return mSculptTexture; } + LLUUID getSculptTexture() const { return mSculptTexture; } void setSculptType(U8 type) { mSculptType = type; } - U8 getSculptType() { return mSculptType; } + U8 getSculptType() const { return mSculptType; } }; +class LLLightImageParams : public LLNetworkData +{ +protected: + LLUUID mLightTexture; + LLVector3 mParams; + +public: + LLLightImageParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setLightTexture(const LLUUID& id) { mLightTexture = id; } + LLUUID getLightTexture() const { return mLightTexture; } + void setParams(const LLVector3& params) { mParams = params; } + LLVector3 getParams() const { return mParams; } + +}; class LLPrimitive : public LLXform @@ -294,6 +319,8 @@ class LLPrimitive : public LLXform LLPrimitive(); virtual ~LLPrimitive(); + void clearTextureList(); + static LLPrimitive *createPrimitive(LLPCode p_code); void init_primitive(LLPCode p_code); @@ -304,11 +331,11 @@ class LLPrimitive : public LLXform // Modify texture entry properties inline BOOL validTE(const U8 te_num) const; - const LLTextureEntry *getTE(const U8 te_num) const; + LLTextureEntry* getTE(const U8 te_num) const; virtual void setNumTEs(const U8 num_tes); virtual void setAllTETextures(const LLUUID &tex_id); - virtual void setTE(const U8 index, const LLTextureEntry &te); + virtual void setTE(const U8 index, const LLTextureEntry& te); virtual S32 setTEColor(const U8 te, const LLColor4 &color); virtual S32 setTEColor(const U8 te, const LLColor3 &color); virtual S32 setTEAlpha(const U8 te, const F32 alpha); @@ -331,10 +358,6 @@ class LLPrimitive : public LLXform virtual S32 setTEGlow(const U8 te, const F32 glow); virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed - void setTEArrays(const U8 size, - const LLUUID* image_ids, - const F32* scale_s, - const F32* scale_t); void copyTEs(const LLPrimitive *primitive); S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); @@ -382,14 +405,21 @@ class LLPrimitive : public LLXform const LLVector3& getAngularVelocity() const { return mAngularVelocity; } const LLVector3& getVelocity() const { return mVelocity; } const LLVector3& getAcceleration() const { return mAcceleration; } - U8 getNumTEs() const { return mNumTEs; } + U8 getNumTEs() const { return mTextureList.size(); } + U8 getExpectedNumTEs() const; U8 getMaterial() const { return mMaterial; } void setVolumeType(const U8 code); U8 getVolumeType(); - void setTextureList(LLTextureEntry *listp); + // clears existing textures + // copies the contents of other_list into mEntryList + void copyTextureList(const LLPrimTextureList& other_list); + + // clears existing textures + // takes the contents of other_list and clears other_list + void takeTextureList(LLPrimTextureList& other_list); inline BOOL isAvatar() const; inline BOOL isSittingAvatar() const; @@ -414,7 +444,7 @@ class LLPrimitive : public LLXform LLVector3 mAcceleration; // are we under constant acceleration? LLVector3 mAngularVelocity; // angular velocity LLPointer<LLVolume> mVolumep; - LLTextureEntry *mTextureList; // list of texture GUIDs, scales, offsets + LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets U8 mMaterial; // Material code U8 mNumTEs; // # of faces on the primitve U32 mMiscFlags; // home for misc bools diff --git a/linden/indra/llprimitive/llprimlinkinfo.h b/linden/indra/llprimitive/llprimlinkinfo.h old mode 100644 new mode 100755 index 946fa75bf..dfe33c1d0 --- a/linden/indra/llprimitive/llprimlinkinfo.h +++ b/linden/indra/llprimitive/llprimlinkinfo.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2007-2009, Linden Research, Inc. + * Copyright (c) 2007-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab diff --git a/linden/indra/llprimitive/llprimtexturelist.cpp b/linden/indra/llprimitive/llprimtexturelist.cpp new file mode 100755 index 000000000..691eb760e --- /dev/null +++ b/linden/indra/llprimitive/llprimtexturelist.cpp @@ -0,0 +1,424 @@ +/** + * @file lltexturelist.cpp + * @brief LLPrimTextureList (virtual) base class + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llprimtexturelist.h" +#include "lltextureentry.h" +#include "llmemtype.h" + +// static +//int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++ +LLTextureEntry* (*LLPrimTextureList::sNewTextureEntryCallback)() = &(LLTextureEntry::newTextureEntry); + +// static +void LLPrimTextureList::setNewTextureEntryCallback( LLTextureEntry* (*callback)() ) +{ + if (callback) + { + LLPrimTextureList::sNewTextureEntryCallback = callback; + } + else + { + LLPrimTextureList::sNewTextureEntryCallback = &(LLTextureEntry::newTextureEntry); + } +} + +// static +// call this to get a new texture entry +LLTextureEntry* LLPrimTextureList::newTextureEntry() +{ + return (*sNewTextureEntryCallback)(); +} + +LLPrimTextureList::LLPrimTextureList() +{ +} + +// virtual +LLPrimTextureList::~LLPrimTextureList() +{ + clear(); +} + +void LLPrimTextureList::clear() +{ + texture_list_t::iterator itr = mEntryList.begin(); + while (itr != mEntryList.end()) + { + delete (*itr); + (*itr) = NULL; + ++itr; + } + mEntryList.clear(); +} + + +// clears current entries +// copies contents of other_list +// this is somewhat expensive, so it must be called explicitly +void LLPrimTextureList::copy(const LLPrimTextureList& other_list) +{ + // compare the sizes + S32 this_size = mEntryList.size(); + S32 other_size = other_list.mEntryList.size(); + + if (this_size > other_size) + { + // remove the extra entries + for (S32 index = this_size; index > other_size; --index) + { + delete mEntryList[index-1]; + } + mEntryList.resize(other_size); + this_size = other_size; + } + + S32 index = 0; + // copy for the entries that already exist + for ( ; index < this_size; ++index) + { + delete mEntryList[index]; + mEntryList[index] = other_list.getTexture(index)->newCopy(); + } + + // add new entires if needed + for ( ; index < other_size; ++index) + { + mEntryList.push_back( other_list.getTexture(index)->newCopy() ); + } +} + +// clears current copies +// takes contents of other_list +// clears other_list +void LLPrimTextureList::take(LLPrimTextureList& other_list) +{ + clear(); + mEntryList = other_list.mEntryList; + other_list.mEntryList.clear(); +} + +// virtual +// copies LLTextureEntry 'te' +// returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE +S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te) +{ + if (S32(index) >= mEntryList.size()) + { + S32 current_size = mEntryList.size(); + llwarns << "ignore copy of index = " << S32(index) << " into texture entry list of size = " << current_size << llendl; + return TEM_CHANGE_NONE; + } + + // we're changing an existing entry + llassert(mEntryList[index]); + delete (mEntryList[index]); + if (&te) + { + mEntryList[index] = te.newCopy(); + } + else + { + mEntryList[index] = LLPrimTextureList::newTextureEntry(); + } + return TEM_CHANGE_TEXTURE; +} + +// virtual +// takes ownership of LLTextureEntry* 'te' +// returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE +// IMPORTANT! -- if you use this function you must check the return value +S32 LLPrimTextureList::takeTexture(const U8 index, LLTextureEntry* te) +{ + if (S32(index) >= mEntryList.size()) + { + return TEM_CHANGE_NONE; + } + + // we're changing an existing entry + llassert(mEntryList[index]); + delete (mEntryList[index]); + mEntryList[index] = te; + return TEM_CHANGE_TEXTURE; +} + +// returns pointer to texture at 'index' slot +LLTextureEntry* LLPrimTextureList::getTexture(const U8 index) const +{ + if (index < mEntryList.size()) + { + return mEntryList[index]; + } + return NULL; +} + +//virtual +//S32 setTE(const U8 index, const LLTextureEntry& te) = 0; + +S32 LLPrimTextureList::setID(const U8 index, const LLUUID& id) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setID(id); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setColor(const U8 index, const LLColor3& color) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setColor(color); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setColor(const U8 index, const LLColor4& color) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setColor(color); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setAlpha(const U8 index, const F32 alpha) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setAlpha(alpha); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setScale(const U8 index, const F32 s, const F32 t) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setScale(s, t); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setScaleS(const U8 index, const F32 s) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setScaleS(s); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setScaleT(const U8 index, const F32 t) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setScaleT(t); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setOffset(const U8 index, const F32 s, const F32 t) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setOffset(s, t); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setOffsetS(const U8 index, const F32 s) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setOffsetS(s); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setOffsetT(const U8 index, const F32 t) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setOffsetT(t); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setRotation(const U8 index, const F32 r) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setRotation(r); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setBumpShinyFullbright(const U8 index, const U8 bump) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setBumpShinyFullbright(bump); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setMediaTexGen(const U8 index, const U8 media) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setMediaTexGen(media); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setBumpMap(const U8 index, const U8 bump) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setBumpmap(bump); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setBumpShiny(const U8 index, const U8 bump_shiny) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setBumpShiny(bump_shiny); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setTexGen(const U8 index, const U8 texgen) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setTexGen(texgen); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setShiny(const U8 index, const U8 shiny) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setShiny(shiny); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setFullbright(const U8 index, const U8 fullbright) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setFullbright(fullbright); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setMediaFlags(media_flags); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow) +{ + if (index < mEntryList.size()) + { + return mEntryList[index]->setGlow(glow); + } + return TEM_CHANGE_NONE; +} + +S32 LLPrimTextureList::size() const +{ + return mEntryList.size(); +} + +// sets the size of the mEntryList container +void LLPrimTextureList::setSize(S32 new_size) +{ + LLMemType m1(LLMemType::MTYPE_PRIMITIVE); + if (new_size < 0) + { + new_size = 0; + } + + S32 current_size = mEntryList.size(); + + if (new_size > current_size) + { + mEntryList.resize(new_size); + for (S32 index = current_size; index < new_size; ++index) + { + if (current_size > 0 + && mEntryList[current_size - 1]) + { + // copy the last valid entry for the new one + mEntryList[index] = mEntryList[current_size - 1]->newCopy(); + } + else + { + // no valid enries to copy, so we new one up + LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry(); + mEntryList[index] = new_entry; + } + } + } + else if (new_size < current_size) + { + for (S32 index = current_size-1; index >= new_size; --index) + { + delete mEntryList[index]; + } + mEntryList.resize(new_size); + } +} + + +void LLPrimTextureList::setAllIDs(const LLUUID& id) +{ + texture_list_t::iterator itr = mEntryList.begin(); + while (itr != mEntryList.end()) + { + (*itr)->setID(id); + ++itr; + } +} + + diff --git a/linden/indra/llprimitive/llprimtexturelist.h b/linden/indra/llprimitive/llprimtexturelist.h new file mode 100755 index 000000000..c62f7b935 --- /dev/null +++ b/linden/indra/llprimitive/llprimtexturelist.h @@ -0,0 +1,127 @@ +/** + * @file llprimtexturelist.h + * @brief LLPrimTextureList (virtual) base class + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPRIMTEXTURELIST_H +#define LL_LLPRIMTEXTURELIST_H + +#include <vector> +#include "lluuid.h" +#include "v3color.h" +#include "v4color.h" + + +class LLTextureEntry; + +// this is a list of LLTextureEntry*'s because in practice the list's elements +// are of some derived class: LLFooTextureEntry +typedef std::vector<LLTextureEntry*> texture_list_t; + +class LLPrimTextureList +{ +public: + // the LLPrimTextureList needs to know what type of LLTextureEntry + // to generate when it needs a new one, so we may need to set a + // callback for generating it, (or else use the base class default: + // static LLPrimTextureEntry::newTextureEntry() ) + //typedef LLTextureEntry* (__stdcall *NewTextureEntryFunction)(); + //static NewTextureEntryFunction sNewTextureEntryCallback; + static LLTextureEntry* newTextureEntry(); + static void setNewTextureEntryCallback( LLTextureEntry* (*callback)() ); + static LLTextureEntry* (*sNewTextureEntryCallback)(); + + LLPrimTextureList(); + virtual ~LLPrimTextureList(); + + void clear(); + + // clears current entries + // copies contents of other_list + // this is somewhat expensive, so it must be called explicitly + void copy(const LLPrimTextureList& other_list); + + // clears current copies + // takes contents of other_list + // clears other_list + void take(LLPrimTextureList& other_list); + + // copies LLTextureEntry 'te' + // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE + S32 copyTexture(const U8 index, const LLTextureEntry& te); + + // takes ownership of LLTextureEntry* 'te' + // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE + // IMPORTANT! -- if you use this function you must check the return value + S32 takeTexture(const U8 index, LLTextureEntry* te); + +// // copies contents of 'entry' and stores it in 'index' slot +// void copyTexture(const U8 index, const LLTextureEntry* entry); + + // returns pointer to texture at 'index' slot + LLTextureEntry* getTexture(const U8 index) const; + + S32 setID(const U8 index, const LLUUID& id); + S32 setColor(const U8 index, const LLColor3& color); + S32 setColor(const U8 index, const LLColor4& color); + S32 setAlpha(const U8 index, const F32 alpha); + S32 setScale(const U8 index, const F32 s, const F32 t); + S32 setScaleS(const U8 index, const F32 s); + S32 setScaleT(const U8 index, const F32 t); + S32 setOffset(const U8 index, const F32 s, const F32 t); + S32 setOffsetS(const U8 index, const F32 s); + S32 setOffsetT(const U8 index, const F32 t); + S32 setRotation(const U8 index, const F32 r); + S32 setBumpShinyFullbright(const U8 index, const U8 bump); + S32 setMediaTexGen(const U8 index, const U8 media); + S32 setBumpMap(const U8 index, const U8 bump); + S32 setBumpShiny(const U8 index, const U8 bump_shiny); + S32 setTexGen(const U8 index, const U8 texgen); + S32 setShiny(const U8 index, const U8 shiny); + S32 setFullbright(const U8 index, const U8 t); + S32 setMediaFlags(const U8 index, const U8 media_flags); + S32 setGlow(const U8 index, const F32 glow); + + S32 size() const; + +// void forceResize(S32 new_size); + void setSize(S32 new_size); + + void setAllIDs(const LLUUID& id); +protected: + texture_list_t mEntryList; +private: + LLPrimTextureList(const LLPrimTextureList& other_list) + { + // private so that it can't be used + } +}; + +#endif diff --git a/linden/indra/llprimitive/lltextureentry.cpp b/linden/indra/llprimitive/lltextureentry.cpp old mode 100644 new mode 100755 index 14b45443d..11afdc02a --- a/linden/indra/llprimitive/lltextureentry.cpp +++ b/linden/indra/llprimitive/lltextureentry.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -32,25 +32,52 @@ #include "linden_common.h" +#include "lluuid.h" +#include "llmediaentry.h" #include "lltextureentry.h" -#include "llsdutil.h" +#include "llsdutil.h"//_math.h" +#include "v4color.h" const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess const LLTextureEntry LLTextureEntry::null; +// Some LLSD keys. Do not change these! +#define OBJECT_ID_KEY_STR "object_id" +#define TEXTURE_INDEX_KEY_STR "texture_index" +#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version" +#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data" +#define TEXTURE_MEDIA_DATA_KEY_STR "media_data" + +/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR; +/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR; +/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR; +/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR; +/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR; + +static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:"; + +// static +LLTextureEntry* LLTextureEntry::newTextureEntry() +{ + return new LLTextureEntry(); +} + //=============================================================== LLTextureEntry::LLTextureEntry() + : mMediaEntry(NULL) { init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLUUID& tex_id) + : mMediaEntry(NULL) { init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) + : mMediaEntry(NULL) { mID = rhs.mID; mScaleS = rhs.mScaleS; @@ -62,6 +89,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) mBump = rhs.mBump; mMediaFlags = rhs.mMediaFlags; mGlow = rhs.mGlow; + if (rhs.mMediaEntry != NULL) { + // Make a copy + mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); + } } LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) @@ -78,6 +109,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) mBump = rhs.mBump; mMediaFlags = rhs.mMediaFlags; mGlow = rhs.mGlow; + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + if (rhs.mMediaEntry != NULL) { + // Make a copy + mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); + } + else { + mMediaEntry = NULL; + } } return *this; @@ -97,10 +138,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of mGlow = 0; setColor(LLColor4(1.f, 1.f, 1.f, 1.f)); + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + mMediaEntry = NULL; } LLTextureEntry::~LLTextureEntry() { + if(mMediaEntry) + { + delete mMediaEntry; + mMediaEntry = NULL; + } } bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const @@ -136,23 +186,33 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const LLSD LLTextureEntry::asLLSD() const { LLSD sd; + asLLSD(sd); + return sd; +} - sd["imageid"] = getID(); - sd["colors"] = ll_sd_from_color4(getColor()); +void LLTextureEntry::asLLSD(LLSD& sd) const +{ + sd["imageid"] = mID; + sd["colors"] = ll_sd_from_color4(mColor); sd["scales"] = mScaleS; sd["scalet"] = mScaleT; sd["offsets"] = mOffsetS; sd["offsett"] = mOffsetT; - sd["imagerot"] = getRotation(); + sd["imagerot"] = mRotation; sd["bump"] = getBumpShiny(); sd["fullbright"] = getFullbright(); - sd["media_flags"] = getMediaTexGen(); - sd["glow"] = getGlow(); - - return sd; + sd["media_flags"] = mMediaFlags; + if (hasMedia()) { + LLSD mediaData; + if (NULL != getMediaData()) { + getMediaData()->asLLSD(mediaData); + } + sd[TEXTURE_MEDIA_DATA_KEY] = mediaData; + } + sd["glow"] = mGlow; } -bool LLTextureEntry::fromLLSD(LLSD& sd) +bool LLTextureEntry::fromLLSD(const LLSD& sd) { const char *w, *x; w = "imageid"; @@ -197,6 +257,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd) { setMediaTexGen( sd[w].asInteger() ); } else goto fail; + // If the "has media" flag doesn't match the fact that + // media data exists, updateMediaData will "fix" it + // by either clearing or setting the flag + w = TEXTURE_MEDIA_DATA_KEY; + if (hasMedia() != sd.has(w)) + { + llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() << + ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << llendl; + } + updateMediaData(sd[w]); + w = "glow"; if (sd.has(w)) { @@ -208,6 +279,19 @@ bool LLTextureEntry::fromLLSD(LLSD& sd) return false; } +// virtual +// override this method for each derived class +LLTextureEntry* LLTextureEntry::newBlank() const +{ + return new LLTextureEntry(); +} + +// virtual +LLTextureEntry* LLTextureEntry::newCopy() const +{ + return new LLTextureEntry(*this); +} + S32 LLTextureEntry::setID(const LLUUID &tex_id) { if (mID != tex_id) @@ -215,7 +299,7 @@ S32 LLTextureEntry::setID(const LLUUID &tex_id) mID = tex_id; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setScale(F32 s, F32 t) @@ -233,6 +317,28 @@ S32 LLTextureEntry::setScale(F32 s, F32 t) return retval; } +S32 LLTextureEntry::setScaleS(F32 s) +{ + S32 retval = TEM_CHANGE_NONE; + if (mScaleS != s) + { + mScaleS = s; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + +S32 LLTextureEntry::setScaleT(F32 t) +{ + S32 retval = TEM_CHANGE_NONE; + if (mScaleT != t) + { + mScaleT = t; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + S32 LLTextureEntry::setColor(const LLColor4 &color) { if (mColor != color) @@ -240,7 +346,7 @@ S32 LLTextureEntry::setColor(const LLColor4 &color) mColor = color; return TEM_CHANGE_COLOR; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setColor(const LLColor3 &color) @@ -251,7 +357,7 @@ S32 LLTextureEntry::setColor(const LLColor3 &color) mColor.setVec(color); return TEM_CHANGE_COLOR; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setAlpha(const F32 alpha) @@ -261,7 +367,7 @@ S32 LLTextureEntry::setAlpha(const F32 alpha) mColor.mV[VW] = alpha; return TEM_CHANGE_COLOR; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setOffset(F32 s, F32 t) @@ -279,6 +385,28 @@ S32 LLTextureEntry::setOffset(F32 s, F32 t) return retval; } +S32 LLTextureEntry::setOffsetS(F32 s) +{ + S32 retval = 0; + if (mOffsetS != s) + { + mOffsetS = s; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + +S32 LLTextureEntry::setOffsetT(F32 t) +{ + S32 retval = 0; + if (mOffsetT != t) + { + mOffsetT = t; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + S32 LLTextureEntry::setRotation(F32 theta) { if (mRotation != theta) @@ -286,7 +414,7 @@ S32 LLTextureEntry::setRotation(F32 theta) mRotation = theta; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) @@ -296,7 +424,7 @@ S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) mBump = bump; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMediaTexGen(U8 media) @@ -304,9 +432,21 @@ S32 LLTextureEntry::setMediaTexGen(U8 media) if (mMediaFlags != media) { mMediaFlags = media; - return TEM_CHANGE_TEXTURE; + + // Special code for media handling + if( hasMedia() && mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + else if ( ! hasMedia() && mMediaEntry != NULL) + { + delete mMediaEntry; + mMediaEntry = NULL; + } + + return TEM_CHANGE_MEDIA; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpmap(U8 bump) @@ -318,7 +458,7 @@ S32 LLTextureEntry::setBumpmap(U8 bump) mBump |= bump; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setFullbright(U8 fullbright) @@ -330,7 +470,7 @@ S32 LLTextureEntry::setFullbright(U8 fullbright) mBump |= fullbright << TEM_FULLBRIGHT_SHIFT; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setShiny(U8 shiny) @@ -342,7 +482,7 @@ S32 LLTextureEntry::setShiny(U8 shiny) mBump |= shiny << TEM_SHINY_SHIFT; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) @@ -354,7 +494,7 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) mBump |= bump_shiny; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMediaFlags(U8 media_flags) @@ -364,9 +504,21 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags) { mMediaFlags &= ~TEM_MEDIA_MASK; mMediaFlags |= media_flags; - return TEM_CHANGE_TEXTURE; + + // Special code for media handling + if( hasMedia() && mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + else if ( ! hasMedia() && mMediaEntry != NULL) + { + delete mMediaEntry; + mMediaEntry = NULL; + } + + return TEM_CHANGE_MEDIA; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setTexGen(U8 tex_gen) @@ -378,7 +530,7 @@ S32 LLTextureEntry::setTexGen(U8 tex_gen) mMediaFlags |= tex_gen; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setGlow(F32 glow) @@ -388,5 +540,115 @@ S32 LLTextureEntry::setGlow(F32 glow) mGlow = glow; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; +} + +void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry) +{ + mMediaFlags |= MF_HAS_MEDIA; + if (NULL != mMediaEntry) + { + delete mMediaEntry; + } + mMediaEntry = new LLMediaEntry(media_entry); +} + +bool LLTextureEntry::updateMediaData(const LLSD& media_data) +{ + if (media_data.isUndefined()) + { + // clear the media data + clearMediaData(); + return false; + } + else { + mMediaFlags |= MF_HAS_MEDIA; + if (mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + // *NOTE: this will *clobber* all of the fields in mMediaEntry + // with whatever fields are present (or not present) in media_data! + mMediaEntry->fromLLSD(media_data); + return true; + } +} + +void LLTextureEntry::clearMediaData() +{ + mMediaFlags &= ~MF_HAS_MEDIA; + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + mMediaEntry = NULL; +} + +void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields) +{ + mMediaFlags |= MF_HAS_MEDIA; + if (mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + // *NOTE: this will *merge* the data in media_fields + // with the data in our media entry + mMediaEntry->mergeFromLLSD(media_fields); +} + +//static +std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id) +{ + // XXX TODO: make media version string binary (base64-encoded?) + // Media "URL" is a representation of a version and the last-touched agent + // x-mv:nnnnn/agent-id + // where "nnnnn" is version number + // *NOTE: not the most efficient code in the world... + U32 current_version = getVersionFromMediaVersionString(in_version) + 1; + const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits + char buf[MAX_VERSION_LEN+1]; + snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version); // added int cast to fix warning/breakage on mac. + return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString(); +} + +//static +U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string) +{ + U32 version = 0; + if (!version_string.empty()) + { + size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX); + if (found != std::string::npos) + { + found = version_string.find_first_of("/", found); + std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found); + version = strtoul(v.c_str(),NULL,10); + } + } + return version; +} + +//static +LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string) +{ + LLUUID id; + if (!version_string.empty()) + { + size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX); + if (found != std::string::npos) + { + found = version_string.find_first_of("/", found); + if (found != std::string::npos) + { + std::string v = version_string.substr(found + 1); + id.set(v); + } + } + } + return id; +} + +//static +bool LLTextureEntry::isMediaVersionString(const std::string &version_string) +{ + return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX); } diff --git a/linden/indra/llprimitive/lltextureentry.h b/linden/indra/llprimitive/lltextureentry.h old mode 100644 new mode 100755 index c562545fc..e70673ea2 --- a/linden/indra/llprimitive/lltextureentry.h +++ b/linden/indra/llprimitive/lltextureentry.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -37,9 +37,13 @@ #include "v4color.h" #include "llsd.h" +// These bits are used while unpacking TEM messages to tell which aspects of +// the texture entry changed. +const S32 TEM_CHANGE_NONE = 0x0; const S32 TEM_CHANGE_COLOR = 0x1; const S32 TEM_CHANGE_TEXTURE = 0x2; -const S32 TEM_INVALID = 0x4; +const S32 TEM_CHANGE_MEDIA = 0x4; +const S32 TEM_INVALID = 0x8; const S32 TEM_BUMPMAP_COUNT = 32; @@ -64,10 +68,13 @@ const S32 TEM_MEDIA_MASK = 0x01; const S32 TEM_TEX_GEN_MASK = 0x06; const S32 TEM_TEX_GEN_SHIFT = 1; +// forward declarations +class LLMediaEntry; class LLTextureEntry { public: + static LLTextureEntry* newTextureEntry(); typedef enum e_texgen { @@ -82,14 +89,18 @@ class LLTextureEntry LLTextureEntry(const LLTextureEntry &rhs); LLTextureEntry &operator=(const LLTextureEntry &rhs); - ~LLTextureEntry(); + virtual ~LLTextureEntry(); bool operator==(const LLTextureEntry &rhs) const; bool operator!=(const LLTextureEntry &rhs) const; LLSD asLLSD() const; + void asLLSD(LLSD& sd) const; operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); + bool fromLLSD(const LLSD& sd); + + virtual LLTextureEntry* newBlank() const; + virtual LLTextureEntry* newCopy() const; void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump); @@ -99,7 +110,11 @@ class LLTextureEntry S32 setColor(const LLColor3 &color); S32 setAlpha(const F32 alpha); S32 setScale(F32 s, F32 t); + S32 setScaleS(F32 s); + S32 setScaleT(F32 t); S32 setOffset(F32 s, F32 t); + S32 setOffsetS(F32 s); + S32 setOffsetT(F32 t); S32 setRotation(F32 theta); S32 setBumpmap(U8 bump); @@ -113,7 +128,7 @@ class LLTextureEntry S32 setMediaTexGen(U8 media); S32 setGlow(F32 glow); - const LLUUID &getID() const { return mID; } + virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; } void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; } @@ -130,9 +145,37 @@ class LLTextureEntry U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; } U8 getMediaTexGen() const { return mMediaFlags; } F32 getGlow() const { return mGlow; } + + // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL. + // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() + // to NOT return NULL. + bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); } + LLMediaEntry* getMediaData() const { return mMediaEntry; } + + // Completely change the media data on this texture entry. + void setMediaData(const LLMediaEntry &media_entry); + // Returns true if media data was updated, false if it was cleared + bool updateMediaData(const LLSD& media_data); + // Clears media data, and sets the media flags bit to 0 + void clearMediaData(); + // Merges the given LLSD of media fields with this media entry. + // Only those fields that are set that match the keys in + // LLMediaEntry will be affected. If no fields are set or if + // the LLSD is undefined, this is a no-op. + void mergeIntoMediaData(const LLSD& media_fields); + + // Takes a media version string (an empty string or a previously-returned string) + // and returns a "touched" string, touched by agent_id + static std::string touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id); + // Given a media version string, return the version + static U32 getVersionFromMediaVersionString(const std::string &version_string); + // Given a media version string, return the UUID of the agent + static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string); + // Return whether or not the given string is actually a media version + static bool isMediaVersionString(const std::string &version_string); // Media flags - enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 }; + enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; public: F32 mScaleS; // S, T offset @@ -142,6 +185,14 @@ class LLTextureEntry F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner static const LLTextureEntry null; + + // LLSD key defines + static const char* OBJECT_ID_KEY; + static const char* OBJECT_MEDIA_DATA_KEY; + static const char* MEDIA_VERSION_KEY; + static const char* TEXTURE_INDEX_KEY; + static const char* TEXTURE_MEDIA_DATA_KEY; + protected: LLUUID mID; // Texture GUID LLColor4 mColor; @@ -149,6 +200,9 @@ class LLTextureEntry U8 mMediaFlags; // replace with web page, movie, etc. F32 mGlow; + // Note the media data is not sent via the same message structure as the rest of the TE + LLMediaEntry* mMediaEntry; // The media data for the face + // NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the // message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs() diff --git a/linden/indra/llprimitive/material_codes.cpp b/linden/indra/llprimitive/material_codes.cpp new file mode 100755 index 000000000..8eb2ae77e --- /dev/null +++ b/linden/indra/llprimitive/material_codes.cpp @@ -0,0 +1,46 @@ +/** + * @file material_codes.cpp + * @brief Material_codes definitions + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "material_codes.h" + +#include "lluuid.h" + +const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); +const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); +const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); +const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); +const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); +const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); +const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); +const LLUUID LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000"); diff --git a/linden/indra/llprimitive/material_codes.h b/linden/indra/llprimitive/material_codes.h old mode 100644 new mode 100755 index e5a59a278..c63f29577 --- a/linden/indra/llprimitive/material_codes.h +++ b/linden/indra/llprimitive/material_codes.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2000&license=viewergpl$ * - * Copyright (c) 2000-2009, Linden Research, Inc. + * Copyright (c) 2000-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -33,7 +33,7 @@ #ifndef LL_MATERIAL_CODES_H #define LL_MATERIAL_CODES_H -#include "lluuid.h" +class LLUUID; // material types const U8 LL_MCODE_STONE = 0; @@ -47,13 +47,14 @@ const U8 LL_MCODE_LIGHT = 7; const U8 LL_MCODE_END = 8; const U8 LL_MCODE_MASK = 0x0F; -const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); -const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); -const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); -const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); -const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); -const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); -const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); -const LLUUID LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000"); +// *NOTE: Define these in .cpp file to reduce duplicate instances +extern const LLUUID LL_DEFAULT_STONE_UUID; +extern const LLUUID LL_DEFAULT_METAL_UUID; +extern const LLUUID LL_DEFAULT_GLASS_UUID; +extern const LLUUID LL_DEFAULT_WOOD_UUID; +extern const LLUUID LL_DEFAULT_FLESH_UUID; +extern const LLUUID LL_DEFAULT_PLASTIC_UUID; +extern const LLUUID LL_DEFAULT_RUBBER_UUID; +extern const LLUUID LL_DEFAULT_LIGHT_UUID; #endif diff --git a/linden/indra/llprimitive/tests/llmediaentry_test.cpp b/linden/indra/llprimitive/tests/llmediaentry_test.cpp new file mode 100755 index 000000000..89f778d38 --- /dev/null +++ b/linden/indra/llprimitive/tests/llmediaentry_test.cpp @@ -0,0 +1,508 @@ +/** + * @file llmediaentry_test.cpp + * @brief llmediaentry unit tests + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "lltut.h" +#if LL_WINDOWS +#pragma warning (push) +#pragma warning (disable : 4702) // boost::lexical_cast generates this warning +#endif +#include <boost/lexical_cast.hpp> +#if LL_WINDOWS +#pragma warning (pop) +#endif +#include "llstring.h" +#include "llsdutil.h" +#include "llsdserialize.h" + +#include "../llmediaentry.h" +#include "lllslconstants.h" + +#define DEFAULT_MEDIA_ENTRY "<llsd>\n\ + <map>\n\ + <key>alt_image_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_loop</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_play</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_scale</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_zoom</key>\n\ + <boolean>0</boolean>\n\ + <key>controls</key>\n\ + <integer>0</integer>\n\ + <key>current_url</key>\n\ + <string />\n\ + <key>first_click_interact</key>\n\ + <boolean>0</boolean>\n\ + <key>height_pixels</key>\n\ + <integer>0</integer>\n\ + <key>home_url</key>\n\ + <string />\n\ + <key>perms_control</key>\n\ + <integer>7</integer>\n\ + <key>perms_interact</key>\n\ + <integer>7</integer>\n\ + <key>whitelist_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>width_pixels</key>\n\ + <integer>0</integer>\n\ + </map>\n\ + </llsd>" + +#define EMPTY_MEDIA_ENTRY "<llsd>\n\ + <map>\n\ + <key>alt_image_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_loop</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_play</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_scale</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_zoom</key>\n\ + <boolean>0</boolean>\n\ + <key>controls</key>\n\ + <integer>0</integer>\n\ + <key>current_url</key>\n\ + <string />\n\ + <key>first_click_interact</key>\n\ + <boolean>0</boolean>\n\ + <key>height_pixels</key>\n\ + <integer>0</integer>\n\ + <key>home_url</key>\n\ + <string />\n\ + <key>perms_control</key>\n\ + <integer>0</integer>\n\ + <key>perms_interact</key>\n\ + <integer>0</integer>\n\ + <key>whitelist_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>width_pixels</key>\n\ + <integer>0</integer>\n\ + </map>\n\ + </llsd>" + +#define PARTIAL_MEDIA_ENTRY(CURRENT_URL) "<llsd>\n\ + <map>\n\ + <key>alt_image_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_loop</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_play</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_scale</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_zoom</key>\n\ + <boolean>0</boolean>\n\ + <key>controls</key>\n\ + <integer>0</integer>\n\ + <key>current_url</key>\n\ + <string>" CURRENT_URL "</string>\n\ + <key>first_click_interact</key>\n\ + <boolean>0</boolean>\n\ + <key>height_pixels</key>\n\ + <integer>0</integer>\n\ + <key>home_url</key>\n\ + <string />\n\ + <key>perms_control</key>\n\ + <integer>0</integer>\n\ + <key>perms_interact</key>\n\ + <integer>0</integer>\n\ + <key>whitelist_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>width_pixels</key>\n\ + <integer>0</integer>\n\ + </map>\n\ + </llsd>" + +namespace tut +{ + // this is fixture data that gets created before each test and destroyed + // after each test. this is where we put all of the setup/takedown code + // and data needed for each test. + struct MediaEntry_test + { + MediaEntry_test() { + emptyMediaEntryStr = EMPTY_MEDIA_ENTRY; + std::istringstream e(EMPTY_MEDIA_ENTRY); + LLSDSerialize::fromXML(emptyMediaEntryLLSD, e); + defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY; + std::istringstream d(DEFAULT_MEDIA_ENTRY); + LLSDSerialize::fromXML(defaultMediaEntryLLSD, d); + } + std::string emptyMediaEntryStr; + LLSD emptyMediaEntryLLSD; + std::string defaultMediaEntryStr; + LLSD defaultMediaEntryLLSD; + }; + + typedef test_group<MediaEntry_test, 55> factory; + typedef factory::object object; +} + + +namespace +{ + // this is for naming our tests to make pretty output + tut::factory tf("MediaEntry Test"); +} + +namespace tut +{ + void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual) + { + if (!llsd_equals(expected, actual)) + { + std::string message = msg; + message += ": actual: "; + message += ll_pretty_print_sd(actual); + message += "\n expected: "; + message += ll_pretty_print_sd(expected); + message += "\n"; + ensure(message, false); + } + } + + void ensure_string_equals(const std::string& msg, const std::string& expected, const std::string& actual) + { + if ( expected != actual ) + { + std::string message = msg; + message += ": actual: "; + message += actual; + message += "\n expected: "; + message += expected; + message += "\n"; + ensure(message, false); + } + } + + void set_whitelist(LLMediaEntry &entry, const char *str) + { + std::vector<std::string> tokens; + LLStringUtil::getTokens(std::string(str), tokens, ","); + entry.setWhiteList(tokens); + } + + void whitelist_test(int num, bool enable, const char *whitelist, const char *candidate_url, bool expected_pass) + { + std::string message = "Whitelist test " + boost::lexical_cast<std::string>(num); + LLMediaEntry entry; + entry.setWhiteListEnable(enable); + set_whitelist(entry, whitelist); + bool passed_whitelist = entry.checkCandidateUrl(candidate_url); + if (passed_whitelist != expected_pass) + { + message += " failed: expected "; + message += (expected_pass) ? "" : "NOT "; + message += "to match\nwhitelist = "; + message += whitelist; + message += "\ncandidate_url = "; + message += candidate_url; + } + ensure(message, expected_pass == passed_whitelist); + } + + void whitelist_test(int num, const char *whitelist, const char *candidate_url, bool expected_pass) + { + whitelist_test(num, true, whitelist, candidate_url, expected_pass); + } + void whitelist_test(int num, const char *whitelist, const char *candidate_url) + { + whitelist_test(num, true, whitelist, candidate_url, true); + } + + template<> template<> + void object::test<1>() + { + set_test_name("Test LLMediaEntry Instantiation"); + LLMediaEntry entry; + ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry.asLLSD()); + } + + template<> template<> + void object::test<2>() + { + set_test_name("Test LLMediaEntry Instantiation from LLSD"); + LLMediaEntry entry; + LLSD sd; + entry.fromLLSD(sd); + ensure_llsd_equals(get_test_name() + " failed", emptyMediaEntryLLSD, entry.asLLSD()); + } + + template<> template<> + void object::test<3>() + { + set_test_name("Test LLMediaEntry Partial Instantiation from LLSD"); + LLMediaEntry entry; + LLSD sd; + sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com"; + entry.fromLLSD(sd); + LLSD golden; + std::istringstream p(PARTIAL_MEDIA_ENTRY("http://www.example.com")); + LLSDSerialize::fromXML(golden,p); + ensure_llsd_equals(get_test_name() + " failed", golden, entry.asLLSD()); + } + + template<> template<> + void object::test<4>() + { + set_test_name("Test LLMediaEntry::asLLSD()"); + LLMediaEntry entry; + LLSD sd; + // Put some cruft in the LLSD + sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com"; + LLSD whitelist; + whitelist.append("*.example.com"); + sd[LLMediaEntry::WHITELIST_KEY] = whitelist; + entry.asLLSD(sd); + ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, sd); + } + + + template<> template<> + void object::test<5>() + { + set_test_name("Test LLMediaEntry::asLLSD() -> LLMediaEntry::fromLLSD()"); + LLMediaEntry entry1, entry2; + // Add a whitelist to entry2 + std::vector<std::string> whitelist; + whitelist.push_back("*.example.com"); + entry2.setWhiteList(whitelist); + // Render entry1 (which has no whitelist) as an LLSD + LLSD sd; + entry1.asLLSD(sd); + // "read" that LLSD into entry 2 + entry2.fromLLSD(sd); + ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry2.asLLSD()); + } + + // limit tests + const char *URL_OK = "http://www.example.com"; + const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"; + + template<> template<> + void object::test<6>() + { + set_test_name("Test Limits on setting current URL"); + LLMediaEntry entry; + U32 status = entry.setCurrentURL(URL_OK); + ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK); + status = entry.setCurrentURL(URL_TOO_BIG); + ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR); + } + + template<> template<> + void object::test<7>() + { + set_test_name("Test Limits on setting home URL"); + LLMediaEntry entry; + U32 status = entry.setHomeURL(URL_OK); + ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK); + status = entry.setHomeURL(URL_TOO_BIG); + ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR); + } + + template<> template<> + void object::test<8>() + { + set_test_name("Test Limits on setting whitelist"); + + // Test a valid list + LLMediaEntry entry; + std::vector<std::string> whitelist; + whitelist.push_back(std::string(URL_OK)); + S32 status = entry.setWhiteList(whitelist); + ensure(get_test_name() + " invalid result", status == LSL_STATUS_OK); + ensure(get_test_name() + " failed", whitelist == entry.getWhiteList()); + } + + template<> template<> + void object::test<9>() + { + set_test_name("Test Limits on setting whitelist too big"); + + // Test an invalid list + LLMediaEntry entry; + std::vector<std::string> whitelist, empty; + whitelist.push_back(std::string(URL_OK)); + whitelist.push_back(std::string(URL_TOO_BIG)); + S32 status = entry.setWhiteList(whitelist); + ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR); + ensure(get_test_name() + " failed", empty == entry.getWhiteList()); + } + + template<> template<> + void object::test<10>() + { + set_test_name("Test Limits on setting whitelist too many"); + + // Test an invalid list + LLMediaEntry entry; + std::vector<std::string> whitelist, empty; + for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) { + whitelist.push_back("Q"); + } + S32 status = entry.setWhiteList(whitelist); + ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR); + ensure(get_test_name() + " failed", empty == entry.getWhiteList()); + } + + template<> template<> + void object::test<11>() + { + set_test_name("Test to make sure both setWhiteList() functions behave the same"); + + // Test a valid list + std::vector<std::string> whitelist, empty; + LLSD whitelist_llsd; + whitelist.push_back(std::string(URL_OK)); + whitelist_llsd.append(std::string(URL_OK)); + LLMediaEntry entry1, entry2; + ensure(get_test_name() + " setWhiteList(s) don't match", + entry1.setWhiteList(whitelist) == LSL_STATUS_OK && + entry2.setWhiteList(whitelist_llsd)== LSL_STATUS_OK ); + ensure(get_test_name() + " failed", + entry1.getWhiteList() == entry2.getWhiteList()); + } + + template<> template<> + void object::test<12>() + { + set_test_name("Test to make sure both setWhiteList() functions behave the same"); + + // Test an invalid list + std::vector<std::string> whitelist, empty; + LLSD whitelist_llsd; + whitelist.push_back(std::string(URL_OK)); + whitelist.push_back(std::string(URL_TOO_BIG)); + whitelist_llsd.append(std::string(URL_OK)); + whitelist_llsd.append(std::string(URL_TOO_BIG)); + LLMediaEntry entry1, entry2; + ensure(get_test_name() + " setWhiteList(s) don't match", + entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR && + entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR); + ensure(get_test_name() + " failed", + empty == entry1.getWhiteList() && + empty == entry2.getWhiteList()); + } + + template<> template<> + void object::test<13>() + { + set_test_name("Test to make sure both setWhiteList() functions behave the same"); + + // Test an invalid list, too many + std::vector<std::string> whitelist, empty; + LLSD whitelist_llsd; + for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) { + whitelist.push_back("Q"); + whitelist_llsd.append("Q"); + } + LLMediaEntry entry1, entry2; + ensure(get_test_name() + " invalid result", + entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR && + entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR); + ensure(get_test_name() + " failed", + empty == entry1.getWhiteList() && + empty == entry2.getWhiteList()); + } + + template<> template<> + void object::test<14>() + { + // Whitelist check tests + int n=0; + + // Check the "empty whitelist" case + whitelist_test(++n, "", "http://www.example.com", true); + + // Check the "missing scheme" case + whitelist_test(++n, "www.example.com", "http://www.example.com", true); + + // Check the "exactly the same" case + whitelist_test(++n, "http://example.com", "http://example.com", true); + + // Check the enable flag + whitelist_test(++n, false, "www.example.com", "http://www.secondlife.com", true); + whitelist_test(++n, true, "www.example.com", "http://www.secondlife.com", false); + + // Check permutations of trailing slash: + whitelist_test(++n, "http://www.example.com", "http://www.example.com/", true); + whitelist_test(++n, "http://www.example.com/", "http://www.example.com/", true); + whitelist_test(++n, "http://www.example.com/", "http://www.example.com", false); + whitelist_test(++n, "http://www.example.com", "http://www.example.com/foobar", true); + whitelist_test(++n, "http://www.example.com/", "http://www.example.com/foobar", false); + + + // More cases... + whitelist_test(++n, "http://example.com", "http://example.com/wiki", true); + whitelist_test(++n, "www.example.com", "http://www.example.com/help", true); + whitelist_test(++n, "http://www.example.com", "http://wwwexample.com", false); + whitelist_test(++n, "http://www.example.com", "http://www.example.com/wiki", true); + whitelist_test(++n, "example.com", "http://wwwexample.com", false); + whitelist_test(++n, "http://www.example.com/", "http://www.amazon.com/wiki", false); + whitelist_test(++n, "www.example.com", "http://www.amazon.com", false); + + // regexp cases + whitelist_test(++n, "*.example.com", "http://www.example.com", true); + whitelist_test(++n, "*.example.com", "http://www.amazon.com", false); + whitelist_test(++n, "*.example.com", "http://www.example.com/foo/bar", true); + whitelist_test(++n, "*.example.com", "http:/example.com/foo/bar", false); + whitelist_test(++n, "*example.com", "http://example.com/foo/bar", true); + whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?example.com", false); + whitelist_test(++n, "example.com", "http://my.virus.com/foo/bar?example.com", false); + whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?*example.com", false); + whitelist_test(++n, "http://*example.com", "http://www.example.com", true); + whitelist_test(++n, "http://*.example.com", "http://www.example.com", true); + whitelist_test(++n, "http://*.e$?^.com", "http://www.e$?^.com", true); + whitelist_test(++n, "*.example.com/foo/bar", "http://www.example.com/", false); + whitelist_test(++n, "*.example.com/foo/bar", "http://example.com/foo/bar", false); + whitelist_test(++n, "http://*.example.com/foo/bar", "http://www.example.com", false); + whitelist_test(++n, "http://*.example.com", "https://www.example.com", false); + whitelist_test(++n, "http*://*.example.com", "rtsp://www.example.com", false); + whitelist_test(++n, "http*://*.example.com", "https://www.example.com", true); + whitelist_test(++n, "example.com", "http://www.example.com", false); + whitelist_test(++n, "www.example.com", "http://www.example.com:80", false); + whitelist_test(++n, "www.example.com", "http://www.example.com", true); + whitelist_test(++n, "www.example.com/", "http://www.example.com", false); + whitelist_test(++n, "www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); + + // Path only + whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/baz", true); + whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/", false); + } + +} + diff --git a/linden/indra/llprimitive/tests/llmessagesystem_stub.cpp b/linden/indra/llprimitive/tests/llmessagesystem_stub.cpp new file mode 100755 index 000000000..37a61de12 --- /dev/null +++ b/linden/indra/llprimitive/tests/llmessagesystem_stub.cpp @@ -0,0 +1,53 @@ +/** + * @file llmessagesystem_stub.cpp + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +char * _PREHASH_TextureEntry; + +S32 LLMessageSystem::getSizeFast(char const*, char const*) const +{ + return 0; +} + +S32 LLMessageSystem::getSizeFast(char const*, int, char const*) const +{ + return 0; +} + +void LLMessageSystem::getBinaryDataFast(char const*, char const*, void*, int, int, int) +{ +} + +void LLMessageSystem::addBinaryDataFast(char const*, void const*, int) +{ +} + diff --git a/linden/indra/llprimitive/tests/llprimitive_test.cpp b/linden/indra/llprimitive/tests/llprimitive_test.cpp new file mode 100755 index 000000000..c923442a6 --- /dev/null +++ b/linden/indra/llprimitive/tests/llprimitive_test.cpp @@ -0,0 +1,237 @@ +/** + * @file llprimitive_test.cpp + * @brief llprimitive tests + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../llprimitive.h" + +#include "../../llmath/llvolumemgr.h" + +class DummyVolumeMgr : public LLVolumeMgr +{ +public: + DummyVolumeMgr() : LLVolumeMgr(), mVolumeTest(NULL), mCurrDetailTest(0) {} + ~DummyVolumeMgr() + { + } + + + virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail) + { + if (mVolumeTest.isNull() || volume_params != mCurrParamsTest || detail != mCurrDetailTest) + { + F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail); + mVolumeTest = new LLVolume(volume_params, volume_detail, FALSE, FALSE); + mCurrParamsTest = volume_params; + mCurrDetailTest = detail; + return mVolumeTest; + } + else + { + return mVolumeTest; + } + } + + virtual void unrefVolume(LLVolume *volumep) + { + if (mVolumeTest == volumep) + { + mVolumeTest = NULL; + } + } + +private: + LLPointer<LLVolume> mVolumeTest; + LLVolumeParams mCurrParamsTest; + S32 mCurrDetailTest; +}; + +class PRIMITIVE_TEST_SETUP +{ +public: + PRIMITIVE_TEST_SETUP() + { + volume_manager_test = new DummyVolumeMgr(); + LLPrimitive::setVolumeManager(volume_manager_test); + } + + ~PRIMITIVE_TEST_SETUP() + { + LLPrimitive::cleanupVolumeManager(); + } + DummyVolumeMgr * volume_manager_test; +}; + +namespace tut +{ + struct llprimitive + { + PRIMITIVE_TEST_SETUP setup_class; + }; + + typedef test_group<llprimitive> llprimitive_t; + typedef llprimitive_t::object llprimitive_object_t; + tut::llprimitive_t tut_llprimitive("llprimitive"); + + template<> template<> + void llprimitive_object_t::test<1>() + { + set_test_name("Test LLPrimitive Instantiation"); + LLPrimitive test; + } + + template<> template<> + void llprimitive_object_t::test<2>() + { + set_test_name("Test LLPrimitive PCode setter and getter."); + LLPrimitive test; + ensure_equals(test.getPCode(), 0); + LLPCode code = 1; + test.setPCode(code); + ensure_equals(test.getPCode(), code); + } + + template<> template<> + void llprimitive_object_t::test<3>() + { + set_test_name("Test llprimitive constructor and initer."); + LLPCode code = 1; + LLPrimitive primitive; + primitive.init_primitive(code); + ensure_equals(primitive.getPCode(), code); + } + + template<> template<> + void llprimitive_object_t::test<4>() + { + set_test_name("Test Static llprimitive constructor and initer."); + LLPCode code = 1; + LLPrimitive * primitive = LLPrimitive::createPrimitive(code); + ensure(primitive != NULL); + ensure_equals(primitive->getPCode(), code); + } + + template<> template<> + void llprimitive_object_t::test<5>() + { + set_test_name("Test setVolume creation of new unique volume."); + LLPrimitive primitive; + LLVolumeParams params; + + // Make sure volume starts off null + ensure(primitive.getVolume() == NULL); + + // Make sure we have no texture entries before setting the volume + ensure_equals(primitive.getNumTEs(), 0); + + // Test that GEOMETRY has not been flagged as changed. + ensure(!primitive.isChanged(LLXform::GEOMETRY)); + + // Make sure setVolume returns true + ensure(primitive.setVolume(params, 0, true) == TRUE); + LLVolume* new_volume = primitive.getVolume(); + + // make sure new volume was actually created + ensure(new_volume != NULL); + + // Make sure that now that we've set the volume we have texture entries + ensure_not_equals(primitive.getNumTEs(), 0); + + // Make sure that the number of texture entries equals the number of faces in the volume (should be 6) + ensure_equals(new_volume->getNumFaces(), 6); + ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces()); + + // Test that GEOMETRY has been flagged as changed. + ensure(primitive.isChanged(LLXform::GEOMETRY)); + + // Run it twice to make sure it doesn't create a different one if params are the same + ensure(primitive.setVolume(params, 0, true) == FALSE); + ensure(new_volume == primitive.getVolume()); + + // Change the param definition and try setting it again. + params.setRevolutions(4); + ensure(primitive.setVolume(params, 0, true) == TRUE); + + // Ensure that we now have a different volume + ensure(new_volume != primitive.getVolume()); + } + + template<> template<> + void llprimitive_object_t::test<6>() + { + set_test_name("Test setVolume creation of new NOT-unique volume."); + LLPrimitive primitive; + LLVolumeParams params; + + // Make sure volume starts off null + ensure(primitive.getVolume() == NULL); + + // Make sure we have no texture entries before setting the volume + ensure_equals(primitive.getNumTEs(), 0); + + // Test that GEOMETRY has not been flagged as changed. + ensure(!primitive.isChanged(LLXform::GEOMETRY)); + + // Make sure setVolume returns true + ensure(primitive.setVolume(params, 0, false) == TRUE); + + LLVolume* new_volume = primitive.getVolume(); + + // make sure new volume was actually created + ensure(new_volume != NULL); + + // Make sure that now that we've set the volume we have texture entries + ensure_not_equals(primitive.getNumTEs(), 0); + + // Make sure that the number of texture entries equals the number of faces in the volume (should be 6) + ensure_equals(new_volume->getNumFaces(), 6); + ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces()); + + // Test that GEOMETRY has been flagged as changed. + ensure(primitive.isChanged(LLXform::GEOMETRY)); + + // Run it twice to make sure it doesn't create a different one if params are the same + ensure(primitive.setVolume(params, 0, false) == FALSE); + ensure(new_volume == primitive.getVolume()); + + // Change the param definition and try setting it again. + params.setRevolutions(4); + ensure(primitive.setVolume(params, 0, false) == TRUE); + + // Ensure that we now have a different volume + ensure(new_volume != primitive.getVolume()); + } +} + +#include "llmessagesystem_stub.cpp" diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index 558d27835..b2904b9fc 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -1715,7 +1715,7 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& U8 media_flags = LLTextureEntry::MF_NONE; if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE) { - media_flags = LLTextureEntry::MF_WEB_PAGE; + media_flags = LLTextureEntry::MF_HAS_MEDIA; } struct f : public LLSelectedTEFunctor From c791570b8f7704dd3af382ab1d6ad446af1fa671 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Mon, 14 Jun 2010 14:29:10 +0200 Subject: [PATCH 020/239] make it compile and run. TODO: llpanellandmedia.cpp and llviewermedia.cpp need a proper fix --- linden/indra/llprimitive/llprimitive.cpp | 96 +---------------------- linden/indra/newview/CMakeLists.txt | 1 - linden/indra/newview/llpanellandmedia.cpp | 51 ------------ 3 files changed, 1 insertion(+), 147 deletions(-) diff --git a/linden/indra/llprimitive/llprimitive.cpp b/linden/indra/llprimitive/llprimitive.cpp index 754676456..0ad9f795a 100755 --- a/linden/indra/llprimitive/llprimitive.cpp +++ b/linden/indra/llprimitive/llprimitive.cpp @@ -247,50 +247,22 @@ void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setID(index, id); } S32 LLPrimitive::setTEColor(const U8 index, const LLColor4 &color) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setColor(index, color); } S32 LLPrimitive::setTEColor(const U8 index, const LLColor3 &color) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setColor(index, color); } S32 LLPrimitive::setTEAlpha(const U8 index, const F32 alpha) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setAlpha(index, alpha); } @@ -350,111 +322,46 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r) //=============================================================== S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - - return mTextureList.setBumpShinyFullbright(index, bump); + return mTextureList.setBumpShinyFullbright(index, bump); } S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setMediaTexGen(index, media); } S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setBumpMap(index, bump); } S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setBumpShiny(index, bump_shiny); } S32 LLPrimitive::setTETexGen(const U8 index, const U8 texgen) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setTexGen(index, texgen); } S32 LLPrimitive::setTEShiny(const U8 index, const U8 shiny) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - - return mTextureList.setShiny(index, shiny); } S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright) { - - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setFullbright(index, fullbright); } S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setMediaFlags(index, media_flags); } S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl; - return 0; - } - return mTextureList.setGlow(index, glow); } @@ -1029,7 +936,6 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); } } ->>>>>>> 5faaca1... port llprimitive from SG2.0 return TRUE; } diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index b576ccde6..75ba97759 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1174,7 +1174,6 @@ set(viewer_APPSETTINGS_FILES ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg ) - source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) set_source_files_properties(${viewer_APPSETTINGS_FILES} diff --git a/linden/indra/newview/llpanellandmedia.cpp b/linden/indra/newview/llpanellandmedia.cpp index fc84bb51c..db68c4279 100644 --- a/linden/indra/newview/llpanellandmedia.cpp +++ b/linden/indra/newview/llpanellandmedia.cpp @@ -172,57 +172,6 @@ void LLPanelLandMedia::refresh() BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); mCheckSoundLocal->set( parcel->getSoundLocal() ); - mCheckSoundLocal->setEnabled( can_change_media ); - - LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - if (!region) - { - // never seen this happen, but log it - llwarns << "Couldn't get selected region." << llendl; - } - - // We need to do this differently for OpenSim because it doesn't include - // REGION_FLAGS_ALLOW_VOICE in the "RegionInfo" message as of 0.6.9 PF -- MC - bool allow_voice = parcel->getParcelFlagAllowVoice(); - if (gHippoGridManager->getConnectedGrid()->isSecondLife()) - { - if (region && region->isVoiceEnabled()) // estate-wide voice-disable overrides all - { - mCheckEnableVoiceChatIsEstateDisabled->setVisible(false); - - mCheckEnableVoiceChat->setVisible(true); - mCheckEnableVoiceChat->setEnabled( can_change_media ); - mCheckEnableVoiceChat->set(allow_voice); - - mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); - } - else // disabled at region level - { - mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); // always disabled - mCheckEnableVoiceChat->setVisible(false); - mCheckEnableVoiceChat->setEnabled(false); - mCheckEnableVoiceChat->set(false); - - mCheckEnableVoiceChatParcel->setEnabled(false); - } - } - else - { - mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); - - mCheckEnableVoiceChat->setVisible(true); - mCheckEnableVoiceChat->setEnabled( can_change_media ); - mCheckEnableVoiceChat->set(allow_voice); - - mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); - } - - mCheckEnableVoiceChatParcel->set(!parcel->getParcelFlagUseEstateVoiceChannel()); - - mMusicURLEdit->setText(parcel->getMusicURL()); - mMusicURLEdit->setEnabled( can_change_media ); - - childSetText("current_url", parcel->getMediaCurrentURL()); From 3069d8886241b2d9deaadfbf8823d463b469ec6b Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Mon, 14 Jun 2010 16:27:25 +0200 Subject: [PATCH 021/239] update to latest SG2 media_plugins --- .../indra/media_plugins/base/CMakeLists.txt | 4 +- .../media_plugins/base/media_plugin_base.cpp | 5 +- .../media_plugins/base/media_plugin_base.h | 5 +- .../media_plugins/example/CMakeLists.txt | 6 +- .../example/media_plugin_example.cpp | 31 +- .../media_plugins/gstreamer010/CMakeLists.txt | 15 +- .../gstreamer010/llmediaimplgstreamer.h | 5 +- .../llmediaimplgstreamer_syms.cpp | 5 +- .../gstreamer010/llmediaimplgstreamer_syms.h | 5 +- .../llmediaimplgstreamertriviallogging.h | 5 +- .../llmediaimplgstreamervidplug.cpp | 25 +- .../llmediaimplgstreamervidplug.h | 5 +- .../media_plugin_gstreamer010.cpp | 63 +-- .../quicktime/media_plugin_quicktime.cpp | 71 +-- .../indra/media_plugins/webkit/CMakeLists.txt | 10 +- .../webkit/linux_volume_catcher.cpp | 490 ++++++++++++++++++ .../webkit/linux_volume_catcher.h | 56 ++ .../webkit/linux_volume_catcher_pa_syms.inc | 21 + .../linux_volume_catcher_paglib_syms.inc | 6 + .../webkit/media_plugin_webkit.cpp | 352 +++++++++---- 20 files changed, 956 insertions(+), 229 deletions(-) create mode 100755 linden/indra/media_plugins/webkit/linux_volume_catcher.cpp create mode 100755 linden/indra/media_plugins/webkit/linux_volume_catcher.h create mode 100755 linden/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc create mode 100755 linden/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc diff --git a/linden/indra/media_plugins/base/CMakeLists.txt b/linden/indra/media_plugins/base/CMakeLists.txt index a3ee02eaa..8d620433a 100755 --- a/linden/indra/media_plugins/base/CMakeLists.txt +++ b/linden/indra/media_plugins/base/CMakeLists.txt @@ -25,13 +25,13 @@ include_directories( ### media_plugin_base -if(WORD_SIZE EQUAL 64) +if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) if(WINDOWS) add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif (WORD_SIZE EQUAL 64) +endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) set(media_plugin_base_SOURCE_FILES media_plugin_base.cpp diff --git a/linden/indra/media_plugins/base/media_plugin_base.cpp b/linden/indra/media_plugins/base/media_plugin_base.cpp index baae68c02..47acdfd28 100755 --- a/linden/indra/media_plugins/base/media_plugin_base.cpp +++ b/linden/indra/media_plugins/base/media_plugin_base.cpp @@ -15,13 +15,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -31,6 +31,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/media_plugins/base/media_plugin_base.h b/linden/indra/media_plugins/base/media_plugin_base.h index 8311e66bc..efb0629a5 100755 --- a/linden/indra/media_plugins/base/media_plugin_base.h +++ b/linden/indra/media_plugins/base/media_plugin_base.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/media_plugins/example/CMakeLists.txt b/linden/indra/media_plugins/example/CMakeLists.txt index 6d14c1b28..7822300ba 100755 --- a/linden/indra/media_plugins/example/CMakeLists.txt +++ b/linden/indra/media_plugins/example/CMakeLists.txt @@ -14,7 +14,7 @@ include(PluginAPI) include(MediaPluginBase) include(FindOpenGL) -#awfixme include(ExamplePlugin) +#include(ExamplePlugin) include_directories( ${LLPLUGIN_INCLUDE_DIRS} @@ -29,13 +29,13 @@ include_directories( ### media_plugin_example -if(WORD_SIZE EQUAL 64) +if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) if(WINDOWS) add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif (WORD_SIZE EQUAL 64) +endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) set(media_plugin_example_SOURCE_FILES media_plugin_example.cpp diff --git a/linden/indra/media_plugins/example/media_plugin_example.cpp b/linden/indra/media_plugins/example/media_plugin_example.cpp index 83abae0a7..1eabe6c85 100755 --- a/linden/indra/media_plugins/example/media_plugin_example.cpp +++ b/linden/indra/media_plugins/example/media_plugin_example.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -120,17 +121,6 @@ void MediaPluginExample::receiveMessage( const char* message_string ) std::string plugin_version = "Example media plugin, Example Version 1.0.0.0"; message.setValue( "plugin_version", plugin_version ); sendMessage( message ); - - // Plugin gets to decide the texture parameters to use. - message.setMessage( LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params" ); - message.setValueS32( "default_width", mWidth ); - message.setValueS32( "default_height", mHeight ); - message.setValueS32( "depth", mDepth ); - message.setValueU32( "internalformat", GL_RGBA ); - message.setValueU32( "format", GL_RGBA ); - message.setValueU32( "type", GL_UNSIGNED_BYTE ); - message.setValueBoolean( "coords_opengl", false ); - sendMessage( message ); } else if ( message_name == "idle" ) @@ -192,7 +182,20 @@ void MediaPluginExample::receiveMessage( const char* message_string ) else if ( message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA ) { - if ( message_name == "size_change" ) + if ( message_name == "init" ) + { + // Plugin gets to decide the texture parameters to use. + LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params" ); + message.setValueS32( "default_width", mWidth ); + message.setValueS32( "default_height", mHeight ); + message.setValueS32( "depth", mDepth ); + message.setValueU32( "internalformat", GL_RGBA ); + message.setValueU32( "format", GL_RGBA ); + message.setValueU32( "type", GL_UNSIGNED_BYTE ); + message.setValueBoolean( "coords_opengl", false ); + sendMessage( message ); + } + else if ( message_name == "size_change" ) { std::string name = message_in.getValue( "name" ); S32 width = message_in.getValueS32( "width" ); diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt index 3b73e0478..ee1684927 100755 --- a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -30,6 +30,14 @@ include_directories( ### media_plugin_gstreamer010 +if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) + set(media_plugin_gstreamer010_SOURCE_FILES media_plugin_gstreamer010.cpp llmediaimplgstreamer_syms.cpp @@ -42,13 +50,6 @@ set(media_plugin_gstreamer010_HEADER_FILES llmediaimplgstreamertriviallogging.h ) -if (${CXX_VERSION_NUMBER} MATCHES "4[23].") - # Work around a bad interaction between broken gstreamer headers and - # g++ 4.3's increased strictness. - set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES - COMPILE_FLAGS -Wno-write-strings) -endif (${CXX_VERSION_NUMBER} MATCHES "4[23].") - add_library(media_plugin_gstreamer010 SHARED ${media_plugin_gstreamer010_SOURCE_FILES} diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h index 6920c3b3a..bfc443b9e 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h @@ -14,13 +14,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -30,6 +30,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp index 28960acec..82978addf 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h index 7955898d8..c30904311 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h index 27f0eed6c..f5da63720 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index 2b10a2aa3..924283011 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -54,7 +55,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); #define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ( - "sink", + (gchar*)"sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (SLV_ALLCAPS) @@ -514,18 +515,18 @@ plugin_init (GstPlugin * plugin) some g++ versions buggily avoid __attribute__((constructor)) functions - so we provide an explicit plugin init function. */ -void gst_slvideo_init_class (void) -{ -#define PACKAGE "packagehack" +#define PACKAGE (gchar*)"packagehack" // this macro quietly refers to PACKAGE internally - static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, - "private-slvideoplugin", - "SL Video sink plugin", - plugin_init, "0.1", GST_LICENSE_UNKNOWN, - "Second Life", - "http://www.secondlife.com/"); + (gchar*)"private-slvideoplugin", + (gchar*)"SL Video sink plugin", + plugin_init, (gchar*)"0.1", (gchar*)GST_LICENSE_UNKNOWN, + (gchar*)"Second Life", + (gchar*)"http://www.secondlife.com/"); #undef PACKAGE +void gst_slvideo_init_class (void) +{ ll_gst_plugin_register_static (&gst_plugin_desc); DEBUGMSG("CLASS INIT"); } diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index fad80cbbc..56f6db956 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 82e6fdc45..7d34a1ec0 100755 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -947,33 +948,6 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string) message.setValue("plugin_version", getVersion()); sendMessage(message); - - // Plugin gets to decide the texture parameters to use. - message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - // lame to have to decide this now, it depends on the movie. Oh well. - mDepth = 4; - - mCurrentWidth = 1; - mCurrentHeight = 1; - mPreviousWidth = 1; - mPreviousHeight = 1; - mNaturalWidth = 1; - mNaturalHeight = 1; - mWidth = 1; - mHeight = 1; - mTextureWidth = 1; - mTextureHeight = 1; - - message.setValueU32("format", GL_RGBA); - message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); - - message.setValueS32("depth", mDepth); - message.setValueS32("default_width", mWidth); - message.setValueS32("default_height", mHeight); - message.setValueU32("internalformat", GL_RGBA8); - message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. - message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale - sendMessage(message); } else if(message_name == "idle") { @@ -1038,7 +1012,36 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string) } else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) { - if(message_name == "size_change") + if(message_name == "init") + { + // Plugin gets to decide the texture parameters to use. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + // lame to have to decide this now, it depends on the movie. Oh well. + mDepth = 4; + + mCurrentWidth = 1; + mCurrentHeight = 1; + mPreviousWidth = 1; + mPreviousHeight = 1; + mNaturalWidth = 1; + mNaturalHeight = 1; + mWidth = 1; + mHeight = 1; + mTextureWidth = 1; + mTextureHeight = 1; + + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); + + message.setValueS32("depth", mDepth); + message.setValueS32("default_width", mWidth); + message.setValueS32("default_height", mHeight); + message.setValueU32("internalformat", GL_RGBA8); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale + sendMessage(message); + } + else if(message_name == "size_change") { std::string name = message_in.getValue("name"); S32 width = message_in.getValueS32("width"); diff --git a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 9b4c5314b..68b9679d3 100755 --- a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -860,36 +861,6 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) plugin_version += codec.str(); message.setValue("plugin_version", plugin_version); sendMessage(message); - - // Plugin gets to decide the texture parameters to use. - message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - #if defined(LL_WINDOWS) - // Values for Windows - mDepth = 3; - message.setValueU32("format", GL_RGB); - message.setValueU32("type", GL_UNSIGNED_BYTE); - - // We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even. - // Padding to a multiple of 3*32 guarantees it'll divide out properly. - message.setValueU32("padding", 32 * 3); - #else - // Values for Mac - mDepth = 4; - message.setValueU32("format", GL_BGRA_EXT); - #ifdef __BIG_ENDIAN__ - message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV ); - #else - message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8); - #endif - - // Pad texture width to a multiple of 32 bytes, to line up with cache lines. - message.setValueU32("padding", 32); - #endif - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGB); - message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. - message.setValueBoolean("allow_downsample", true); - sendMessage(message); } else if(message_name == "idle") { @@ -954,7 +925,41 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) } else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) { - if(message_name == "size_change") + if(message_name == "init") + { + // This is the media init message -- all necessary data for initialization should have been received. + + // Plugin gets to decide the texture parameters to use. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + #if defined(LL_WINDOWS) + // Values for Windows + mDepth = 3; + message.setValueU32("format", GL_RGB); + message.setValueU32("type", GL_UNSIGNED_BYTE); + + // We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even. + // Padding to a multiple of 3*32 guarantees it'll divide out properly. + message.setValueU32("padding", 32 * 3); + #else + // Values for Mac + mDepth = 4; + message.setValueU32("format", GL_BGRA_EXT); + #ifdef __BIG_ENDIAN__ + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV ); + #else + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8); + #endif + + // Pad texture width to a multiple of 32 bytes, to line up with cache lines. + message.setValueU32("padding", 32); + #endif + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); + sendMessage(message); + } + else if(message_name == "size_change") { std::string name = message_in.getValue("name"); S32 width = message_in.getValueS32("width"); diff --git a/linden/indra/media_plugins/webkit/CMakeLists.txt b/linden/indra/media_plugins/webkit/CMakeLists.txt index 1c999ba78..be02781ee 100644 --- a/linden/indra/media_plugins/webkit/CMakeLists.txt +++ b/linden/indra/media_plugins/webkit/CMakeLists.txt @@ -14,10 +14,12 @@ include(Linking) include(PluginAPI) include(MediaPluginBase) include(FindOpenGL) +#include(PulseAudio) include(WebKitLibPlugin) include_directories( + ${PULSEAUDIO_INCLUDE_DIRS} ${LLPLUGIN_INCLUDE_DIRS} ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} @@ -35,13 +37,13 @@ set(media_plugin_webkit_SOURCE_FILES media_plugin_webkit.cpp ) -if(WORD_SIZE EQUAL 64) +if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) if(WINDOWS) add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif (WORD_SIZE EQUAL 64) +endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) set(media_plugin_webkit_LINK_LIBRARIES ${LLPLUGIN_LIBRARIES} @@ -49,9 +51,11 @@ set(media_plugin_webkit_LINK_LIBRARIES ${LLCOMMON_LIBRARIES} ${WEBKIT_PLUGIN_LIBRARIES} ${PLUGIN_API_WINDOWS_LIBRARIES} + ${PULSEAUDIO_LIBRARIES} ) -if(LINUX) +if (LINUX) + list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp) list(APPEND media_plugin_webkit_LINK_LIBRARIES ${UI_LIBRARIES} # for glib/GTK ) diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp new file mode 100755 index 000000000..15a2dfb1f --- /dev/null +++ b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp @@ -0,0 +1,490 @@ +/** + * @file linux_volume_catcher.cpp + * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +/* + The high-level design is as follows: + 1) Connect to the PulseAudio daemon + 2) Watch for the creation of new audio players connecting to the daemon (this includes ALSA clients running on the PulseAudio emulation layer, such as Flash plugins) + 3) Examine any new audio player's PID to see if it belongs to our own process + 4) If so, tell PA to adjust the volume of that audio player ('sink input' in PA parlance) + 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call + */ + +#include "linden_common.h" + +#include "linux_volume_catcher.h" + + +#if LL_PULSEAUDIO_ENABLED + +extern "C" { +#include <glib.h> + +#include <pulse/introspect.h> +#include <pulse/context.h> +#include <pulse/subscribe.h> +#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. + +#include "apr_pools.h" +#include "apr_dso.h" +} + +//////////////////////////////////////////////////// + +#define DEBUGMSG(...) do {} while(0) +#define INFOMSG(...) do {} while(0) +#define WARNMSG(...) do {} while(0) + +#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) RTN (*ll##PASYM)(__VA_ARGS__) = NULL +#include "linux_volume_catcher_pa_syms.inc" +#include "linux_volume_catcher_paglib_syms.inc" +#undef LL_PA_SYM + +static bool sSymsGrabbed = false; +static apr_pool_t *sSymPADSOMemoryPool = NULL; +static apr_dso_handle_t *sSymPADSOHandleG = NULL; + +bool grab_pa_syms(std::string pulse_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 *sSymPADSOHandle = NULL; + +#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) + + //attempt to load the shared library + apr_pool_create(&sSymPADSOMemoryPool, NULL); + + if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, + pulse_dso_name.c_str(), + sSymPADSOMemoryPool) )) + { + INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); + +#include "linux_volume_catcher_pa_syms.inc" +#include "linux_volume_catcher_paglib_syms.inc" + + if ( sSymPADSOHandle ) + { + sSymPADSOHandleG = sSymPADSOHandle; + sSymPADSOHandle = NULL; + } + + rtn = !sym_error; + } + else + { + INFOMSG("Couldn't load DSO: %s", pulse_dso_name.c_str()); + rtn = false; // failure + } + + if (sym_error) + { + WARNMSG("Failed to find necessary symbols in PulseAudio libraries."); + } +#undef LL_PA_SYM + + sSymsGrabbed = rtn; + return rtn; +} + + +void ungrab_pa_syms() +{ + // should be safe to call regardless of whether we've + // actually grabbed syms. + + if ( sSymPADSOHandleG ) + { + apr_dso_unload(sSymPADSOHandleG); + sSymPADSOHandleG = NULL; + } + + if ( sSymPADSOMemoryPool ) + { + apr_pool_destroy(sSymPADSOMemoryPool); + sSymPADSOMemoryPool = NULL; + } + + // NULL-out all of the symbols we'd grabbed +#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) +#include "linux_volume_catcher_pa_syms.inc" +#include "linux_volume_catcher_paglib_syms.inc" +#undef LL_PA_SYM + + sSymsGrabbed = false; +} +//////////////////////////////////////////////////// + +// PulseAudio requires a chain of callbacks with C linkage +extern "C" { + void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata); + void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata); + void callback_context_state(pa_context *context, void *userdata); +} + + +class LinuxVolumeCatcherImpl +{ +public: + LinuxVolumeCatcherImpl(); + ~LinuxVolumeCatcherImpl(); + + void setVolume(F32 volume); + void pump(void); + + // for internal use - can't be private because used from our C callbacks + + bool loadsyms(std::string pulse_dso_name); + void init(); + void cleanup(); + + void update_all_volumes(F32 volume); + void update_index_volume(U32 index, F32 volume); + void connected_okay(); + + std::set<U32> mSinkInputIndices; + std::map<U32,U32> mSinkInputNumChannels; + F32 mDesiredVolume; + pa_glib_mainloop *mMainloop; + pa_context *mPAContext; + bool mConnected; + bool mGotSyms; +}; + +LinuxVolumeCatcherImpl::LinuxVolumeCatcherImpl() + : mDesiredVolume(0.0f), + mMainloop(NULL), + mPAContext(NULL), + mConnected(false), + mGotSyms(false) +{ + init(); +} + +LinuxVolumeCatcherImpl::~LinuxVolumeCatcherImpl() +{ + cleanup(); +} + +bool LinuxVolumeCatcherImpl::loadsyms(std::string pulse_dso_name) +{ + return grab_pa_syms(pulse_dso_name); +} + +void LinuxVolumeCatcherImpl::init() +{ + // try to be as defensive as possible because PA's interface is a + // bit fragile and (for our purposes) we'd rather simply not function + // than crash + + // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in + // libpulse.so.0 - this isn't a great assumption, and the two DSOs should + // probably be loaded separately. Our Linux DSO framework needs refactoring, + // we do this sort of thing a lot with practically identical logic... + mGotSyms = loadsyms("libpulse-mainloop-glib.so.0"); + if (!mGotSyms) return; + + mMainloop = llpa_glib_mainloop_new(g_main_context_default()); + if (mMainloop) + { + pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop); + if (api) + { + pa_proplist *proplist = llpa_proplist_new(); + if (proplist) + { + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1"); + + // plain old pa_context_new() is broken! + mPAContext = llpa_context_new_with_proplist(api, NULL, proplist); + llpa_proplist_free(proplist); + } + } + } + + // Now we've set up a PA context and mainloop, try connecting the + // PA context to a PA daemon. + if (mPAContext) + { + llpa_context_set_state_callback(mPAContext, callback_context_state, this); + pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN? + if (llpa_context_connect(mPAContext, NULL, cflags, NULL) >= 0) + { + // Okay! We haven't definitely connected, but we + // haven't definitely failed yet. + } + else + { + // Failed to connect to PA manager... we'll leave + // things like that. Perhaps we should try again later. + } + } +} + +void LinuxVolumeCatcherImpl::cleanup() +{ + mConnected = false; + + if (mGotSyms && mPAContext) + { + llpa_context_disconnect(mPAContext); + llpa_context_unref(mPAContext); + } + mPAContext = NULL; + + if (mGotSyms && mMainloop) + { + llpa_glib_mainloop_free(mMainloop); + } + mMainloop = NULL; +} + +void LinuxVolumeCatcherImpl::setVolume(F32 volume) +{ + mDesiredVolume = volume; + + if (!mGotSyms) return; + + if (mConnected && mPAContext) + { + update_all_volumes(mDesiredVolume); + } + + pump(); +} + +void LinuxVolumeCatcherImpl::pump() +{ + gboolean may_block = FALSE; + g_main_context_iteration(g_main_context_default(), may_block); +} + +void LinuxVolumeCatcherImpl::connected_okay() +{ + pa_operation *op; + + // fetch global list of existing sinkinputs + if ((op = llpa_context_get_sink_input_info_list(mPAContext, + callback_discovered_sinkinput, + this))) + { + llpa_operation_unref(op); + } + + // subscribe to future global sinkinput changes + llpa_context_set_subscribe_callback(mPAContext, + callback_subscription_alert, + this); + if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t) + (PA_SUBSCRIPTION_MASK_SINK_INPUT), + NULL, NULL))) + { + llpa_operation_unref(op); + } +} + +void LinuxVolumeCatcherImpl::update_all_volumes(F32 volume) +{ + for (std::set<U32>::iterator it = mSinkInputIndices.begin(); + it != mSinkInputIndices.end(); ++it) + { + update_index_volume(*it, volume); + } +} + +void LinuxVolumeCatcherImpl::update_index_volume(U32 index, F32 volume) +{ + static pa_cvolume cvol; + llpa_cvolume_set(&cvol, mSinkInputNumChannels[index], + llpa_sw_volume_from_linear(volume)); + + pa_context *c = mPAContext; + uint32_t idx = index; + const pa_cvolume *cvolumep = &cvol; + pa_context_success_cb_t cb = NULL; // okay as null + void *userdata = NULL; // okay as null + + pa_operation *op; + if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata))) + { + llpa_operation_unref(op); + } +} + + +void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata) +{ + LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + llassert(impl); + + if (0 == eol) + { + pa_proplist *proplist = sii->proplist; + pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID)); + + if (sinkpid == getpid()) // does the discovered sinkinput belong to this process? + { + bool is_new = (impl->mSinkInputIndices.find(sii->index) == + impl->mSinkInputIndices.end()); + + impl->mSinkInputIndices.insert(sii->index); + impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels; + + if (is_new) + { + // new! + impl->update_index_volume(sii->index, impl->mDesiredVolume); + } + else + { + // seen it already, do nothing. + } + } + } +} + +void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata) +{ + LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + llassert(impl); + + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == + PA_SUBSCRIPTION_EVENT_REMOVE) + { + // forget this sinkinput, if we were caring about it + impl->mSinkInputIndices.erase(index); + impl->mSinkInputNumChannels.erase(index); + } + else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == + PA_SUBSCRIPTION_EVENT_NEW) + { + // ask for more info about this new sinkinput + pa_operation *op; + if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl))) + { + llpa_operation_unref(op); + } + } + else + { + // property change on this sinkinput - we don't care. + } + break; + + default:; + } +} + +void callback_context_state(pa_context *context, void *userdata) +{ + LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + llassert(impl); + + switch (llpa_context_get_state(context)) + { + case PA_CONTEXT_READY: + impl->mConnected = true; + impl->connected_okay(); + break; + case PA_CONTEXT_TERMINATED: + impl->mConnected = false; + break; + case PA_CONTEXT_FAILED: + impl->mConnected = false; + break; + default:; + } +} + +///////////////////////////////////////////////////// + +LinuxVolumeCatcher::LinuxVolumeCatcher() +{ + pimpl = new LinuxVolumeCatcherImpl(); +} + +LinuxVolumeCatcher::~LinuxVolumeCatcher() +{ + delete pimpl; + pimpl = NULL; +} + +void LinuxVolumeCatcher::setVolume(F32 volume) +{ + llassert(pimpl); + pimpl->setVolume(volume); +} + +void LinuxVolumeCatcher::pump() +{ + llassert(pimpl); + pimpl->pump(); +} + +#else // !LL_PULSEAUDIO_ENABLED + +// stub. + +LinuxVolumeCatcher::LinuxVolumeCatcher() +{ + pimpl = NULL; +} + +LinuxVolumeCatcher::~LinuxVolumeCatcher() +{ +} + +void LinuxVolumeCatcher::setVolume(F32 volume) +{ +} + +void LinuxVolumeCatcher::pump() +{ +} + +#endif // LL_PULSEAUDIO_ENABLED diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher.h b/linden/indra/media_plugins/webkit/linux_volume_catcher.h new file mode 100755 index 000000000..d4a1b38f9 --- /dev/null +++ b/linden/indra/media_plugins/webkit/linux_volume_catcher.h @@ -0,0 +1,56 @@ +/** + * @file linux_volume_catcher.h + * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +#ifndef LINUX_VOLUME_CATCHER_H +#define LINUX_VOLUME_CATCHER_H + +#include "linden_common.h" + +class LinuxVolumeCatcherImpl; + +class LinuxVolumeCatcher +{ + public: + LinuxVolumeCatcher(); + ~LinuxVolumeCatcher(); + + void setVolume(F32 volume); // 0.0 - 1.0 + void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume + + private: + LinuxVolumeCatcherImpl *pimpl; +}; + +#endif // LINUX_VOLUME_CATCHER_H diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/linden/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc new file mode 100755 index 000000000..d806b4842 --- /dev/null +++ b/linden/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc @@ -0,0 +1,21 @@ +// required symbols to grab +LL_PA_SYM(true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api); +LL_PA_SYM(true, pa_context_disconnect, void, pa_context *c); +LL_PA_SYM(true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_get_state, pa_context_state_t, pa_context *c); +LL_PA_SYM(true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist); +LL_PA_SYM(true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata); +LL_PA_SYM(true, pa_context_unref, void, pa_context *c); +LL_PA_SYM(true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v); +LL_PA_SYM(true, pa_operation_unref, void, pa_operation *o); +LL_PA_SYM(true, pa_proplist_free, void, pa_proplist* p); +LL_PA_SYM(true, pa_proplist_gets, const char*, pa_proplist *p, const char *key); +LL_PA_SYM(true, pa_proplist_new, pa_proplist*, void); +LL_PA_SYM(true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value); +LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v); + +// optional symbols to grab diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc b/linden/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc new file mode 100755 index 000000000..abf628c96 --- /dev/null +++ b/linden/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc @@ -0,0 +1,6 @@ +// required symbols to grab +LL_PA_SYM(true, pa_glib_mainloop_free, void, pa_glib_mainloop* g); +LL_PA_SYM(true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g); +LL_PA_SYM(true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c); + +// optional symbols to grab diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index 2e3f06d67..28c6e98d4 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,9 +29,10 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ -#include <iomanip>//FIXME: This is included from elsewhere in SG2.0 + #include "llqtwebkit.h" #include "linden_common.h" @@ -44,11 +45,22 @@ #include "llpluginmessageclasses.h" #include "media_plugin_base.h" +// set to 1 if you're using the version of llqtwebkit that's QPixmap-ified +#if LL_LINUX +# define LL_QTWEBKIT_USES_PIXMAPS 0 +#else +# define LL_QTWEBKIT_USES_PIXMAPS 0 +#endif // LL_LINUX + +#if LL_LINUX +# include "linux_volume_catcher.h" +#endif // LL_LINUX + #if LL_WINDOWS -#include <direct.h> +# include <direct.h> #else -#include <unistd.h> -#include <stdlib.h> +# include <unistd.h> +# include <stdlib.h> #endif #if LL_WINDOWS @@ -78,10 +90,16 @@ class MediaPluginWebKit : private: std::string mProfileDir; + std::string mHostLanguage; + std::string mUserAgent; + bool mCookiesEnabled; + bool mJavascriptEnabled; + bool mPluginsEnabled; enum { - INIT_STATE_UNINITIALIZED, // Browser instance hasn't been set up yet + INIT_STATE_UNINITIALIZED, // LLQtWebkit hasn't been set up yet + INIT_STATE_INITIALIZED, // LLQtWebkit has been set up, but no browser window has been created yet. INIT_STATE_NAVIGATING, // Browser instance has been set up and initial navigate to about:blank has been issued INIT_STATE_NAVIGATE_COMPLETE, // initial navigate to about:blank has completed INIT_STATE_WAIT_REDRAW, // First real navigate begin has been received, waiting for page changed event to start handling redraws @@ -103,6 +121,10 @@ class MediaPluginWebKit : F32 mBackgroundG; F32 mBackgroundB; +#if LL_LINUX + LinuxVolumeCatcher mLinuxVolumeCatcher; +#endif // LL_LINUX + void setInitState(int state) { // std::cerr << "changing init state to " << state << std::endl; @@ -115,6 +137,10 @@ class MediaPluginWebKit : { LLQtWebKit::getInstance()->pump( milliseconds ); +#if LL_LINUX + mLinuxVolumeCatcher.pump(); +#endif // LL_LINUX + checkEditState(); if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) @@ -131,7 +157,11 @@ class MediaPluginWebKit : { const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId ); - unsigned int buffer_size = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId ) * LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId ); + unsigned int rowspan = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId ); + unsigned int height = LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId ); +#if !LL_QTWEBKIT_USES_PIXMAPS + unsigned int buffer_size = rowspan * height; +#endif // !LL_QTWEBKIT_USES_PIXMAPS // std::cerr << "webkit plugin: updating" << std::endl; @@ -139,7 +169,16 @@ class MediaPluginWebKit : if ( mPixels && browser_pixels ) { // std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl; + +#if LL_QTWEBKIT_USES_PIXMAPS + // copy the pixel data upside-down because of the co-ord system + for (int y=0; y<height; ++y) + { + memcpy( &mPixels[(height-y-1)*rowspan], &browser_pixels[y*rowspan], rowspan ); + } +#else memcpy( mPixels, browser_pixels, buffer_size ); +#endif // LL_QTWEBKIT_USES_PIXMAPS } if ( mWidth > 0 && mHeight > 0 ) @@ -160,13 +199,6 @@ class MediaPluginWebKit : if ( mInitState > INIT_STATE_UNINITIALIZED ) return true; - // not enough information to initialize the browser yet. - if ( mWidth < 0 || mHeight < 0 || mDepth < 0 || - mTextureWidth < 0 || mTextureHeight < 0 ) - { - return false; - }; - // set up directories char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) @@ -177,12 +209,12 @@ class MediaPluginWebKit : std::string application_dir = std::string( cwd ); #if LL_DARWIN - // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on. - // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger. - // This wouldn't cause any problems except for the fact that the current release version of the Flash plugin has a call to Debugger() in it - // which gets hit when the plugin is probed by webkit. - // Unsetting the environment variable here works around this issue. - unsetenv("USERBREAK"); + // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on. + // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger. + // This wouldn't cause any problems except for the fact that the current release version of the Flash plugin has a call to Debugger() in it + // which gets hit when the plugin is probed by webkit. + // Unsetting the environment variable here works around this issue. + unsetenv("USERBREAK"); #endif #if LL_WINDOWS @@ -223,65 +255,91 @@ class MediaPluginWebKit : bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle ); if ( result ) { - // create single browser window - mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight ); -#if LL_WINDOWS - // Enable plugins - LLQtWebKit::getInstance()->enablePlugins(true); -#elif LL_DARWIN - // Enable plugins - LLQtWebKit::getInstance()->enablePlugins(true); -#elif LL_LINUX - // Enable plugins - LLQtWebKit::getInstance()->enablePlugins(true); -#endif - // Enable cookies - LLQtWebKit::getInstance()->enableCookies( true ); - - // tell LLQtWebKit about the size of the browser window - LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); - - // observer events that LLQtWebKit emits - LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this ); - - // append details to agent string - LLQtWebKit::getInstance()->setBrowserAgentId( "LLPluginMedia Web Browser" ); - - // don't flip bitmap - LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); - - // set background color - // convert background color channels from [0.0, 1.0] to [0, 255]; - LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) ); - - // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns. - setInitState(INIT_STATE_NAVIGATING); - - // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance. - // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially - // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date. - // Build a data URL like this: "data:text/html,%3Chtml%3E%3Cbody bgcolor=%22#RRGGBB%22%3E%3C/body%3E%3C/html%3E" - // where RRGGBB is the background color in HTML style - std::stringstream url; + mInitState = INIT_STATE_INITIALIZED; - url << "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#"; - // convert background color channels from [0.0, 1.0] to [0, 255]; - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundR * 255.0f); - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundG * 255.0f); - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f); - url << "%22%3E%3C/body%3E%3C/html%3E"; - - lldebugs << "data url is: " << url.str() << llendl; - - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() ); -// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" ); - return true; }; return false; }; + //////////////////////////////////////////////////////////////////////////////// + // + bool initBrowserWindow() + { + // already initialized + if ( mInitState > INIT_STATE_INITIALIZED ) + return true; + + // not enough information to initialize the browser yet. + if ( mWidth < 0 || mHeight < 0 || mDepth < 0 || + mTextureWidth < 0 || mTextureHeight < 0 ) + { + return false; + }; + + // Set up host language before creating browser window + if(!mHostLanguage.empty()) + { + LLQtWebKit::getInstance()->setHostLanguage(mHostLanguage); + } + + // turn on/off cookies based on what host app tells us + LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled ); + + // turn on/off plugins based on what host app tells us + LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled ); + + // turn on/off Javascript based on what host app tells us + LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); + + // create single browser window + mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight ); + + // tell LLQtWebKit about the size of the browser window + LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); + + // observer events that LLQtWebKit emits + LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this ); + + // append details to agent string + LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); + +#if !LL_QTWEBKIT_USES_PIXMAPS + // don't flip bitmap + LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); +#endif // !LL_QTWEBKIT_USES_PIXMAPS + + // set background color + // convert background color channels from [0.0, 1.0] to [0, 255]; + LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) ); + + // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns. + setInitState(INIT_STATE_NAVIGATING); + + // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance. + // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially + // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date. + // Build a data URL like this: "data:text/html,%3Chtml%3E%3Cbody bgcolor=%22#RRGGBB%22%3E%3C/body%3E%3C/html%3E" + // where RRGGBB is the background color in HTML style + std::stringstream url; + + url << "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#"; + // convert background color channels from [0.0, 1.0] to [0, 255]; + url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundR * 255.0f); + url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundG * 255.0f); + url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f); + url << "%22%3E%3C/body%3E%3C/html%3E"; + + lldebugs << "data url is: " << url.str() << llendl; + + LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() ); +// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" ); + + return true; + } + + void setVolume(F32 vol); //////////////////////////////////////////////////////////////////////////////// // virtual @@ -616,6 +674,11 @@ MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_ mBackgroundR = 0.0f; mBackgroundG = 0.0f; mBackgroundB = 0.0f; + + mHostLanguage = "en"; // default to english + mJavascriptEnabled = true; // default to on + mPluginsEnabled = true; // default to on + mUserAgent = "LLPluginMedia Web Browser"; } MediaPluginWebKit::~MediaPluginWebKit() @@ -642,9 +705,6 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) { if(message_name == "init") { - std::string user_data_path = message_in.getValue("user_data_path"); // n.b. always has trailing platform-specific dir-delimiter - mProfileDir = user_data_path + "browser_profile"; - LLPluginMessage message("base", "init_response"); LLSD versions = LLSD::emptyMap(); versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; @@ -656,19 +716,6 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) plugin_version += LLQtWebKit::getInstance()->getVersion(); message.setValue("plugin_version", plugin_version); sendMessage(message); - - // Plugin gets to decide the texture parameters to use. - mDepth = 4; - - message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - message.setValueS32("default_width", 1024); - message.setValueS32("default_height", 1024); - message.setValueS32("depth", mDepth); - message.setValueU32("internalformat", GL_RGBA); - message.setValueU32("format", GL_RGBA); - message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", true); - sendMessage(message); } else if(message_name == "idle") { @@ -733,9 +780,68 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) // std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; } } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "set_volume") + { + F32 volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) { - if(message_name == "size_change") + if(message_name == "init") + { + // This is the media init message -- all necessary data for initialization should have been received. + if(initBrowser()) + { + + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGBA); + #if LL_QTWEBKIT_USES_PIXMAPS + message.setValueU32("format", GL_BGRA_EXT); // I hope this isn't system-dependant... is it? If so, we'll have to check the root window's pixel layout or something... yuck. + #else + message.setValueU32("format", GL_RGBA); + #endif // LL_QTWEBKIT_USES_PIXMAPS + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", true); + sendMessage(message); + } + else + { + // if initialization failed, we're done. + mDeleteMe = true; + } + + } + else if(message_name == "set_user_data_path") + { + std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter + mProfileDir = user_data_path + "browser_profile"; + + // FIXME: Should we do anything with this if it comes in after the browser has been initialized? + } + else if(message_name == "set_language_code") + { + mHostLanguage = message_in.getValue("language"); + + // FIXME: Should we do anything with this if it comes in after the browser has been initialized? + } + else if(message_name == "plugins_enabled") + { + mPluginsEnabled = message_in.getValueBoolean("enable"); + } + else if(message_name == "javascript_enabled") + { + mJavascriptEnabled = message_in.getValueBoolean("enable"); + } + else if(message_name == "size_change") { std::string name = message_in.getValue("name"); S32 width = message_in.getValueS32("width"); @@ -757,29 +863,36 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) mWidth = width; mHeight = height; - // initialize (only gets called once) - initBrowser(); - - // size changed so tell the browser - LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); - -// std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight -// << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl; - - S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId); - - // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response. - if(real_width <= texture_width) + if(initBrowserWindow()) { - texture_width = real_width; + + // size changed so tell the browser + LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); + + // std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight + // << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl; + + S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId); + + // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response. + if(real_width <= texture_width) + { + texture_width = real_width; + } + else + { + // This won't work -- it'll be bigger than the allocated memory. This is a fatal error. + // std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl; + mDeleteMe = true; + return; + } } else { - // This won't work -- it'll be bigger than the allocated memory. This is a fatal error. -// std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl; + // Setting up the browser window failed. This is a fatal error. mDeleteMe = true; - return; } + mTextureWidth = texture_width; mTextureHeight = texture_height; @@ -929,8 +1042,18 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) } else if(message_name == "enable_cookies") { - bool val = message_in.getValueBoolean("enable"); - LLQtWebKit::getInstance()->enableCookies( val ); + mCookiesEnabled = message_in.getValueBoolean("enable"); + LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled ); + } + else if(message_name == "enable_plugins") + { + mPluginsEnabled = message_in.getValueBoolean("enable"); + LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled ); + } + else if(message_name == "enable_javascript") + { + mJavascriptEnabled = message_in.getValueBoolean("enable"); + //LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); } else if(message_name == "proxy_setup") { @@ -967,8 +1090,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) } else if(message_name == "set_user_agent") { - std::string user_agent = message_in.getValue("user_agent"); - LLQtWebKit::getInstance()->setBrowserAgentId( user_agent ); + mUserAgent = message_in.getValue("user_agent"); + LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); } else if(message_name == "init_history") { @@ -999,6 +1122,13 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) } } +void MediaPluginWebKit::setVolume(F32 volume) +{ +#if LL_LINUX + mLinuxVolumeCatcher.setVolume(volume); +#endif // LL_LINUX +} + int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) { MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data); From 093b99196f27b518b183953cade1077fa6d7c5ed Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Mon, 14 Jun 2010 17:51:51 +0200 Subject: [PATCH 022/239] update llplugin to latest version of SG2, pull latest webkit --- linden/indra/llplugin/CMakeLists.txt | 4 +- linden/indra/llplugin/llpluginclassmedia.cpp | 48 ++++++++++++++++--- linden/indra/llplugin/llpluginclassmedia.h | 15 ++++-- .../indra/llplugin/llpluginclassmediaowner.h | 5 +- linden/indra/llplugin/llplugininstance.cpp | 5 +- linden/indra/llplugin/llplugininstance.h | 5 +- linden/indra/llplugin/llpluginmessage.cpp | 5 +- linden/indra/llplugin/llpluginmessage.h | 5 +- .../indra/llplugin/llpluginmessageclasses.h | 5 +- linden/indra/llplugin/llpluginmessagepipe.cpp | 5 +- linden/indra/llplugin/llpluginmessagepipe.h | 5 +- .../indra/llplugin/llpluginprocesschild.cpp | 7 ++- linden/indra/llplugin/llpluginprocesschild.h | 7 ++- .../indra/llplugin/llpluginprocessparent.cpp | 12 ++--- linden/indra/llplugin/llpluginprocessparent.h | 12 +++-- .../indra/llplugin/llpluginsharedmemory.cpp | 5 +- linden/indra/llplugin/llpluginsharedmemory.h | 5 +- linden/indra/llplugin/slplugin/slplugin.cpp | 16 +++++-- .../webkit/media_plugin_webkit.cpp | 1 + linden/indra/newview/llviewermedia.cpp | 2 +- linden/indra/newview/viewer_manifest.py | 3 +- linden/install.xml | 19 +++++--- 22 files changed, 132 insertions(+), 64 deletions(-) diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt index e41cdf71b..d9b623d5c 100755 --- a/linden/indra/llplugin/CMakeLists.txt +++ b/linden/indra/llplugin/CMakeLists.txt @@ -48,13 +48,13 @@ set(llplugin_HEADER_FILES set_source_files_properties(${llplugin_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) -if(WORD_SIZE EQUAL 64) +if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) if(WINDOWS) add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) -endif (WORD_SIZE EQUAL 64) +endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp index 2e8bf3fb8..b958f0c70 100755 --- a/linden/indra/llplugin/llpluginclassmedia.cpp +++ b/linden/indra/llplugin/llpluginclassmedia.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -66,15 +67,19 @@ LLPluginClassMedia::~LLPluginClassMedia() reset(); } -bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path) +bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug) { LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL; LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL; - LL_DEBUGS("Plugin") << "user_data_path: " << user_data_path << LL_ENDL; mPlugin = new LLPluginProcessParent(this); mPlugin->setSleepTime(mSleepTime); - mPlugin->init(launcher_filename, plugin_filename, debug, user_data_path); + + // Queue up the media init message -- it will be sent after all the currently queued messages. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init"); + sendMessage(message); + + mPlugin->init(launcher_filename, plugin_filename, debug); return true; } @@ -384,7 +389,7 @@ bool LLPluginClassMedia::textureValid(void) bool LLPluginClassMedia::getDirty(LLRect *dirty_rect) { - bool result = !mDirtyRect.isNull();//awfixme isEmpty(); + bool result = !mDirtyRect.isNull(); if(dirty_rect != NULL) { @@ -679,6 +684,34 @@ void LLPluginClassMedia::paste() sendMessage(message); } +void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path"); + message.setValue("path", user_data_path); + sendMessage(message); +} + +void LLPluginClassMedia::setLanguageCode(const std::string &language_code) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_language_code"); + message.setValue("language", language_code); + sendMessage(message); +} + +void LLPluginClassMedia::setPluginsEnabled(const bool enabled) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "plugins_enabled"); + message.setValueBoolean("enable", enabled); + sendMessage(message); +} + +void LLPluginClassMedia::setJavascriptEnabled(const bool enabled) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "javascript_enabled"); + message.setValueBoolean("enable", enabled); + sendMessage(message); +} + LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) { // convert a LinkTargetType value from llqtwebkit to an ETargetType @@ -746,7 +779,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) newDirtyRect.mBottom = temp; } - if(mDirtyRect.isNull())//awfixme isEmpty()) + if(mDirtyRect.isNull()) { mDirtyRect = newDirtyRect; } @@ -1048,6 +1081,7 @@ void LLPluginClassMedia::clear_cookies() void LLPluginClassMedia::enable_cookies(bool enable) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies"); + message.setValueBoolean("enable", enable); sendMessage(message); } diff --git a/linden/indra/llplugin/llpluginclassmedia.h b/linden/indra/llplugin/llpluginclassmedia.h index ab5434873..fc94563b2 100755 --- a/linden/indra/llplugin/llpluginclassmedia.h +++ b/linden/indra/llplugin/llpluginclassmedia.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -50,7 +51,9 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner virtual ~LLPluginClassMedia(); // local initialization, called by the media manager when creating a source - virtual bool init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path); + virtual bool init(const std::string &launcher_filename, + const std::string &plugin_filename, + bool debug); // undoes everything init() didm called by the media manager when destroying a source virtual void reset(); @@ -174,6 +177,12 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner void paste(); bool canPaste() const { return mCanPaste; }; + + // These can be called before init(), and they will be queued and sent before the media init message. + void setUserDataPath(const std::string &user_data_path); + void setLanguageCode(const std::string &language_code); + void setPluginsEnabled(const bool enabled); + void setJavascriptEnabled(const bool enabled); /////////////////////////////////// // media browser class functions diff --git a/linden/indra/llplugin/llpluginclassmediaowner.h b/linden/indra/llplugin/llpluginclassmediaowner.h index 239f69266..c1f6ae170 100755 --- a/linden/indra/llplugin/llpluginclassmediaowner.h +++ b/linden/indra/llplugin/llpluginclassmediaowner.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llplugininstance.cpp b/linden/indra/llplugin/llplugininstance.cpp index ce10cb638..b822b9e94 100755 --- a/linden/indra/llplugin/llplugininstance.cpp +++ b/linden/indra/llplugin/llplugininstance.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llplugininstance.h b/linden/indra/llplugin/llplugininstance.h index baa51cc08..9cf6075ff 100755 --- a/linden/indra/llplugin/llplugininstance.h +++ b/linden/indra/llplugin/llplugininstance.h @@ -12,13 +12,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -28,6 +28,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llpluginmessage.cpp b/linden/indra/llplugin/llpluginmessage.cpp index 8efc774ca..6452f4afc 100755 --- a/linden/indra/llplugin/llpluginmessage.cpp +++ b/linden/indra/llplugin/llpluginmessage.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llpluginmessage.h b/linden/indra/llplugin/llpluginmessage.h index 82eb89f96..fe504c8b9 100755 --- a/linden/indra/llplugin/llpluginmessage.h +++ b/linden/indra/llplugin/llpluginmessage.h @@ -12,13 +12,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -28,6 +28,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llpluginmessageclasses.h b/linden/indra/llplugin/llpluginmessageclasses.h index 9a39e98ca..8812a1676 100755 --- a/linden/indra/llplugin/llpluginmessageclasses.h +++ b/linden/indra/llplugin/llpluginmessageclasses.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llpluginmessagepipe.cpp b/linden/indra/llplugin/llpluginmessagepipe.cpp index 85ed2272b..b16381c48 100755 --- a/linden/indra/llplugin/llpluginmessagepipe.cpp +++ b/linden/indra/llplugin/llpluginmessagepipe.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llpluginmessagepipe.h b/linden/indra/llplugin/llpluginmessagepipe.h index 63fd569a0..8f74f38f8 100755 --- a/linden/indra/llplugin/llpluginmessagepipe.h +++ b/linden/indra/llplugin/llpluginmessagepipe.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llpluginprocesschild.cpp b/linden/indra/llplugin/llpluginprocesschild.cpp index e13376fc0..0b7ce3db4 100755 --- a/linden/indra/llplugin/llpluginprocesschild.cpp +++ b/linden/indra/llplugin/llpluginprocesschild.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -156,7 +157,6 @@ void LLPluginProcessChild::idle(void) { setState(STATE_PLUGIN_INITIALIZING); LLPluginMessage message("base", "init"); - message.setValue("user_data_path", mUserDataPath); sendMessageToPlugin(message); } break; @@ -329,7 +329,6 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) if(message_name == "load_plugin") { mPluginFile = parsed.getValue("file"); - mUserDataPath = parsed.getValue("user_data_path"); } else if(message_name == "shm_add") { diff --git a/linden/indra/llplugin/llpluginprocesschild.h b/linden/indra/llplugin/llpluginprocesschild.h index 8e9579e04..96ae7b491 100755 --- a/linden/indra/llplugin/llpluginprocesschild.h +++ b/linden/indra/llplugin/llpluginprocesschild.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -99,8 +100,6 @@ class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInst std::string mPluginFile; - std::string mUserDataPath; - LLPluginInstance *mInstance; typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType; diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp index 9b8ea8b3e..8ea28f19e 100755 --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -99,14 +100,12 @@ void LLPluginProcessParent::errorState(void) setState(STATE_ERROR); } -void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path) +void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug) { mProcess.setExecutable(launcher_filename); mPluginFile = plugin_filename; mCPUUsage = 0.0f; - mDebug = debug; - mUserDataPath = user_data_path; - + mDebug = debug; setState(STATE_INITIALIZED); } @@ -363,7 +362,6 @@ void LLPluginProcessParent::idle(void) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); message.setValue("file", mPluginFile); - message.setValue("user_data_path", mUserDataPath); sendMessage(message); } diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h index 6dbe0c174..523ce510c 100755 --- a/linden/indra/llplugin/llpluginprocessparent.h +++ b/linden/indra/llplugin/llpluginprocessparent.h @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ @@ -60,7 +61,10 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner LLPluginProcessParent(LLPluginProcessParentOwner *owner); ~LLPluginProcessParent(); - void init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug, const std::string &user_data_path); + void init(const std::string &launcher_filename, + const std::string &plugin_filename, + bool debug); + void idle(void); // returns true if the plugin is on its way to steady state @@ -144,8 +148,6 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner std::string mPluginFile; - std::string mUserDataPath; - LLPluginProcessParentOwner *mOwner; typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType; diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp index a475f122d..e8a411a53 100755 --- a/linden/indra/llplugin/llpluginsharedmemory.cpp +++ b/linden/indra/llplugin/llpluginsharedmemory.cpp @@ -13,13 +13,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -29,6 +29,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/llpluginsharedmemory.h b/linden/indra/llplugin/llpluginsharedmemory.h index 1d23cbe57..081d311b3 100755 --- a/linden/indra/llplugin/llpluginsharedmemory.h +++ b/linden/indra/llplugin/llpluginsharedmemory.h @@ -12,13 +12,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -28,6 +28,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * @endcond */ diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp index 526734ab0..649d56847 100755 --- a/linden/indra/llplugin/slplugin/slplugin.cpp +++ b/linden/indra/llplugin/slplugin/slplugin.cpp @@ -14,13 +14,13 @@ * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * online at http://secondlife.com/developers/opensource/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * http://secondlife.com/developers/opensource/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -30,6 +30,7 @@ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ + * * * @endcond */ @@ -240,6 +241,9 @@ int main(int argc, char **argv) checkExceptionHandler(); #endif +#if LL_DARWIN + EventTargetRef event_target = GetEventDispatcherTarget(); +#endif while(!plugin->isDone()) { timer.reset(); @@ -247,8 +251,12 @@ int main(int argc, char **argv) #if LL_DARWIN { // Some plugins (webkit at least) will want an event loop. This qualifies. - EventRecord evt; - WaitNextEvent(0, &evt, 0, NULL); + EventRef event; + if(ReceiveNextEvent(0, 0, kEventDurationNoWait, true, &event) == noErr) + { + SendEventToEventTarget (event, event_target); + ReleaseEvent(event); + } } #endif F64 elapsed = timer.getElapsedTimeF64(); diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index 28c6e98d4..09ba8dc21 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -47,6 +47,7 @@ // set to 1 if you're using the version of llqtwebkit that's QPixmap-ified #if LL_LINUX +# include <iomanip> # define LL_QTWEBKIT_USES_PIXMAPS 0 #else # define LL_QTWEBKIT_USES_PIXMAPS 0 diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index c0d146081..8c5cf6a14 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -480,7 +480,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ { LLPluginClassMedia* media_source = new LLPluginClassMedia(owner); media_source->setSize(default_width, default_height); - if (media_source->init(launcher_name, plugin_name, false, user_data_path)) + if (media_source->init(launcher_name, plugin_name, false)) { return media_source; } diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index fcebda92e..0c0099578 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -1092,7 +1092,8 @@ def construct(self): self.path("libcairo.so.2") self.path("libfontconfig.so.1") self.path("libfreetype.so.6") -# self.path("libgdk_pixbuf-2.0.so.0") # use systems gdk pixbufs instead + self.path("libgdk_pixbuf-2.0.so.0") # was commented to use systems gdk pixbufs instead - + # but seems webkit needs it o_O . Packaging for testing now. self.path("libgdk-x11-2.0.so.0") self.path("libgtk-x11-2.0.so.0") # self.path("libpango-1.0.so.0") # use systems pango instead diff --git a/linden/install.xml b/linden/install.xml index d9f400acd..07e7498c8 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -1144,23 +1144,30 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <key>darwin</key> <map> <key>md5sum</key> - <string>95f44f0023dddc80be4398fc4f213861</string> + <string>38a31c64cbb021320c6f8c0296933f2b</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100208.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100402.tar.bz2</uri> </map> <key>linux</key> <map> <key>md5sum</key> - <string>4c75b2f1e8524c7844ee3ea1cd59a3db</string> + <string>78e22d53c84c8642fbaa027fed20cc48</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20100209b.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20100407.tar.bz2</uri> + </map> + <key>linux64</key> + <map> + <key>md5sum</key> + <string>d602324a827be7e0a8c90f85d27d6151</string> + <key>url</key> + <uri>http://imprudenceviewer.org/download/libs/llqtwebkit-linux64-20100617.tar.bz2</uri> </map> <key>windows</key> <map> <key>md5sum</key> - <string>1e9798dc424a6f6c2bea50649bbcc7ae</string> + <string>b6ec5fe296b8ad9097b182b5c09a9589</string> <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100210.tar.bz2</uri> + <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100402.tar.bz2</uri> </map> </map> </map> From c4891694b7c8fcc469dfa057ebf397ee28fc44b1 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Thu, 17 Jun 2010 11:15:54 +0200 Subject: [PATCH 023/239] Robin Cornelius: fixes for building plugins on Linux 64bit --- linden/indra/cmake/00-Common.cmake | 8 ++++++++ linden/indra/cmake/LLCommon.cmake | 13 +++++++++++- linden/indra/llcommon/CMakeLists.txt | 20 +++++++++++++++++++ linden/indra/llplugin/CMakeLists.txt | 4 ++++ .../indra/media_plugins/base/CMakeLists.txt | 4 ++++ .../media_plugins/example/CMakeLists.txt | 4 ++++ .../media_plugins/gstreamer010/CMakeLists.txt | 4 ++++ .../indra/media_plugins/webkit/CMakeLists.txt | 4 ++++ linden/indra/newview/CMakeLists.txt | 2 ++ 9 files changed, 62 insertions(+), 1 deletion(-) mode change 100755 => 100644 linden/indra/llplugin/CMakeLists.txt mode change 100755 => 100644 linden/indra/media_plugins/base/CMakeLists.txt mode change 100755 => 100644 linden/indra/media_plugins/example/CMakeLists.txt mode change 100755 => 100644 linden/indra/media_plugins/gstreamer010/CMakeLists.txt diff --git a/linden/indra/cmake/00-Common.cmake b/linden/indra/cmake/00-Common.cmake index d335cb061..6403d4992 100644 --- a/linden/indra/cmake/00-Common.cmake +++ b/linden/indra/cmake/00-Common.cmake @@ -20,6 +20,14 @@ set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING "Supported build types." FORCE) +# Determine the number of bits of this processor + +if(CMAKE_SIZEOF_VOID_P MATCHES 4) + set( HAVE_64_BIT 0 ) +else(CMAKE_SIZEOF_VOID_P MATCHES 4) + set( HAVE_64_BIT 1 ) +endif(CMAKE_SIZEOF_VOID_P MATCHES 4) + # Platform-specific compilation flags. if (WINDOWS) diff --git a/linden/indra/cmake/LLCommon.cmake b/linden/indra/cmake/LLCommon.cmake index 410766e4f..9158e9824 100644 --- a/linden/indra/cmake/LLCommon.cmake +++ b/linden/indra/cmake/LLCommon.cmake @@ -12,4 +12,15 @@ set(LLCOMMON_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ) -set(LLCOMMON_LIBRARIES llcommon) +# Files that need PIC code (pluginAPI) need to set REQUIRE_PIC on 64bit systems +# this will link against a llcommon built with Position Independent Code +# this is a requirment to link a static library (.a) to a DSO on 64 bit systems + +if(REQUIRE_PIC) + set(LLCOMMON_LIBRARIES llcommonPIC) +else(REQUIRE_PIC) + set(LLCOMMON_LIBRARIES llcommon) +endif(REQUIRE_PIC) + +#force clear the flag, files that need this must explicity set it themselves +set(REQUIRE_PIC 0) \ No newline at end of file diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt index 1c12e5525..ae961a3ed 100644 --- a/linden/indra/llcommon/CMakeLists.txt +++ b/linden/indra/llcommon/CMakeLists.txt @@ -198,3 +198,23 @@ target_link_libraries( ${EXPAT_LIBRARIES} ${ZLIB_LIBRARIES} ) + +if(HAVE_64_BIT) + add_library (llcommonPIC ${llcommon_SOURCE_FILES}) + add_dependencies(llcommonPIC prepare) + + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) + + target_link_libraries( + llcommonPIC + ${APRUTIL_LIBRARIES} + ${APR_LIBRARIES} + ${EXPAT_LIBRARIES} + ${ZLIB_LIBRARIES} + ) +endif(HAVE_64_BIT) + diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt old mode 100755 new mode 100644 index d9b623d5c..8a2eff876 --- a/linden/indra/llplugin/CMakeLists.txt +++ b/linden/indra/llplugin/CMakeLists.txt @@ -2,6 +2,10 @@ project(llplugin) +if(HAVE_64_BIT) + set(REQUIRE_PIC) +endif(HAVE_64_BIT) + include(00-Common) include(LLCommon) include(LLImage) diff --git a/linden/indra/media_plugins/base/CMakeLists.txt b/linden/indra/media_plugins/base/CMakeLists.txt old mode 100755 new mode 100644 index 8d620433a..dd0b0a0b0 --- a/linden/indra/media_plugins/base/CMakeLists.txt +++ b/linden/indra/media_plugins/base/CMakeLists.txt @@ -2,6 +2,10 @@ project(media_plugin_base) +if(HAVE_64_BIT) + set(REQUIRE_PIC) +endif(HAVE_64_BIT) + include(00-Common) include(LLCommon) include(LLImage) diff --git a/linden/indra/media_plugins/example/CMakeLists.txt b/linden/indra/media_plugins/example/CMakeLists.txt old mode 100755 new mode 100644 index 7822300ba..bac5fa2fe --- a/linden/indra/media_plugins/example/CMakeLists.txt +++ b/linden/indra/media_plugins/example/CMakeLists.txt @@ -2,6 +2,10 @@ project(media_plugin_example) +if(HAVE_64_BIT) + set(REQUIRE_PIC) +endif(HAVE_64_BIT) + include(00-Common) include(LLCommon) include(LLImage) diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt old mode 100755 new mode 100644 index ee1684927..6eab49cd0 --- a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -2,6 +2,10 @@ project(media_plugin_gstreamer010) +if(HAVE_64_BIT) + set(REQUIRE_PIC) +endif(HAVE_64_BIT) + include(00-Common) include(LLCommon) include(LLImage) diff --git a/linden/indra/media_plugins/webkit/CMakeLists.txt b/linden/indra/media_plugins/webkit/CMakeLists.txt index be02781ee..a47d5e015 100644 --- a/linden/indra/media_plugins/webkit/CMakeLists.txt +++ b/linden/indra/media_plugins/webkit/CMakeLists.txt @@ -2,6 +2,10 @@ project(media_plugin_webkit) +if(HAVE_64_BIT) + set(REQUIRE_PIC) +endif(HAVE_64_BIT) + include(00-Common) include(LLCommon) include(LLImage) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 75ba97759..e0c6c61ce 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1472,10 +1472,12 @@ if (DARWIN) --build=${CMAKE_CURRENT_BINARY_DIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) add_custom_command( TARGET package POST_BUILD COMMAND ${PYTHON_EXECUTABLE} From 087e15e89930d51c3964329befb273ae3b2d330d Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Tue, 7 Sep 2010 13:41:02 +0200 Subject: [PATCH 024/239] port of LL renderpipeline/Kirstens S19 pipeline for bridging to Viewer 2 texture system --- linden/indra/llmath/llbbox.cpp | 162 + linden/indra/llmath/llbbox.h | 103 + linden/indra/llmath/llcamera.cpp | 24 + linden/indra/llmath/llcamera.h | 16 +- linden/indra/llmath/llmath.h | 2 +- linden/indra/llmath/llmodularmath.cpp | 36 + linden/indra/llmath/llvolume.cpp | 14 +- linden/indra/llprimitive/CMakeLists.txt | 1 + linden/indra/llrender/CMakeLists.txt | 6 +- linden/indra/llrender/llcubemap.cpp | 17 +- linden/indra/llrender/llfont.cpp | 2 +- linden/indra/llrender/llfontgl.cpp | 6 +- linden/indra/llrender/llgl.cpp | 8 +- linden/indra/llrender/llgl.h | 31 + linden/indra/llrender/llglslshader.cpp | 2 +- linden/indra/llrender/llimagegl.cpp | 451 ++- linden/indra/llrender/llimagegl.h | 117 +- linden/indra/llrender/llrender.cpp | 64 +- linden/indra/llrender/llrendertarget.cpp | 57 +- linden/indra/llrender/llrendertarget.h | 1 + linden/indra/llrender/lltextureatlas.cpp | 411 +++ linden/indra/llrender/lltextureatlas.h | 92 + linden/indra/llrender/llvertexbuffer.cpp | 72 +- linden/indra/newview/CMakeLists.txt | 4 + .../indra/newview/app_settings/settings.xml | 735 +++- .../shaders/class1/deferred/alphaF.glsl | 24 +- .../shaders/class1/deferred/alphaV.glsl | 10 +- .../shaders/class1/deferred/avatarAlphaF.glsl | 2 +- .../shaders/class1/deferred/avatarF.glsl | 13 +- .../class1/deferred/avatarShadowF.glsl | 3 +- .../class1/deferred/avatarShadowV.glsl | 3 +- .../shaders/class1/deferred/avatarV.glsl | 2 - .../shaders/class1/deferred/blurLightF.glsl | 41 +- .../shaders/class1/deferred/bumpF.glsl | 8 +- .../shaders/class1/deferred/bumpV.glsl | 3 - .../shaders/class1/deferred/diffuseF.glsl | 6 +- .../shaders/class1/deferred/diffuseV.glsl | 5 +- .../shaders/class1/deferred/fullbrightF.glsl | 28 +- .../shaders/class1/deferred/fullbrightV.glsl | 2 +- .../shaders/class1/deferred/giF.glsl | 165 + .../shaders/class1/deferred/giV.glsl | 22 + .../shaders/class1/deferred/luminanceF.glsl | 15 + .../shaders/class1/deferred/luminanceV.glsl | 20 + .../class1/deferred/multiPointLightF.glsl | 62 +- .../class1/deferred/multiSpotLightF.glsl | 184 + .../shaders/class1/deferred/pointLightF.glsl | 61 +- .../shaders/class1/deferred/pointLightV.glsl | 6 +- .../class1/deferred/postDeferredF.glsl | 57 + .../class1/deferred/postDeferredV.glsl | 17 + .../shaders/class1/deferred/postgiF.glsl | 107 + .../shaders/class1/deferred/postgiV.glsl | 16 + .../shaders/class1/deferred/shadowF.glsl | 3 + .../shaders/class1/deferred/shadowV.glsl | 10 +- .../shaders/class1/deferred/softenLightF.glsl | 4 - .../shaders/class1/deferred/spotLightF.glsl | 199 + .../shaders/class1/deferred/sunLightF.glsl | 111 +- .../shaders/class1/deferred/terrainF.glsl | 6 +- .../shaders/class1/deferred/terrainV.glsl | 2 - .../shaders/class1/deferred/treeF.glsl | 4 +- .../shaders/class1/deferred/treeV.glsl | 3 - .../shaders/class1/deferred/waterF.glsl | 2 +- .../shaders/class1/effects/colorFilterF.glsl | 31 + .../shaders/class1/effects/drawQuadV.glsl | 14 + .../shaders/class1/effects/nightVisionF.glsl | 42 + .../shaders/class2/deferred/alphaF.glsl | 112 + .../shaders/class2/deferred/alphaV.glsl | 75 + .../shaders/class2/deferred/avatarAlphaF.glsl | 77 + .../shaders/class2/deferred/avatarAlphaV.glsl | 78 + .../shaders/class2/deferred/blurLightF.glsl | 71 + .../shaders/class2/deferred/blurLightV.glsl | 17 + .../class2/deferred/multiSpotLightF.glsl | 188 + .../class2/deferred/postDeferredF.glsl | 59 + .../class2/deferred/postDeferredV.glsl | 17 + .../shaders/class2/deferred/softenLightF.glsl | 294 ++ .../shaders/class2/deferred/softenLightV.glsl | 24 + .../shaders/class2/deferred/spotLightF.glsl | 199 + .../shaders/class2/deferred/sunLightF.glsl | 203 ++ .../shaders/class2/deferred/sunLightV.glsl | 25 + .../shaders/class2/deferred/waterF.glsl | 139 + .../shaders/class2/deferred/waterV.glsl | 76 + .../shaders/class3/deferred/avatarF.glsl | 18 + .../shaders/class3/deferred/bumpF.glsl | 27 + .../shaders/class3/deferred/diffuseF.glsl | 18 + .../class3/deferred/giDownsampleF.glsl | 84 + .../class3/deferred/giDownsampleV.glsl | 17 + .../shaders/class3/deferred/giF.glsl | 219 ++ .../shaders/class3/deferred/giV.glsl | 22 + .../shaders/class3/deferred/luminanceF.glsl | 16 + .../shaders/class3/deferred/luminanceV.glsl | 20 + .../class3/deferred/postDeferredF.glsl | 76 + .../class3/deferred/postDeferredV.glsl | 17 + .../shaders/class3/deferred/postgiF.glsl | 87 + .../shaders/class3/deferred/postgiV.glsl | 17 + .../shaders/class3/deferred/softenLightF.glsl | 312 ++ .../shaders/class3/deferred/softenLightV.glsl | 24 + .../shaders/class3/deferred/treeF.glsl | 18 + .../shaders/class3/deferred/waterF.glsl | 139 + .../shaders/class3/effects/blurF.glsl | 31 + .../shaders/class3/effects/blurV.glsl | 35 + .../shaders/class3/effects/colorFilterF.glsl | 31 + .../shaders/class3/effects/drawQuadV.glsl | 14 + .../shaders/class3/effects/extractF.glsl | 22 + .../shaders/class3/effects/nightVisionF.glsl | 42 + .../shaders/class3/effects/simpleF.glsl | 14 + linden/indra/newview/llagent.cpp | 3 +- linden/indra/newview/llagent.h | 1 + linden/indra/newview/llappviewer.cpp | 2 +- linden/indra/newview/llcolorswatch.cpp | 3 +- linden/indra/newview/llcompilequeue.cpp | 1 - linden/indra/newview/llconsole.cpp | 166 +- linden/indra/newview/llconsole.h | 47 +- linden/indra/newview/lldebugview.cpp | 24 +- linden/indra/newview/lldrawable.cpp | 76 +- linden/indra/newview/lldrawable.h | 3 +- linden/indra/newview/lldrawpool.h | 5 + linden/indra/newview/lldrawpoolalpha.cpp | 59 +- linden/indra/newview/lldrawpoolavatar.cpp | 69 +- linden/indra/newview/lldrawpoolbump.cpp | 25 +- linden/indra/newview/lldrawpoolsky.cpp | 68 +- linden/indra/newview/lldrawpoolsky.h | 4 + linden/indra/newview/lldrawpoolterrain.cpp | 6 +- linden/indra/newview/lldrawpooltree.cpp | 15 +- linden/indra/newview/lldrawpoolwater.cpp | 20 +- linden/indra/newview/lldynamictexture.cpp | 21 +- linden/indra/newview/lldynamictexture.h | 4 +- linden/indra/newview/llface.cpp | 445 ++- linden/indra/newview/llface.h | 38 +- .../indra/newview/llfloaterassetbrowser.cpp | 18 +- linden/indra/newview/llfloaterchat.cpp | 3 +- .../newview/llfloaterhardwaresettings.cpp | 27 +- .../indra/newview/llfloaterhardwaresettings.h | 4 + linden/indra/newview/llfloaterlagmeter.cpp | 2 +- linden/indra/newview/llfloaterpostprocess.cpp | 66 +- linden/indra/newview/llfloaterreporter.cpp | 3 +- linden/indra/newview/llhudeffect.cpp | 2 +- linden/indra/newview/llhudtext.cpp | 2 + linden/indra/newview/llmanip.cpp | 2 +- linden/indra/newview/llmaniptranslate.h | 2 +- linden/indra/newview/llmediactrl.cpp | 3 +- linden/indra/newview/lloverlaybar.cpp | 1 - linden/indra/newview/llpanelvolume.cpp | 117 + linden/indra/newview/llpanelvolume.h | 5 + linden/indra/newview/llpostprocess.cpp | 594 +++ linden/indra/newview/llpostprocess.h | 274 ++ linden/indra/newview/llpreview.cpp | 1 + linden/indra/newview/llselectmgr.cpp | 22 +- linden/indra/newview/llselectmgr.h | 2 +- linden/indra/newview/llsky.cpp | 14 + linden/indra/newview/llspatialpartition.cpp | 390 +- linden/indra/newview/llspatialpartition.h | 62 +- linden/indra/newview/llstartup.cpp | 2 +- linden/indra/newview/llsurface.cpp | 20 +- linden/indra/newview/llsurfacepatch.cpp | 34 +- linden/indra/newview/llsurfacepatch.h | 1 + linden/indra/newview/lltexlayer.cpp | 26 +- linden/indra/newview/lltexlayer.h | 4 +- .../indra/newview/lltextureatlasmanager.cpp | 274 ++ linden/indra/newview/lltextureatlasmanager.h | 112 + linden/indra/newview/lltextureview.cpp | 238 +- linden/indra/newview/lltoolpie.h | 1 - linden/indra/newview/llviewercamera.cpp | 4 +- linden/indra/newview/llviewercontrol.cpp | 16 +- linden/indra/newview/llviewerdisplay.cpp | 27 +- linden/indra/newview/llviewerimage.cpp | 367 +- linden/indra/newview/llviewerimage.h | 31 +- linden/indra/newview/llviewerimagelist.cpp | 50 +- linden/indra/newview/llviewerimagelist.h | 4 +- linden/indra/newview/llviewerjointmesh.cpp | 10 +- linden/indra/newview/llviewermedia.cpp | 4 +- linden/indra/newview/llviewermenu.cpp | 20 +- linden/indra/newview/llviewerobject.cpp | 35 +- linden/indra/newview/llviewerobject.h | 11 +- linden/indra/newview/llviewerobjectlist.cpp | 2 +- linden/indra/newview/llviewerobjectlist.h | 1 - .../indra/newview/llviewerparceloverlay.cpp | 4 +- linden/indra/newview/llviewershadermgr.cpp | 106 +- linden/indra/newview/llviewershadermgr.h | 25 + linden/indra/newview/llviewerstats.h | 2 +- linden/indra/newview/llviewerwindow.cpp | 110 +- linden/indra/newview/llvlcomposition.cpp | 4 + linden/indra/newview/llvoavatar.cpp | 98 +- linden/indra/newview/llvoavatar.h | 10 +- linden/indra/newview/llvoclouds.cpp | 7 +- linden/indra/newview/llvoclouds.h | 2 +- linden/indra/newview/llvograss.cpp | 2 +- linden/indra/newview/llvograss.h | 2 +- linden/indra/newview/llvoground.cpp | 2 +- linden/indra/newview/llvoground.h | 2 +- linden/indra/newview/llvopartgroup.cpp | 20 +- linden/indra/newview/llvopartgroup.h | 2 +- linden/indra/newview/llvosky.cpp | 8 +- linden/indra/newview/llvosky.h | 4 +- linden/indra/newview/llvosurfacepatch.cpp | 18 +- linden/indra/newview/llvosurfacepatch.h | 3 +- linden/indra/newview/llvotextbubble.cpp | 2 +- linden/indra/newview/llvotextbubble.h | 2 +- linden/indra/newview/llvotree.cpp | 6 +- linden/indra/newview/llvotree.h | 2 +- linden/indra/newview/llvotreenew.h | 2 +- linden/indra/newview/llvovolume.cpp | 422 ++- linden/indra/newview/llvovolume.h | 23 +- linden/indra/newview/llvowater.cpp | 6 +- linden/indra/newview/llvowater.h | 2 +- linden/indra/newview/llwaterparammanager.cpp | 3 +- linden/indra/newview/llwlparammanager.cpp | 3 +- linden/indra/newview/llworld.h | 6 +- linden/indra/newview/pipeline.cpp | 3229 +++++++++++++---- linden/indra/newview/pipeline.h | 128 +- .../xui/en-us/floater_hardware_settings.xml | 30 +- .../skins/default/xui/en-us/floater_tools.xml | 44 +- 210 files changed, 12753 insertions(+), 2324 deletions(-) create mode 100644 linden/indra/llmath/llbbox.cpp create mode 100644 linden/indra/llmath/llbbox.h create mode 100644 linden/indra/llmath/llmodularmath.cpp create mode 100644 linden/indra/llrender/lltextureatlas.cpp create mode 100644 linden/indra/llrender/lltextureatlas.h create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl create mode 100644 linden/indra/newview/llpostprocess.cpp create mode 100644 linden/indra/newview/llpostprocess.h create mode 100644 linden/indra/newview/lltextureatlasmanager.cpp create mode 100644 linden/indra/newview/lltextureatlasmanager.h diff --git a/linden/indra/llmath/llbbox.cpp b/linden/indra/llmath/llbbox.cpp new file mode 100644 index 000000000..f0ec010c0 --- /dev/null +++ b/linden/indra/llmath/llbbox.cpp @@ -0,0 +1,162 @@ +/** + * @file llbbox.cpp + * @brief General purpose bounding box class (Not axis aligned) + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, /linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by /linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and /linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// self include +#include "llbbox.h" + +// library includes +#include "m4math.h" + +void LLBBox::addPointLocal(const LLVector3& p) +{ + if (mEmpty) + { + mMinLocal = p; + mMaxLocal = p; + mEmpty = FALSE; + } + else + { + mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] ); + mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] ); + mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] ); + mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] ); + mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] ); + mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] ); + } +} + +void LLBBox::addPointAgent( LLVector3 p) +{ + p -= mPosAgent; + p.rotVec( ~mRotation ); + addPointLocal( p ); +} + + +void LLBBox::addBBoxAgent(const LLBBox& b) +{ + if (mEmpty) + { + mPosAgent = b.mPosAgent; + mRotation = b.mRotation; + mMinLocal.clearVec(); + mMaxLocal.clearVec(); + } + LLVector3 vertex[8]; + vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + + LLMatrix4 m( b.mRotation ); + m.translate( b.mPosAgent ); + m.translate( -mPosAgent ); + m.rotate( ~mRotation ); + + for( S32 i=0; i<8; i++ ) + { + addPointLocal( vertex[i] * m ); + } +} + + +void LLBBox::expand( F32 delta ) +{ + mMinLocal.mV[VX] -= delta; + mMinLocal.mV[VY] -= delta; + mMinLocal.mV[VZ] -= delta; + mMaxLocal.mV[VX] += delta; + mMaxLocal.mV[VY] += delta; + mMaxLocal.mV[VZ] += delta; +} + +LLVector3 LLBBox::localToAgent(const LLVector3& v) const +{ + LLMatrix4 m( mRotation ); + m.translate( mPosAgent ); + return v * m; +} + +LLVector3 LLBBox::agentToLocal(const LLVector3& v) const +{ + LLMatrix4 m; + m.translate( -mPosAgent ); + m.rotate( ~mRotation ); // inverse rotation + return v * m; +} + +LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const +{ + LLMatrix4 m( mRotation ); + return v * m; +} + +LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const +{ + LLMatrix4 m( ~mRotation ); // inverse rotation + return v * m; +} + +BOOL LLBBox::containsPointLocal(const LLVector3& p) const +{ + if ( (p.mV[VX] < mMinLocal.mV[VX]) + ||(p.mV[VX] > mMaxLocal.mV[VX]) + ||(p.mV[VY] < mMinLocal.mV[VY]) + ||(p.mV[VY] > mMaxLocal.mV[VY]) + ||(p.mV[VZ] < mMinLocal.mV[VZ]) + ||(p.mV[VZ] > mMaxLocal.mV[VZ])) + { + return FALSE; + } + return TRUE; +} + +BOOL LLBBox::containsPointAgent(const LLVector3& p) const +{ + LLVector3 point_local = agentToLocal(p); + return containsPointLocal(point_local); +} + + +/* +LLBBox operator*(const LLBBox &a, const LLMatrix4 &b) +{ + return LLBBox( a.mMin * b, a.mMax * b ); +} +*/ diff --git a/linden/indra/llmath/llbbox.h b/linden/indra/llmath/llbbox.h new file mode 100644 index 000000000..355928406 --- /dev/null +++ b/linden/indra/llmath/llbbox.h @@ -0,0 +1,103 @@ +/** + * @file llbbox.h + * @brief General purpose bounding box class + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, /linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by /linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and /linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_BBOX_H +#define LL_BBOX_H + +#include "v3math.h" +#include "llquaternion.h" + +// Note: "local space" for an LLBBox is defined relative to agent space in terms of +// a translation followed by a rotation. There is no scale term since the LLBBox's min and +// max are not necessarily symetrical and define their own extents. + +class LLBBox +{ +public: + LLBBox() {mEmpty = TRUE;} + LLBBox( const LLVector3& pos_agent, + const LLQuaternion& rot, + const LLVector3& min_local, + const LLVector3& max_local ) + : + mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE ) + {} + + // Default copy constructor is OK. + + const LLVector3& getPositionAgent() const { return mPosAgent; } + const LLQuaternion& getRotation() const { return mRotation; } + + const LLVector3& getMinLocal() const { return mMinLocal; } + void setMinLocal( const LLVector3& min ) { mMinLocal = min; } + + const LLVector3& getMaxLocal() const { return mMaxLocal; } + void setMaxLocal( const LLVector3& max ) { mMaxLocal = max; } + + LLVector3 getCenterLocal() const { return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; } + LLVector3 getCenterAgent() const { return localToAgent( getCenterLocal() ); } + + LLVector3 getExtentLocal() const { return mMaxLocal - mMinLocal; } + + BOOL containsPointLocal(const LLVector3& p) const; + BOOL containsPointAgent(const LLVector3& p) const; + + void addPointAgent(LLVector3 p); + void addBBoxAgent(const LLBBox& b); + + void addPointLocal(const LLVector3& p); + void addBBoxLocal(const LLBBox& b) { addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); } + + void expand( F32 delta ); + + LLVector3 localToAgent( const LLVector3& v ) const; + LLVector3 agentToLocal( const LLVector3& v ) const; + + // Changes rotation but not position + LLVector3 localToAgentBasis(const LLVector3& v) const; + LLVector3 agentToLocalBasis(const LLVector3& v) const; + + +// friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b); + +private: + LLVector3 mMinLocal; + LLVector3 mMaxLocal; + LLVector3 mPosAgent; // Position relative to Agent's Region + LLQuaternion mRotation; + BOOL mEmpty; // Nothing has been added to this bbox yet +}; + +//LLBBox operator*(const LLBBox &a, const LLMatrix4 &b); + + +#endif // LL_BBOX_H diff --git a/linden/indra/llmath/llcamera.cpp b/linden/indra/llmath/llcamera.cpp index 0f343bcef..0609e2f7f 100644 --- a/linden/indra/llmath/llcamera.cpp +++ b/linden/indra/llmath/llcamera.cpp @@ -246,6 +246,10 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) for (U32 i = 0; i < mPlaneCount; i++) { mask = mAgentPlanes[i].mask; + if (mask == 0xff) + { + continue; + } LLPlane p = mAgentPlanes[i].p; LLVector3 n = LLVector3(p); float d = p.mV[3]; @@ -294,6 +298,10 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& r } mask = mAgentPlanes[i].mask; + if (mask == 0xff) + { + continue; + } LLPlane p = mAgentPlanes[i].p; LLVector3 n = LLVector3(p); float d = p.mV[3]; @@ -437,6 +445,11 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) int res = 2; for (int i = 0; i < 6; i++) { + if (mAgentPlanes[i].mask == 0xff) + { + continue; + } + float d = mAgentPlanes[i].p.dist(sphere_center); if (d > radius) @@ -622,6 +635,17 @@ U8 LLCamera::calcPlaneMask(const LLPlane& plane) return mask; } +void LLCamera::ignoreAgentFrustumPlane(S32 idx) +{ + if (idx < 0 || idx > (S32) mPlaneCount) + { + return; + } + + mAgentPlanes[idx].mask = 0xff; + mAgentPlanes[idx].p.clearVec(); +} + void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { diff --git a/linden/indra/llmath/llcamera.h b/linden/indra/llmath/llcamera.h index 23ee1157f..0c8106791 100644 --- a/linden/indra/llmath/llcamera.h +++ b/linden/indra/llmath/llcamera.h @@ -93,6 +93,17 @@ class LLCamera PLANE_TOP_MASK = (1<<PLANE_TOP), PLANE_ALL_MASK = 0xf }; + + enum + { + AGENT_PLANE_LEFT = 0, + AGENT_PLANE_RIGHT, + AGENT_PLANE_NEAR, + AGENT_PLANE_BOTTOM, + AGENT_PLANE_TOP, + AGENT_PLANE_FAR, + }; + enum { HORIZ_PLANE_LEFT = 0, HORIZ_PLANE_RIGHT = 1, @@ -132,7 +143,8 @@ class LLCamera public: LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane - + LLPlane getAgentPlane(U32 idx) { return mAgentPlanes[idx].p; } + public: LLCamera(); LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); @@ -179,6 +191,8 @@ class LLCamera // Return number of bytes copied. size_t readFrustumFromBuffer(const char *buffer); void calcAgentFrustumPlanes(LLVector3* frust); + void ignoreAgentFrustumPlane(S32 idx); + // Returns 1 if partly in, 2 if fully in. // NOTE: 'center' is in absolute frame. S32 sphereInFrustumOld(const LLVector3 ¢er, const F32 radius) const; diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h index 0de568cbd..ec1076d84 100644 --- a/linden/indra/llmath/llmath.h +++ b/linden/indra/llmath/llmath.h @@ -203,7 +203,7 @@ inline S32 llfloor( F32 f ) } return result; #else - return (S32)floor(f); + return (S32)floorf(f); #endif } diff --git a/linden/indra/llmath/llmodularmath.cpp b/linden/indra/llmath/llmodularmath.cpp new file mode 100644 index 000000000..f0afeb7bd --- /dev/null +++ b/linden/indra/llmath/llmodularmath.cpp @@ -0,0 +1,36 @@ +/** + * @file llmodularmath.cpp + * @brief LLModularMath class implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, /linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by /linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and /linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes. +#include "llmodularmath.h" diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index b0b8a94e4..a1d891a26 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp @@ -2208,16 +2208,10 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, S32 requested_sizeS = 0; S32 requested_sizeT = 0; - // create oblong sculpties with high LOD always - F32 sculpt_detail = mDetail; - if (sculpt_width != sculpt_height && sculpt_detail < 4.0) - { - sculpt_detail = 4.0; - } - sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, sculpt_detail, requested_sizeS, requested_sizeT); + sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT); - mPathp->generate(mParams.getPathParams(), sculpt_detail, 0, TRUE, requested_sizeS); - mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), sculpt_detail, 0, TRUE, requested_sizeT); + mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); + mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got @@ -4274,7 +4268,7 @@ LLFaceID LLVolume::generateFaceMask() } break; default: - llerrs << "Unknown profile!" << llendl + llerrs << "Unknown profile!" << llendl; break; } diff --git a/linden/indra/llprimitive/CMakeLists.txt b/linden/indra/llprimitive/CMakeLists.txt index e7ee81141..716b2476f 100755 --- a/linden/indra/llprimitive/CMakeLists.txt +++ b/linden/indra/llprimitive/CMakeLists.txt @@ -52,6 +52,7 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) +add_dependencies(llprimitive prepare) #add unit tests INCLUDE(LLAddBuildTest) diff --git a/linden/indra/llrender/CMakeLists.txt b/linden/indra/llrender/CMakeLists.txt index 0bdb55f9d..e42f9ab26 100644 --- a/linden/indra/llrender/CMakeLists.txt +++ b/linden/indra/llrender/CMakeLists.txt @@ -32,9 +32,9 @@ set(llrender_SOURCE_FILES llgldbg.cpp llglslshader.cpp llimagegl.cpp - llpostprocess.cpp llrendersphere.cpp llshadermgr.cpp + lltextureatlas.cpp llvertexbuffer.cpp ) @@ -53,10 +53,10 @@ set(llrender_HEADER_FILES llglstates.h llgltypes.h llimagegl.h - llpostprocess.h llrender.h llrendersphere.h llshadermgr.h + lltextureatlas.h llvertexbuffer.h ) @@ -81,6 +81,7 @@ if (SERVER AND NOT WINDOWS AND NOT DARWIN) ${llrender_SOURCE_FILES} ${server_SOURCE_FILES} ) + add_dependencies(llrenderheadless prepare) else (SERVER AND NOT WINDOWS AND NOT DARWIN) list(APPEND llrender_SOURCE_FILES llgl.cpp @@ -89,3 +90,4 @@ else (SERVER AND NOT WINDOWS AND NOT DARWIN) ) endif (SERVER AND NOT WINDOWS AND NOT DARWIN) add_library (llrender ${llrender_SOURCE_FILES}) +add_dependencies(llrender prepare) diff --git a/linden/indra/llrender/llcubemap.cpp b/linden/indra/llrender/llcubemap.cpp index a5c677dd4..e0923e41d 100644 --- a/linden/indra/llrender/llcubemap.cpp +++ b/linden/indra/llrender/llcubemap.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewergpl$ * - * Copyright (c) 2002-2009, Linden Research, Inc. + * Copyright (c) 2002-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -63,6 +63,12 @@ LLCubeMap::LLCubeMap() mTextureCoordStage(0), mMatrixStage(0) { + mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; + mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; + mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; + mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; + mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; } LLCubeMap::~LLCubeMap() @@ -75,13 +81,6 @@ void LLCubeMap::initGL() if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) { - mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; - mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; - mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; - mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; - mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; - mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; - // Not initialized, do stuff. if (mImages[0].isNull()) { @@ -94,7 +93,7 @@ void LLCubeMap::initGL() mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE)); mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP); mRawImages[i] = new LLImageRaw(64, 64, 4); - mImages[i]->createGLTexture(0, mRawImages[i], texname, TRUE); + mImages[i]->createGLTexture(0, mRawImages[i], texname); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname); mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/linden/indra/llrender/llfont.cpp b/linden/indra/llrender/llfont.cpp index dd3312884..da5eda0cc 100644 --- a/linden/indra/llrender/llfont.cpp +++ b/linden/indra/llrender/llfont.cpp @@ -81,7 +81,7 @@ LLFontManager::LLFontManager() if (error) { // Clean up freetype libs. - llerrs << "Freetype initialization failure!" << llendl; + llwarns << "Freetype initialization failure!" << llendl; FT_Done_FreeType(gFTLibrary); } } diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp index 5d3d6a7fd..9d1f1d453 100644 --- a/linden/indra/llrender/llfontgl.cpp +++ b/linden/indra/llrender/llfontgl.cpp @@ -121,7 +121,7 @@ LLFontGL::LLFontGL() LLFontGL::LLFontGL(const LLFontGL &source) { - llerrs << "Not implemented!" << llendl; + llwarns << "Not implemented!" << llendl; } LLFontGL::~LLFontGL() @@ -278,7 +278,7 @@ void LLFontGL::destroyGL() LLFontGL &LLFontGL::operator=(const LLFontGL &source) { - llerrs << "Not implemented" << llendl; + llwarns << "Not implemented" << llendl; return *this; } @@ -584,7 +584,7 @@ S32 LLFontGL::render(const LLWString &wstr, const LLFontGlyphInfo* fgi= getGlyphInfo(wch); if (!fgi) { - llerrs << "Missing Glyph Info" << llendl; + llwarns << "Missing Glyph Info" << llendl; break; } // Per-glyph bitmap texture. diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp index 61194c4ec..be3ed9674 100644 --- a/linden/indra/llrender/llgl.cpp +++ b/linden/indra/llrender/llgl.cpp @@ -59,11 +59,13 @@ BOOL gDebugGL = FALSE; BOOL gClothRipple = FALSE; BOOL gNoRender = FALSE; +BOOL gGLActive = FALSE; LLMatrix4 gGLObliqueProjectionInverse; #define LL_GL_NAME_POOLING 0 LLGLNamePool::pool_list_t LLGLNamePool::sInstances; +std::list<LLGLUpdate*> LLGLUpdate::sGLQ; #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS // ATI prototypes @@ -1001,7 +1003,7 @@ void assert_glerror() if (quit) { - llerrs << "One or more unhandled GL errors." << llendl; + llwarns << "One or more unhandled GL errors." << llendl; } } @@ -1695,11 +1697,11 @@ void LLGLNamePool::release(GLuint name) } else { - llerrs << "Attempted to release a pooled name that is not in use!" << llendl; + llwarns << "Attempted to release a pooled name that is not in use!" << llendl; } } } - llerrs << "Attempted to release a non pooled name!" << llendl; + llwarns << "Attempted to release a non pooled name!" << llendl; #else releaseName(name); #endif diff --git a/linden/indra/llrender/llgl.h b/linden/indra/llrender/llgl.h index 00ff1e2f5..88552ce3f 100644 --- a/linden/indra/llrender/llgl.h +++ b/linden/indra/llrender/llgl.h @@ -358,6 +358,35 @@ class LLGLNamePool virtual void releaseName(GLuint name) = 0; }; +/* + Interface for objects that need periodic GL updates applied to them. + Used to synchronize GL updates with GL thread. +*/ +class LLGLUpdate +{ +public: + + static std::list<LLGLUpdate*> sGLQ; + + BOOL mInQ; + LLGLUpdate() + : mInQ(FALSE) + { + } + virtual ~LLGLUpdate() + { + if (mInQ) + { + std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this); + if (iter != sGLQ.end()) + { + sGLQ.erase(iter); + } + } + } + virtual void updateGL() = 0; +}; + extern LLMatrix4 gGLObliqueProjectionInverse; #include "llglstates.h" @@ -376,4 +405,6 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor extern BOOL gClothRipple; extern BOOL gNoRender; +extern BOOL gGLActive; + #endif // LL_LLGL_H diff --git a/linden/indra/llrender/llglslshader.cpp b/linden/indra/llrender/llglslshader.cpp index 08d654805..18974a7e0 100644 --- a/linden/indra/llrender/llglslshader.cpp +++ b/linden/indra/llrender/llglslshader.cpp @@ -408,7 +408,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode) { if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) { - llerrs << "Texture channel " << index << " texture type corrupted." << llendl; + llwarns << "Texture channel " << index << " texture type corrupted." << llendl; } gGL.getTexUnit(index)->disable(); } diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp index 7cd4dd7f2..1bddd49aa 100644 --- a/linden/indra/llrender/llimagegl.cpp +++ b/linden/indra/llrender/llimagegl.cpp @@ -43,6 +43,8 @@ #include "llmath.h" #include "llgl.h" #include "llrender.h" +#include "lltextureatlas.h" + //---------------------------------------------------------------------------- const F32 MIN_TEXTURE_LIFETIME = 10.f; @@ -56,19 +58,17 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0; S32 LLImageGL::sBoundTextureMemoryInBytes = 0; S32 LLImageGL::sCurBoundTextureMemory = 0; S32 LLImageGL::sCount = 0; +std::list<U32> LLImageGL::sDeadTextureList; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; F32 LLImageGL::sLastFrameTime = 0.f; -BOOL LLImageGL::sAllowReadBackRaw = FALSE ; +BOOL LLImageGL::sUseTextureAtlas = FALSE ; // render-pipeline KL std::set<LLImageGL*> LLImageGL::sImageList; -//**************************************************************************************************** -//The below for texture auditing use only -//**************************************************************************************************** +#if !LL_RELEASE_FOR_DOWNLOAD //----------------------- //debug use -BOOL gAuditTexture = FALSE ; #define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048 std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ; std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ; @@ -76,15 +76,8 @@ std::vector<S32> LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ; S32 LLImageGL::sCurTexSizeBar = -1 ; S32 LLImageGL::sCurTexPickSize = -1 ; LLPointer<LLImageGL> LLImageGL::sDefaultTexturep = NULL; -S32 LLImageGL::sMaxCatagories = 1 ; - -std::vector<S32> LLImageGL::sTextureMemByCategory; -std::vector<S32> LLImageGL::sTextureMemByCategoryBound ; -std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ; //------------------------ -//**************************************************************************************************** -//End for texture auditing use only -//**************************************************************************************************** +#endif //************************************************************************************** //below are functions for debug use @@ -110,9 +103,12 @@ void LLImageGL::checkTexSize() const { GLint texname; glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname); + BOOL error = FALSE; if (texname != mTexName) { - llerrs << "Invalid texture bound!" << llendl; + + llwarns << "Invalid texture bound!" << llendl; + } stop_glerror() ; LLGLint x = 0, y = 0 ; @@ -125,7 +121,15 @@ void LLImageGL::checkTexSize() const } if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel)) { - llerrs << "wrong texture size and discard level!" << llendl ; + error = TRUE; + + llwarns << "wrong texture size and discard level!" << llendl; + + } + + if (error) + { + llwarns << "LLImageGL::checkTexSize failed." << llendl; } } } @@ -133,20 +137,6 @@ void LLImageGL::checkTexSize() const //************************************************************************************** //---------------------------------------------------------------------------- -//static -void LLImageGL::initClass(S32 num_catagories) -{ - sMaxCatagories = num_catagories ; - - sTextureMemByCategory.resize(sMaxCatagories); - sTextureMemByCategoryBound.resize(sMaxCatagories) ; - sTextureCurMemByCategoryBound.resize(sMaxCatagories) ; -} - -//static -void LLImageGL::cleanupClass() -{ -} //static S32 LLImageGL::dataFormatBits(S32 dataformat) @@ -165,7 +155,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) case GL_RGBA: return 32; case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac default: - llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; + llwarns << "LLImageGL::Unknown format: " << dataformat << llendl; return 0; } } @@ -200,7 +190,7 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) case GL_RGBA: return 4; case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac default: - llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; + llwarns << "LLImageGL::Unknown format: " << dataformat << llendl; return 0; } } @@ -214,43 +204,25 @@ void LLImageGL::updateStats(F32 current_time) sBoundTextureMemoryInBytes = sCurBoundTextureMemory; sCurBoundTextureMemory = 0; - if(gAuditTexture) +#if !LL_RELEASE_FOR_DOWNLOAD + for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++) { - for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++) - { - sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ; - sTextureCurBoundCounter[i] = 0 ; - } - for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++) - { - sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ; - sTextureCurMemByCategoryBound[i] = 0 ; - } + sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ; + sTextureCurBoundCounter[i] = 0 ; } +#endif } //static -S32 LLImageGL::updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) -{ - if(gAuditTexture) - { - sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ; - sTextureCurMemByCategoryBound[category] += delta ; - } - - LLImageGL::sCurBoundTextureMemory += delta ; - return LLImageGL::sCurBoundTextureMemory; -} - -S32 LLImageGL::updateBoundTexMem()const -{ - if(gAuditTexture) - { - sTextureCurBoundCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ; - sTextureCurMemByCategoryBound[mCategory] += mTextureMemory ; - } - - LLImageGL::sCurBoundTextureMemory += mTextureMemory ; +//#if !LL_RELEASE_FOR_DOWNLOAD +//S32 LLImageGL::updateBoundTexMem(const S32 delta, const S32 size) +//{ +// sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ; +//#else +S32 LLImageGL::updateBoundTexMem(const S32 delta) +{ +//#endif + LLImageGL::sCurBoundTextureMemory += delta; return LLImageGL::sCurBoundTextureMemory; } @@ -264,7 +236,6 @@ void LLImageGL::destroyGL(BOOL save_state) gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } - sAllowReadBackRaw = true ; for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); iter != sImageList.end(); iter++) { @@ -284,7 +255,7 @@ void LLImageGL::destroyGL(BOOL save_state) stop_glerror(); } } - sAllowReadBackRaw = false ; +// sAllowReadBackRaw = false ; } //static @@ -296,13 +267,13 @@ void LLImageGL::restoreGL() LLImageGL* glimage = *iter; if(glimage->getTexName()) { - llerrs << "tex name is not 0." << llendl ; + llwarns << "tex name is not 0." << llendl ; } if (glimage->mSaveData.notNull()) { if (glimage->getComponents() && glimage->mSaveData->getComponents()) { - glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory()); + glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData); stop_glerror(); } glimage->mSaveData = NULL; // deletes data @@ -384,7 +355,7 @@ void LLImageGL::init(BOOL usemipmaps) mTextureState = NO_DELETE ; mTextureMemory = 0; mLastBindTime = 0.f; - + mTarget = GL_TEXTURE_2D; mBindTarget = LLTexUnit::TT_TEXTURE; mUseMipMaps = usemipmaps; @@ -411,9 +382,12 @@ void LLImageGL::init(BOOL usemipmaps) mHasExplicitFormat = FALSE; mGLTextureCreated = FALSE ; - mIsMask = FALSE; - mCategory = -1 ; +// mCategory = -1 ; + mCanAddToAtlas = TRUE ; + mDiscardLevelInAtlas = -1 ; + mTexelsInAtlas = 0 ; + mTexelsInGLTexture = 0 ; } void LLImageGL::cleanup() @@ -455,7 +429,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents) // Check if dimensions are a power of two! if (!checkSize(width,height)) { - llerrs << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; + llwarns << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; } if (mTexName) @@ -513,10 +487,6 @@ void LLImageGL::dump() } //---------------------------------------------------------------------------- -void LLImageGL::forceUpdateBindStats(void) const -{ - mLastBindTime = sLastFrameTime; -} void LLImageGL::updateBindStats(void) const { @@ -530,8 +500,12 @@ void LLImageGL::updateBindStats(void) const { // we haven't accounted for this texture yet this frame sUniqueCount++; - - updateBoundTexMem(); + +//#if !LL_RELEASE_FOR_DOWNLOAD +// updateBoundTexMem(mTextureMemory, getWidth(mCurrentDiscardLevel) * getHeight(mCurrentDiscardLevel)) ; +//#else + updateBoundTexMem(mTextureMemory); +//#endif mLastBindTime = sLastFrameTime; } } @@ -544,7 +518,7 @@ bool LLImageGL::bindError(const S32 stage) const } //virtual -bool LLImageGL::bindDefaultImage(const S32 stage) +bool LLImageGL::bindDefaultImage(const S32 stage) const { return false; } @@ -583,6 +557,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { // LLFastTimer t1(LLFastTimer::FTM_TEMP1); + llpushcallstacks ; bool is_compressed = false; if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) { @@ -590,7 +565,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } // LLFastTimer t2(LLFastTimer::FTM_TEMP2); - gGL.getTexUnit(0)->bind(this); + llverify(gGL.getTexUnit(0)->bind(this, false, true)); if (mUseMipMaps) { @@ -753,7 +728,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } else { - llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; + llwarns << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; } mHasMipMaps = true; } @@ -795,10 +770,63 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } stop_glerror(); mGLTextureCreated = true; + llpushcallstacks ; +} + +BOOL LLImageGL::canAddToAtlas() +{ + return sUseTextureAtlas && mCanAddToAtlas ; +} + +BOOL LLImageGL::addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) +{ + if(!atlasp) + { + return FALSE ; + } + + preAddToAtlas(raw_image->getWidth()) ; + LLGLuint tex_name = atlasp->insertSubTexture(raw_image, slot_col, slot_row); + postAddToAtlas() ; + + if(tex_name > 0) //successfully added to atlas + { + //gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); + //gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); + gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); + return TRUE ; + } + + return FALSE ; +} + +void LLImageGL::preAddToAtlas(S32 data_width) +{ + glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width); + stop_glerror(); + + if(mFormatSwapBytes) + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); + stop_glerror(); + } } -BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) +void LLImageGL::postAddToAtlas() { + if(mFormatSwapBytes) + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); + stop_glerror(); + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + stop_glerror(); +} + +BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) +{ + llpushcallstacks ; if (!width || !height) { return TRUE; @@ -814,8 +842,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 return FALSE; } - // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture. - if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) + if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) { setImage(datap, FALSE); } @@ -824,7 +851,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 if (mUseMipMaps) { dump(); - llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; + llwarns << "setSubImage called with mipmapped image (not supported)" << llendl; } llassert_always(mCurrentDiscardLevel == 0); llassert_always(x_pos >= 0 && y_pos >= 0); @@ -833,7 +860,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 (y_pos + height) > getHeight()) { dump(); - llerrs << "Subimage not wholly in target image!" + llwarns << "Subimage not wholly in target image!" << " x_pos " << x_pos << " y_pos " << y_pos << " width " << width @@ -847,7 +874,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 (y_pos + height) > data_height) { dump(); - llerrs << "Subimage not wholly in source image!" + llwarns << "Subimage not wholly in source image!" << " x_pos " << x_pos << " y_pos " << y_pos << " width " << width @@ -870,7 +897,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 datap += (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName); - if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; + if (!res) llwarns << "LLImageGL::setSubImage(): bindTexture failed" << llendl; stop_glerror(); glTexSubImage2D(mTarget, 0, x_pos, y_pos, @@ -888,12 +915,13 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 stop_glerror(); mGLTextureCreated = true; } + llpushcallstacks ; return TRUE; } -BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) +BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) { - return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update); + return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height); } // Copy sub image from frame buffer @@ -901,7 +929,6 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ { if (gGL.getTexUnit(0)->bind(this, false, true)) { - //checkTexSize() ; glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); mGLTextureCreated = true; stop_glerror(); @@ -922,13 +949,17 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures) // static void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) { - glDeleteTextures(numTextures, (GLuint*)textures); + for (S32 i = 0; i < numTextures; i++) + { + sDeadTextureList.push_back(textures[i]); + } } // static void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels) { glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); + stop_glerror(); } //create an empty GL texture: just create a texture name @@ -955,21 +986,26 @@ BOOL LLImageGL::createGLTexture() stop_glerror(); if (!mTexName) { - llerrs << "LLImageGL::createGLTexture failed to make an empty texture" << llendl; + llwarns << "LLImageGL::createGLTexture failed to make an empty texture" << llendl; } return TRUE ; } -BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category) +BOOL LLImageGL::createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) { + if(!sUseTextureAtlas) + { + return FALSE ; + } + if (gGLManager.mIsDisabled) { llwarns << "Trying to create a texture while GL is disabled!" << llendl; return FALSE; } - mGLTextureCreated = false ; + // mGLTextureCreated = false ; // KL not in SD llassert(gGLManager.mInited); stop_glerror(); @@ -981,10 +1017,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); // Actual image width/height = raw image width/height * 2^discard_level - S32 raw_w = imageraw->getWidth() ; - S32 raw_h = imageraw->getHeight() ; - S32 w = raw_w << discard_level; - S32 h = raw_h << discard_level; + S32 w = imageraw->getWidth() << discard_level; + S32 h = imageraw->getHeight() << discard_level; // setSize may call destroyGLTexture if the size does not match setSize(w, h, imageraw->getComponents()); @@ -1016,27 +1050,87 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S mFormatType = GL_UNSIGNED_BYTE; break; default: - LL_DEBUGS("Openjpeg") << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL; - to_create = false; - break; + llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl; } } - if(!to_create) //not create a gl texture + if(addToAtlas(imageraw, atlasp, slot_col, slot_row)) { - destroyGLTexture(); + // destroyGLTexture(); mCurrentDiscardLevel = discard_level; + mDiscardLevelInAtlas = discard_level; + mTexelsInAtlas = imageraw->getWidth() * imageraw->getHeight() ; mLastBindTime = sLastFrameTime; + mGLTextureCreated = false ; return TRUE ; } + return FALSE ; +} + +BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/) +{ + if (gGLManager.mIsDisabled) + { + llwarns << "Trying to create a texture while GL is disabled!" << llendl; + return FALSE; + } + + mGLTextureCreated = false ; + llassert(gGLManager.mInited); + stop_glerror(); + + if (discard_level < 0) + { + llassert(mCurrentDiscardLevel >= 0); + discard_level = mCurrentDiscardLevel; + } + discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); + + // Actual image width/height = raw image width/height * 2^discard_level + S32 w = imageraw->getWidth() << discard_level; + S32 h = imageraw->getHeight() << discard_level; + + // setSize may call destroyGLTexture if the size does not match + setSize(w, h, imageraw->getComponents()); + + if( !mHasExplicitFormat ) + { + switch (mComponents) + { + case 1: + // Use luminance alpha (for fonts) + mFormatInternal = GL_LUMINANCE8; + mFormatPrimary = GL_LUMINANCE; + mFormatType = GL_UNSIGNED_BYTE; + break; + case 2: + // Use luminance alpha (for fonts) + mFormatInternal = GL_LUMINANCE8_ALPHA8; + mFormatPrimary = GL_LUMINANCE_ALPHA; + mFormatType = GL_UNSIGNED_BYTE; + break; + case 3: + mFormatInternal = GL_RGB8; + mFormatPrimary = GL_RGB; + mFormatType = GL_UNSIGNED_BYTE; + break; + case 4: + mFormatInternal = GL_RGBA8; + mFormatPrimary = GL_RGBA; + mFormatType = GL_UNSIGNED_BYTE; + break; + default: + llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl; + } + } - mCategory = category ; const U8* rawdata = imageraw->getData(); return createGLTexture(discard_level, rawdata, FALSE, usename); } BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) { + llpushcallstacks ; llassert(data_in); if (discard_level < 0) @@ -1073,7 +1167,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ } if (!mTexName) { - llerrs << "LLImageGL::createGLTexture failed to make texture" << llendl; + llwarns << "LLImageGL::createGLTexture failed to make texture" << llendl; } if (mUseMipMaps) @@ -1104,30 +1198,30 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ if (old_name != 0) { sGlobalTextureMemoryInBytes -= mTextureMemory; - - if(gAuditTexture) - { - decTextureCounter() ; - } +#if !LL_RELEASE_FOR_DOWNLOAD + decTextureCounter(mTextureMemory / mComponents) ; +#endif LLImageGL::deleteTextures(1, &old_name); - stop_glerror(); } mTextureMemory = getMipBytes(discard_level); sGlobalTextureMemoryInBytes += mTextureMemory; + mTexelsInGLTexture = getWidth() * getHeight() ; + +#if !LL_RELEASE_FOR_DOWNLOAD + incTextureCounter(mTextureMemory / mComponents) ; +#endif setActive() ; - if(gAuditTexture) - { - incTextureCounter() ; - } // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; + + llpushcallstacks ; return TRUE; } -#if 0 + BOOL LLImageGL::setDiscardLevel(S32 discard_level) { llassert(discard_level >= 0); @@ -1149,7 +1243,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) { // larger image dump(); - llerrs << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl; + llwarns << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl; return FALSE; } else if (mUseMipMaps) @@ -1174,19 +1268,30 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) { #if !LL_LINUX && !LL_SOLARIS // *FIX: This should not be skipped for the linux client. - llerrs << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; + llwarns << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; #endif return FALSE; } } -#endif + +BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) +{ + assert_glerror(); + S32 gl_discard = discard_level - mCurrentDiscardLevel; + LLGLint glwidth = 0; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth); + LLGLint glheight = 0; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_HEIGHT, (GLint*)&glheight); + LLGLint glcomponents = 0 ; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&glcomponents); + assert_glerror(); + + return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ; +} BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) { - // VWR-13505 : Merov : Allow gl texture read back so save texture works again (temporary) - //llassert_always(sAllowReadBackRaw) ; - //llerrs << "should not call this function!" << llendl ; - + llpushcallstacks ; if (discard_level < 0) { discard_level = mCurrentDiscardLevel; @@ -1291,41 +1396,48 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre return FALSE ; } //----------------------------------------------------------------------------------------------- - + llpushcallstacks ; return TRUE ; } -void LLImageGL::destroyGLTexture() +void LLImageGL::deleteDeadTextures() { - if (mTexName != 0) + while (!sDeadTextureList.empty()) { - stop_glerror(); - + GLuint tex = sDeadTextureList.front(); + sDeadTextureList.pop_front(); for (int i = 0; i < gGLManager.mNumTextureUnits; i++) { - if (sCurrentBoundTextures[i] == mTexName) + if (sCurrentBoundTextures[i] == tex) { gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); } } - + + glDeleteTextures(1, &tex); + stop_glerror(); + } +} + +void LLImageGL::destroyGLTexture() +{ + if (mTexName != 0) + { if(mTextureMemory) { - if(gAuditTexture) - { - decTextureCounter() ; - } +#if !LL_RELEASE_FOR_DOWNLOAD + decTextureCounter(mTextureMemory / mComponents) ; +#endif sGlobalTextureMemoryInBytes -= mTextureMemory; mTextureMemory = 0; } - + LLImageGL::deleteTextures(1, &mTexName); - mTextureState = DELETED ; + mTextureState = DELETED ; mTexName = 0; mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mGLTextureCreated = FALSE ; - stop_glerror(); } } @@ -1354,12 +1466,12 @@ void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option) mFilterOption = option; } - if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) + if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) { gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option); mTexOptionsDirty = false; + stop_glerror(); } - stop_glerror(); } BOOL LLImageGL::getIsResident(BOOL test_now) @@ -1435,11 +1547,6 @@ S32 LLImageGL::getMipBytes(S32 discard_level) const return res; } -BOOL LLImageGL::isJustBound() const -{ - return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f); -} - BOOL LLImageGL::getBoundRecently() const { return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME); @@ -1601,7 +1708,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) U32 pick_offset = pick_bit%8; if (pick_idx >= mPickMaskSize) { - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } mPickMask[pick_idx] |= 1 << pick_offset; @@ -1627,7 +1734,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) if (u < 0.f || u > 1.f || v < 0.f || v > 1.f) { - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; // WTF really useful info NOT } S32 x = (S32)(u * width); @@ -1650,24 +1757,8 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) return res; } -void LLImageGL::setCategory(S32 category) -{ - if(!gAuditTexture) - { - return ; - } - if(mCategory != category) - { - if(mCategory > -1) - { - sTextureMemByCategory[mCategory] -= mTextureMemory ; - } - sTextureMemByCategory[category] += mTextureMemory ; - - mCategory = category; - } -} - +//---------------------------------------------------------------------------- +#if !LL_RELEASE_FOR_DOWNLOAD //for debug use //val is a "power of two" number S32 LLImageGL::getTextureCounterIndex(U32 val) @@ -1691,38 +1782,18 @@ S32 LLImageGL::getTextureCounterIndex(U32 val) return ret ; } } -void LLImageGL::incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) +void LLImageGL::incTextureCounter(U32 val) { sTextureLoadedCounter[getTextureCounterIndex(val)]++ ; - sTextureMemByCategory[category] += (S32)val * ncomponents ; } -void LLImageGL::decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) +void LLImageGL::decTextureCounter(U32 val) { sTextureLoadedCounter[getTextureCounterIndex(val)]-- ; - sTextureMemByCategory[category] += (S32)val * ncomponents ; -} -void LLImageGL::incTextureCounter() -{ - sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ; - sTextureMemByCategory[mCategory] += mTextureMemory ; -} -void LLImageGL::decTextureCounter() -{ - sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]-- ; - sTextureMemByCategory[mCategory] -= mTextureMemory ; } -void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size) +void LLImageGL::setCurTexSizebar(S32 index) { sCurTexSizeBar = index ; - - if(set_pick_size) - { - sCurTexPickSize = (1 << index) ; - } - else - { - sCurTexPickSize = -1 ; - } + sCurTexPickSize = (1 << index) ; } void LLImageGL::resetCurTexSizebar() { @@ -1730,9 +1801,7 @@ void LLImageGL::resetCurTexSizebar() sCurTexPickSize = -1 ; } //---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- - +#endif // Manual Mip Generation /* diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h index c7114c36a..56f79ffb1 100644 --- a/linden/indra/llrender/llimagegl.h +++ b/linden/indra/llrender/llimagegl.h @@ -45,18 +45,23 @@ #define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) #define MEGA_BYTES_TO_BYTES(x) ((x) << 20) +class LLTextureAtlas ; //============================================================================ + class LLImageGL : public LLRefCount { friend class LLTexUnit; public: + static std::list<U32> sDeadTextureList; + + static void deleteDeadTextures(); + // Size calculation static S32 dataFormatBits(S32 dataformat); static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); void updateBindStats(void) const; - void forceUpdateBindStats(void) const; // needs to be called every frame static void updateStats(F32 current_time); @@ -65,10 +70,12 @@ class LLImageGL : public LLRefCount static void destroyGL(BOOL save_state = TRUE); static void restoreGL(); - // Sometimes called externally for textures not using LLImageGL (should go away...) - static S32 updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) ; - S32 updateBoundTexMem()const; - + // Sometimes called externally for textures not using LLImageGL (should go away...) +//#if !LL_RELEASE_FOR_DOWNLOAD +// static S32 updateBoundTexMem(const S32 delta, const S32 size) ; +//#else + static S32 updateBoundTexMem(const S32 delta); +//#endif static bool checkSize(S32 width, S32 height); // Not currently necessary for LLImageGL, but required in some derived classes, @@ -90,7 +97,7 @@ class LLImageGL : public LLRefCount public: virtual void dump(); // debugging info to llinfos virtual bool bindError(const S32 stage = 0) const; - virtual bool bindDefaultImage(const S32 stage = 0) ; + virtual bool bindDefaultImage(const S32 stage = 0) const; virtual void forceImmediateUpdate() ; void setSize(S32 width, S32 height, S32 ncomponents); @@ -102,15 +109,14 @@ class LLImageGL : public LLRefCount static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels); BOOL createGLTexture() ; - BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, - S32 category = sMaxCatagories - 1); + BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0); BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0); void setImage(const LLImageRaw* imageraw); void setImage(const U8* data_in, BOOL data_hasmips = FALSE); - BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); - BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); - + BOOL setDiscardLevel(S32 discard_level); // Read back a raw image for this discard level, if it exists BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); void destroyGLTexture(); @@ -130,7 +136,7 @@ class LLImageGL : public LLRefCount S32 getBytes(S32 discard_level = -1) const; S32 getMipBytes(S32 discard_level = -1) const; BOOL getBoundRecently() const; - BOOL isJustBound() const; + //BOOL isJustBound() const; LLGLenum getPrimaryFormat() const { return mFormatPrimary; } BOOL getHasGLTexture() const { return mTexName != 0; } @@ -151,6 +157,8 @@ class LLImageGL : public LLRefCount BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } BOOL getDontDiscard() const { return mDontDiscard; } + BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; + void updatePickMask(S32 width, S32 height, const U8* data_in); BOOL getMask(const LLVector2 &tc); @@ -176,8 +184,20 @@ class LLImageGL : public LLRefCount void setActive() ; void forceActive() ; void setNoDelete() ; + + BOOL canAddToAtlas() ; + BOOL createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row); + BOOL addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) ; + + LLGLenum getTexTarget()const { return mTarget ;} + S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;} + U32 getTexelsInAtlas()const { return mTexelsInAtlas ;} + U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;} - void setTextureSize(S32 size) {mTextureMemory = size;} +private: + void preAddToAtlas(S32 data_width) ; + void postAddToAtlas() ; + protected: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors @@ -186,7 +206,7 @@ class LLImageGL : public LLRefCount // Various GL/Rendering options S32 mTextureMemory; mutable F32 mLastBindTime; // last time this was bound, by discard level - + private: LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel @@ -202,8 +222,15 @@ class LLImageGL : public LLRefCount U16 mWidth; U16 mHeight; S8 mCurrentDiscardLevel; - + + S8 mDiscardLevelInAtlas; + U32 mTexelsInAtlas ; + U32 mTexelsInGLTexture; + protected: + + BOOL mCanAddToAtlas ; + LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps) LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps) bool mHasMipMaps; @@ -241,42 +268,18 @@ class LLImageGL : public LLRefCount static S32 sCount; static F32 sLastFrameTime; - + static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID // Global memory statistics static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem - static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame + static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame 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; -#if DEBUG_MISS - BOOL mMissed; // Missed on last bind? - BOOL getMissed() const { return mMissed; }; -#else - BOOL getMissed() const { return FALSE; }; -#endif - -public: - static void initClass(S32 num_catagories) ; - static void cleanupClass() ; -private: - static S32 sMaxCatagories ; - - //the flag to allow to call readBackRaw(...). - //can be removed if we do not use that function at all. - static BOOL sAllowReadBackRaw ; -// -//**************************************************************************************************** -//The below for texture auditing use only -//**************************************************************************************************** -private: - S32 mCategory ; -public: - void setCategory(S32 category) ; - S32 getCategory()const {return mCategory ;} - + static BOOL sUseTextureAtlas ; +#if !LL_RELEASE_FOR_DOWNLOAD //for debug use: show texture size distribution //---------------------------------------- static LLPointer<LLImageGL> sDefaultTexturep; //default texture to replace normal textures @@ -287,27 +290,19 @@ class LLImageGL : public LLRefCount static S32 sCurTexPickSize ; static S32 getTextureCounterIndex(U32 val) ; - static void incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; - static void decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; - static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ; + static void incTextureCounter(U32 val) ; + static void decTextureCounter(U32 val) ; + static void setCurTexSizebar(S32 index) ; static void resetCurTexSizebar(); - - void incTextureCounter() ; - void decTextureCounter() ; //---------------------------------------- +#endif - //for debug use: show texture category distribution - //---------------------------------------- - - static std::vector<S32> sTextureMemByCategory; - static std::vector<S32> sTextureMemByCategoryBound ; - static std::vector<S32> sTextureCurMemByCategoryBound ; - //---------------------------------------- -//**************************************************************************************************** -//End of definitions for texture auditing use only -//**************************************************************************************************** - +#if DEBUG_MISS + BOOL mMissed; // Missed on last bind? + BOOL getMissed() const { return mMissed; }; +#else + BOOL getMissed() const { return FALSE; }; +#endif }; -extern BOOL gAuditTexture; #endif // LL_LLIMAGEGL_H diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp index b1fe15357..07ba9f14c 100644 --- a/linden/indra/llrender/llrender.cpp +++ b/linden/indra/llrender/llrender.cpp @@ -47,7 +47,7 @@ F64 gGLLastModelView[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; -static const U32 LL_NUM_TEXTURE_LAYERS = 8; +static const U32 LL_NUM_TEXTURE_LAYERS = 16; // KL was 8 ( keep a track on this ) 16 in render-pipeline static GLenum sGLTextureType[] = { @@ -192,24 +192,25 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) if (!texture->getTexName()) //if texture does not exist { - if (texture->isDeleted()) - { - // This will re-generate the texture immediately. - texture->forceImmediateUpdate() ; - } + //if deleted, will re-generate it immediately + texture->forceImmediateUpdate() ; - texture->forceUpdateBindStats() ; return texture->bindDefaultImage(mIndex); } - if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0) +#if !LL_RELEASE_FOR_DOWNLOAD + if(for_rendering) { - if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize) + int w = texture->getWidth(texture->getDiscardLevel()) ; + int h = texture->getHeight(texture->getDiscardLevel()) ; + + if(w * h == LLImageGL::sCurTexPickSize) { texture->updateBindStats(); return bind(LLImageGL::sDefaultTexturep.get()); } } +#endif if ((mCurrTexture != texture->getTexName()) || forceBind) { @@ -227,7 +228,6 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) setTextureFilteringOption(texture->mFilterOption); } } - return true; } @@ -280,6 +280,11 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) if (bindDepth) { + if (renderTarget->hasStencil()) + { + llwarns << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << llendl; + } + bindManual(renderTarget->getUsage(), renderTarget->getDepth()); } else @@ -293,15 +298,18 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { - if (mIndex < 0 || mCurrTexture == texture) return false; - - gGL.flush(); + if (mIndex < 0) return false; - activate(); - enable(type); - mCurrTexture = texture; - glBindTexture(sGLTextureType[type], texture); - mHasMipMaps = hasMips; + if(mCurrTexture != texture) + { + gGL.flush(); + + activate(); + enable(type); + mCurrTexture = texture; + glBindTexture(sGLTextureType[type], texture); + mHasMipMaps = hasMips; + } return true; } @@ -414,7 +422,7 @@ void LLTexUnit::setTextureBlendType(eTextureBlendType type) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); break; default: - llerrs << "Unknown Texture Blend Type: " << type << llendl; + llwarns << "Unknown Texture Blend Type: " << type << llendl; break; } setColorScale(scale_amount); @@ -809,7 +817,7 @@ void LLRender::setSceneBlendType(eBlendType type) glBlendFunc(GL_ONE, GL_ZERO); break; default: - llerrs << "Unknown Scene Blend Type: " << type << llendl; + llwarns << "Unknown Scene Blend Type: " << type << llendl; break; } } @@ -883,7 +891,7 @@ void LLRender::begin(const GLuint& mode) } else if (mCount != 0) { - llerrs << "gGL.begin() called redundantly." << llendl; + llwarns << "gGL.begin() called redundantly." << llendl; } mMode = mode; @@ -914,22 +922,22 @@ void LLRender::flush() #if 0 if (!glIsEnabled(GL_VERTEX_ARRAY)) { - llerrs << "foo 1" << llendl; + llwarns << "foo 1" << llendl; } if (!glIsEnabled(GL_COLOR_ARRAY)) { - llerrs << "foo 2" << llendl; + llwarns << "foo 2" << llendl; } if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY)) { - llerrs << "foo 3" << llendl; + llwarns << "foo 3" << llendl; } if (glIsEnabled(GL_NORMAL_ARRAY)) { - llerrs << "foo 7" << llendl; + llwarns << "foo 7" << llendl; } GLvoid* pointer; @@ -937,19 +945,19 @@ void LLRender::flush() glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].v)) { - llerrs << "foo 4" << llendl; + llwarns << "foo 4" << llendl; } glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].c)) { - llerrs << "foo 5" << llendl; + llwarns << "foo 5" << llendl; } glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].uv)) { - llerrs << "foo 6" << llendl; + llwarns << "foo 6" << llendl; } #endif diff --git a/linden/indra/llrender/llrendertarget.cpp b/linden/indra/llrender/llrendertarget.cpp index 4cf8451db..151b761c7 100644 --- a/linden/indra/llrender/llrendertarget.cpp +++ b/linden/indra/llrender/llrendertarget.cpp @@ -47,10 +47,10 @@ void check_framebuffer_status() case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; break; default: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } } } @@ -139,9 +139,9 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt) U32 offset = mTex.size(); if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) + offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)) { - llerrs << "Too many color attachments!" << llendl; + llwarns << "Too many color attachments!" << llendl; // KL } U32 tex; @@ -203,7 +203,7 @@ void LLRenderTarget::allocateDepth() gGL.getTexUnit(0)->bindManual(mUsage, mDepth); U32 internal_type = LLTexUnit::getInternalType(mUsage); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - LLImageGL::setManualImage(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL); + LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); } } @@ -211,7 +211,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) { if (!mFBO || !target.mFBO) { - llerrs << "Cannot share depth buffer between non FBO render targets." << llendl; + llwarns << "Cannot share depth buffer between non FBO render targets." << llendl; } if (mDepth) @@ -349,16 +349,16 @@ U32 LLRenderTarget::getTexture(U32 attachment) const { if (attachment > mTex.size()-1) { - llerrs << "Invalid attachment index." << llendl; + llwarns << "Invalid attachment index [getTexture]." << llendl; // lets not crash KL its a pain in the ass! } return mTex[attachment]; } void LLRenderTarget::bindTexture(U32 index, S32 channel) { - if (index > mTex.size()-1) + if (index > 6)//mTex.size()-1) // KL yeah i know its a bit arbitary but make the number big enough as some unused render defer elements cause this to go wild { - llerrs << "Invalid attachment index." << llendl; + llwarns << "Invalid attachment index [bindtexture]." << llendl; } gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]); } @@ -440,7 +440,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, #if !LL_DARWIN if (!source.mFBO || !mFBO) { - llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; + llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } if (mSampleBuffer) @@ -449,12 +449,27 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, } else { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); - - glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) + { + source.bindTarget(); + gGL.getTexUnit(0)->bind(this, true); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); + source.flush(); + } + else + { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); + stop_glerror(); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); + stop_glerror(); + check_framebuffer_status(); + stop_glerror(); + glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + stop_glerror(); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + stop_glerror(); + } } #endif } @@ -553,14 +568,14 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth if (!gGLManager.mHasFramebufferMultisample) { - llerrs << "Attempting to allocate unsupported render target type!" << llendl; + llwarns << "Attempting to allocate unsupported render target type!" << llendl; } mSamples = samples; if (mSamples <= 1) { - llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; + llwarns << "Cannot create a multisample buffer with less than 2 samples." << llendl; } stop_glerror(); @@ -608,9 +623,9 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) U32 offset = mTex.size(); if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) + offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)) { - llerrs << "Too many color attachments!" << llendl; + llwarns << "Too many color attachments!" << llendl; } U32 tex; @@ -631,10 +646,10 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; break; default: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); diff --git a/linden/indra/llrender/llrendertarget.h b/linden/indra/llrender/llrendertarget.h index d5d809b79..69af1ea85 100644 --- a/linden/indra/llrender/llrendertarget.h +++ b/linden/indra/llrender/llrendertarget.h @@ -121,6 +121,7 @@ class LLRenderTarget U32 getTexture(U32 attachment = 0) const; U32 getDepth(void) const { return mDepth; } + BOOL hasStencil() const { return mStencil; } void bindTexture(U32 index, S32 channel); diff --git a/linden/indra/llrender/lltextureatlas.cpp b/linden/indra/llrender/lltextureatlas.cpp new file mode 100644 index 000000000..c0f541982 --- /dev/null +++ b/linden/indra/llrender/lltextureatlas.cpp @@ -0,0 +1,411 @@ +/** + * @file lltextureatlas.cpp + * @brief LLTextureAtlas class implementation. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "linden_common.h" +#include "llerror.h" +#include "llimage.h" +#include "llmath.h" +#include "llgl.h" +#include "llrender.h" +#include "lltextureatlas.h" + +//------------------- +S16 LLTextureAtlas::sMaxSubTextureSize = 64 ; +S16 LLTextureAtlas::sSlotSize = 32 ; + +#ifndef DEBUG_ATLAS +#define DEBUG_ATLAS 0 +#endif + +#ifndef DEBUG_USAGE_BITS +#define DEBUG_USAGE_BITS 0 +#endif +//************************************************************************************************************** +LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) : LLImageGL(), + mAtlasDim(atlas_dim) +{ + setComponents(ncomponents) ; + + mCanAddToAtlas = FALSE ;//do not add one atlas to another. + mNumSlotsReserved = 0 ; + mMaxSlotsInAtlas = mAtlasDim * mAtlasDim ; + + generateEmptyUsageBits() ; + + //generate an empty texture + S32 dim = mAtlasDim * sSlotSize ; //number of pixels per dimension + LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim, dim, getComponents()); + createGLTexture(0, image_raw, 0); + image_raw = NULL; + dontDiscard(); +} + +LLTextureAtlas::~LLTextureAtlas() +{ + if(mSpatialGroupList.size() > 0) + { + llwarns << "Not clean up the spatial groups!" << llendl ; + } + releaseUsageBits() ; +} + +void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) +{ +#if !DEBUG_ATLAS + xoffset = (F32)col / mAtlasDim ; + yoffset = (F32)row / mAtlasDim ; +#endif +} + +void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) +{ +#if !DEBUG_ATLAS + xscale = (F32)w / (mAtlasDim * sSlotSize) ; + yscale = (F32)h / (mAtlasDim * sSlotSize) ; +#endif +} + +//insert a texture piece into the atlas +LLGLuint LLTextureAtlas::insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) +{ + S32 w = raw_image->getWidth() ; + S32 h = raw_image->getHeight() ; + if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize) + { + //size overflow + return 0 ; + } + + BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName()); + if (!res) llwarns << "bindTexture failed" << llendl; + stop_glerror(); + + GLint xoffset = sSlotSize * slot_col ; + GLint yoffset = sSlotSize * slot_row ; + + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE); + glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, + w, h, mFormatPrimary, mFormatType, raw_image->getData()); + + return getTexName(); +} + +//release a sub-texture slot from the atlas +void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width) +{ + unmarkUsageBits(slot_width, slot_col, slot_row) ; + mNumSlotsReserved -= slot_width * slot_width ; +} + +BOOL LLTextureAtlas::isEmpty() const +{ + return !mNumSlotsReserved ; +} + +BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const +{ + return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ; +} +F32 LLTextureAtlas::getFullness() const +{ + return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ; +} + +void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp) +{ + if(groupp && !hasSpatialGroup(groupp)) + { + mSpatialGroupList.push_back(groupp); + } +} + +void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp) +{ + if(groupp) + { + mSpatialGroupList.remove(groupp); + } +} + +void LLTextureAtlas::clearSpatialGroup() +{ + mSpatialGroupList.clear(); +} +void LLTextureAtlas::removeLastSpatialGroup() +{ + mSpatialGroupList.pop_back() ; +} + +LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup() +{ + if(mSpatialGroupList.size() > 0) + { + return mSpatialGroupList.back() ; + } + return NULL ; +} + +BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp) +{ + for(std::list<LLSpatialGroup*>::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter) + { + if(*iter == groupp) + { + return TRUE ; + } + } + return FALSE ; +} + +//-------------------------------------------------------------------------------------- +//private +void LLTextureAtlas::generateEmptyUsageBits() +{ + S32 col_len = (mAtlasDim + 7) >> 3 ; + mUsageBits = new U8*[mAtlasDim] ; + *mUsageBits = new U8[mAtlasDim * col_len] ; + + mUsageBits[0] = *mUsageBits ; + for(S32 i = 1 ; i < mAtlasDim ; i++) + { + mUsageBits[i] = mUsageBits[i-1] + col_len ; + + for(S32 j = 0 ; j < col_len ; j++) + { + //init by 0 for all bits. + mUsageBits[i][j] = 0 ; + } + } + + //do not forget mUsageBits[0]! + for(S32 j = 0 ; j < col_len ; j++) + { + //init by 0 for all bits. + mUsageBits[0][j] = 0 ; + } + + mTestBits = NULL ; +#if DEBUG_USAGE_BITS + //------------ + //test + mTestBits = new U8*[mAtlasDim] ; + *mTestBits = new U8[mAtlasDim * mAtlasDim] ; + mTestBits[0] = *mTestBits ; + for(S32 i = 1 ; i < mAtlasDim ; i++) + { + mTestBits[i] = mTestBits[i-1] + mAtlasDim ; + + for(S32 j = 0 ; j < mAtlasDim ; j++) + { + //init by 0 for all bits. + mTestBits[i][j] = 0 ; + } + } + + for(S32 j = 0 ; j < mAtlasDim ; j++) + { + //init by 0 for all bits. + mTestBits[0][j] = 0 ; + } +#endif +} + +void LLTextureAtlas::releaseUsageBits() +{ + if(mUsageBits) + { + delete[] *mUsageBits ; + delete[] mUsageBits ; + } + mUsageBits = NULL ; + + //test + if( mTestBits) + { + delete[] *mTestBits; + delete[] mTestBits; + } + mTestBits = NULL ; +} + +void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) +{ + S16 x = col >> 3 ; + + for(S8 i = 0 ; i < bits_len ; i++) + { + mUsageBits[row + i][x] |= mask ; + } + +#if DEBUG_USAGE_BITS + //test + for(S8 i = row ; i < row + bits_len ; i++) + { + for(S8 j = col ; j < col + bits_len ; j++) + { + mTestBits[i][j] = 1 ; + } + } +#endif +} + +void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row) +{ + S16 x = col >> 3 ; + U8 mask = 1 ; + for(S8 i = 1 ; i < bits_len ; i++) + { + mask |= (1 << i) ; + } + mask <<= (col & 7) ; + mask = ~mask ; + + for(S8 i = 0 ; i < bits_len ; i++) + { + mUsageBits[row + i][x] &= mask ; + } + +#if DEBUG_USAGE_BITS + //test + for(S8 i = row ; i < row + bits_len ; i++) + { + for(S8 j = col ; j < col + bits_len ; j++) + { + mTestBits[i][j] = 0 ; + } + } +#endif +} + +//return true if any of bits in the range marked. +BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) +{ + BOOL ret = FALSE ; + S16 x = col >> 3 ; + + for(S8 i = 0 ; i < bits_len ; i++) + { + if(mUsageBits[row + i][x] & mask) + { + ret = TRUE ; + break ; + //return TRUE ; + } + } + +#if DEBUG_USAGE_BITS + //test + BOOL ret2 = FALSE ; + for(S8 i = row ; i < row + bits_len ; i++) + { + for(S8 j = col ; j < col + bits_len ; j++) + { + if(mTestBits[i][j]) + { + ret2 = TRUE ; + } + } + } + + if(ret != ret2) + { + llwarns << "bits map corrupted." << llendl ; + } +#endif + return ret ;//FALSE ; +} + +//---------------------------------------------------------------------- +// +//index order: Z order, i.e.: +// |-----|-----|-----|-----| +// | 10 | 11 | 14 | 15 | +// |-----|-----|-----|-----| +// | 8 | 9 | 12 | 13 | +// |-----|-----|-----|-----| +// | 2 | 3 | 6 | 7 | +// |-----|-----|-----|-----| +// | 0 | 1 | 4 | 5 | +// |-----|-----|-----|-----| +void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row) +{ + col = 0 ; + row = 0 ; + + S16 index_copy = index ; + for(S16 i = 0 ; index_copy && i < 16 ; i += 2) + { + col |= ((index & (1 << i)) >> i) << (i >> 1) ; + row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ; + index_copy >>= 2 ; + } +} +void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index) +{ + index = 0 ; + S16 col_copy = col ; + S16 row_copy = row ; + for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++) + { + index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ; + col_copy >>= 1 ; + row_copy >>= 1 ; + } +} +//---------------------------------------------------------------------- +//return TRUE if succeeds. +BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row) +{ + S16 index_step = bits_len * bits_len ; + + U8 mask = 1 ; + for(S8 i = 1 ; i < bits_len ; i++) + { + mask |= (1 << i) ; + } + + U8 cur_mask ; + for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step) + { + getPositionFromIndex(index, col, row) ; + + cur_mask = mask << (col & 7) ; + if(!areUsageBitsMarked(bits_len, cur_mask, col, row)) + { + markUsageBits(bits_len, cur_mask, col, row) ; + mNumSlotsReserved += bits_len * bits_len ; + + return TRUE ; + } + } + + return FALSE ; +} diff --git a/linden/indra/llrender/lltextureatlas.h b/linden/indra/llrender/lltextureatlas.h new file mode 100644 index 000000000..4922175d4 --- /dev/null +++ b/linden/indra/llrender/lltextureatlas.h @@ -0,0 +1,92 @@ +/** + * @file lltextureatlas.h + * @brief LLTextureAtlas base class. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#ifndef LL_TEXTUREATLAS_H +#define LL_TEXTUREATLAS_H + +#include "llimagegl.h" +class LLSpatialGroup ; + +class LLTextureAtlas : public LLImageGL +{ +public: + LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ; + ~LLTextureAtlas() ; + + LLGLuint insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ; + void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width); + + BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ; + void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ; + void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ; + + BOOL isEmpty() const ; + BOOL isFull(S8 to_be_reserved = 1) const ; + F32 getFullness() const ; + + void addSpatialGroup(LLSpatialGroup* groupp) ; + void removeSpatialGroup(LLSpatialGroup* groupp) ; + LLSpatialGroup* getLastSpatialGroup() ; + void removeLastSpatialGroup() ; + BOOL hasSpatialGroup(LLSpatialGroup* groupp) ; + void clearSpatialGroup() ; + std::list<LLSpatialGroup*>* getSpatialGroupList() {return &mSpatialGroupList;} +private: + void generateEmptyUsageBits() ; + void releaseUsageBits() ; + + void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ; + void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ; + + void getPositionFromIndex(S16 index, S16& col, S16& row) ; + void getIndexFromPosition(S16 col, S16 row, S16& index) ; + BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ; + +private: + S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas. + S16 mNumSlotsReserved ; + S16 mMaxSlotsInAtlas ; + U8 **mUsageBits ; + std::list<LLSpatialGroup*> mSpatialGroupList ; + +public: + //debug use only + U8 **mTestBits ; + +public: + static S16 sMaxSubTextureSize ; + static S16 sSlotSize ; +}; + +#endif + diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp index 461edbeec..31c2d75d8 100644 --- a/linden/indra/llrender/llvertexbuffer.cpp +++ b/linden/indra/llrender/llvertexbuffer.cpp @@ -96,7 +96,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) { /*if (LLGLImmediate::sStarted) { - llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; + llwarns << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; }*/ if (sLastMask != data_mask) @@ -129,7 +129,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) { //needs to be enabled, make sure it was (DEBUG TEMPORARY) if (i > 0 && !glIsEnabled(array[i])) { - llerrs << "Bad client state! " << array[i] << " disabled." << llendl; + llwarns << "Bad client state! " << array[i] << " disabled." << llendl; } } } @@ -141,7 +141,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } else if (gDebugGL && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) - llerrs << "Bad client state! " << array[i] << " enabled." << llendl; + llwarns << "Bad client state! " << array[i] << " enabled." << llendl; } } } @@ -197,28 +197,28 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi if (start >= (U32) mRequestedNumVerts || end >= (U32) mRequestedNumVerts) { - llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; + llwarns << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; } if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { - llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } if (mGLIndices != sGLRenderIndices) { - llerrs << "Wrong index buffer bound." << llendl; + llwarns << "Wrong index buffer bound." << llendl; } if (mGLBuffer != sGLRenderBuffer) { - llerrs << "Wrong vertex buffer bound." << llendl; + llwarns << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llerrs << "Invalid draw mode: " << mode << llendl; + llwarns << "Invalid draw mode: " << mode << llendl; return; } @@ -233,22 +233,22 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { - llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } if (mGLIndices != sGLRenderIndices) { - llerrs << "Wrong index buffer bound." << llendl; + llwarns << "Wrong index buffer bound." << llendl; } if (mGLBuffer != sGLRenderBuffer) { - llerrs << "Wrong vertex buffer bound." << llendl; + llwarns << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llerrs << "Invalid draw mode: " << mode << llendl; + llwarns << "Invalid draw mode: " << mode << llendl; return; } @@ -263,17 +263,17 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) { - llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; + llwarns << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; } if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) { - llerrs << "Wrong vertex buffer bound." << llendl; + llwarns << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llerrs << "Invalid draw mode: " << mode << llendl; + llwarns << "Invalid draw mode: " << mode << llendl; return; } @@ -530,7 +530,7 @@ void LLVertexBuffer::destroyGLBuffer() { if (mMappedData || mMappedIndexData) { - llerrs << "Vertex buffer destroyed while mapped!" << llendl; + llwarns << "Vertex buffer destroyed while mapped!" << llendl; } releaseBuffer(); } @@ -557,7 +557,7 @@ void LLVertexBuffer::destroyGLIndices() { if (mMappedData || mMappedIndexData) { - llerrs << "Vertex buffer destroyed while mapped." << llendl; + llwarns << "Vertex buffer destroyed while mapped." << llendl; } releaseIndices(); } @@ -634,7 +634,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) if (mMappedData) { - llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; + llwarns << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; } if (create && (nverts || nindices)) { @@ -782,11 +782,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access) LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mFinal) { - llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; + llwarns << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; } if (!useVBOs() && !mMappedData && !mMappedIndexData) { - llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; + llwarns << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; } if (!mLocked && useVBOs()) @@ -813,11 +813,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access) glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); if (buff != mGLBuffer) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; } - llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; + llwarns << "glMapBuffer returned NULL (no vertex data)" << llendl; } if (!mMappedIndexData) @@ -826,10 +826,10 @@ U8* LLVertexBuffer::mapBuffer(S32 access) glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); if (buff != mGLIndices) { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llwarns << "Invalid GL index buffer bound: " << buff << llendl; } - llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + llwarns << "glMapBuffer returned NULL (no index data)" << llendl; } sMappedCount++; @@ -908,7 +908,7 @@ template <class T,S32 type> struct VertexBufferStrider } else { - llerrs << "VertexBufferStrider could not find valid vertex data." << llendl; + llwarns << "VertexBufferStrider could not find valid vertex data." << llendl; } return FALSE; } @@ -965,7 +965,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride) LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mNumVerts) { - llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; + llwarns << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; } // This code assumes that setStride() will only be called once per VBO per type. S32 delta = new_stride - sTypeOffsets[type]; @@ -1020,15 +1020,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLBuffer) + if ((GLuint)buff != mGLBuffer) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; } glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLIndices) + if ((GLuint)buff != mGLIndices) { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llwarns << "Invalid GL index buffer bound: " << buff << llendl; } } @@ -1038,15 +1038,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLBuffer) + if ((GLuint)buff != mGLBuffer) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; } glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLIndices) + if ((GLuint)buff != mGLIndices) { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llwarns << "Invalid GL index buffer bound: " << buff << llendl; } } @@ -1068,7 +1068,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (data_mask != 0) { - llerrs << "Buffer set for rendering before being filled after resize." << llendl; + llwarns << "Buffer set for rendering before being filled after resize." << llendl; } } @@ -1129,7 +1129,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if ((data_mask & mTypeMask) != data_mask) { - llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; + llwarns << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } if (data_mask & MAP_NORMAL) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index e0c6c61ce..6fd259aa8 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -329,6 +329,7 @@ set(viewer_SOURCE_FILES llpolymesh.cpp llpolymorph.cpp llprefsadvanced.cpp + llpostprocess.cpp llprefschat.cpp llprefsim.cpp llprefsvoice.cpp @@ -359,6 +360,7 @@ set(viewer_SOURCE_FILES llsurface.cpp llsurfacepatch.cpp lltexlayer.cpp + lltextureatlasmanager.cpp lltexturecache.cpp lltexturectrl.cpp lltexturefetch.cpp @@ -777,6 +779,7 @@ set(viewer_HEADER_FILES llpolymesh.h llpolymorph.h llprefsadvanced.h + llpostprocess.h llprefschat.h llprefsim.h llprefsvoice.h @@ -809,6 +812,7 @@ set(viewer_HEADER_FILES llsurfacepatch.h lltable.h lltexlayer.h + lltextureatlasmanager.h lltexturecache.h lltexturectrl.h lltexturefetch.h diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index f70c0fc69..c7f8d367e 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -5097,6 +5097,21 @@ <key>Value</key> <integer>1</integer> </map> + +<!--KL port --> + <key>EnableTextureAtlas</key> + <map> + <key>Comment</key> + <string>Whether to use texture atlas or not</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> +<!--/KL port --> + <key>EnableVoiceChat</key> <map> <key>Comment</key> @@ -8927,12 +8942,75 @@ <key>Type</key> <string>Vector3</string> <key>Value</key> + <array> + <real>1.0</real> + <real>12.0</real> + <real>32.0</real> + </array> + </map> + <key>RenderShadowSplitExponent</key> + <map> + <key>Comment</key> + <string>Near clip plane split distances for shadow map frusta (x=perspective, y=ortho, z=transition rate).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>3.0</real> + <real>3.0</real> + <real>2.0</real> + </array> + </map> + <key>RenderShadowOrthoClipPlanes</key> + <map> + <key>Comment</key> + <string>Near clip plane split distances for orthographic shadow map frusta.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> <array> <real>4.0</real> <real>8.0</real> <real>24.0</real> </array> </map> + <key>RenderShadowProjOffset</key> + <map> + <key>Comment</key> + <string>Amount to scale distance to virtual origin of shadow perspective projection.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>2.0</real> + </map> + <key>RenderShadowSlopeThreshold</key> + <map> + <key>Comment</key> + <string>Cutoff slope value for points to affect perspective shadow generation</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.0</real> + </map> + <key>RenderShadowProjExponent</key> + <map> + <key>Comment</key> + <string>Exponent applied to transition between ortho and perspective shadow projections based on viewing angle and light vector.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.5</real> + </map> <key>RenderSSAOScale</key> <map> <key>Comment</key> @@ -9092,6 +9170,184 @@ <key>Value</key> <integer>0</integer> </map> + + <key>RenderGILightRadius</key> + <map> + <key>Comment</key> + <string>Distance of ambiant bounce lighting from sun.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>8</real> + </map> + + <key>RenderGISamples</key> + <map> + <key>Comment</key> + <string>Number of samples to take for GI.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>64</real> + </map> + + <key>RenderGIRange</key> + <map> + <key>Comment</key> + <string>Distance to cut off GI effect.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>128</real> + </map> + + + <key>RenderGIDirectionWeight</key> + <map> + <key>Comment</key> + <string>Weight of reflected light vector in GI angular attenuation.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.5</real> + </map> + + <key>RenderGILightOffset</key> + <map> + <key>Comment</key> + <string>Amount to offset light from point of impact in gi map (scaled by light radius).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.0</real> + </map> + + <key>RenderGIColorCurve</key> + <map> + <key>Comment</key> + <string>Global illumination color correction curve parameters.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.0</real> + <real>0.2</real> + <real>0.02</real> + </array> + </map> + + <key>RenderLuminanceColorCurve</key> + <map> + <key>Comment</key> + <string>Luminance color correction curve parameters.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.30</real> + <real>0.0</real> + <real>0.04</real> + </array> + </map> + + <key>RenderGILuminanceColorCurve</key> + <map> + <key>Comment</key> + <string>Luminance color correction curve parameters.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.4</real> + <real>0.0</real> + <real>0.05</real> + </array> + </map> + + <key>RenderSunLuminanceColorCurve</key> + <map> + <key>Comment</key> + <string>Luminance color correction curve parameters.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.6</real> + <real>0.0</real> + <real>-0.3</real> + </array> + </map> + + <key>RenderLuminanceDetail</key> + <map> + <key>Comment</key> + <string>Mipmap level to use for luminance</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>8.0</real> + </map> + + <key>RenderLuminanceFade</key> + <map> + <key>Comment</key> + <string>Scaler for speed of luminance adjustment</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.05</real> + </map> + + <key>RenderGISpecularCurve</key> + <map> + <key>Comment</key> + <string>Global illumination specular color correction curve parameters.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.1</real> + <real>0.0</real> + <real>0.9</real> + </array> + </map> + + <key>RenderGIIntensity</key> + <map> + <key>Comment</key> + <string>Distance of ambiant bounce lighting from sun.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.2f</real> + </map> + <key>RenderDeferredAlphaSoften</key> <map> <key>Comment</key> @@ -9114,89 +9370,472 @@ <key>Value</key> <real>4</real> </map> - <key>RenderDeferred</key> + <key>RenderDeferredSpotShadowBias</key> <map> <key>Comment</key> - <string>Use deferred rendering pipeline.</string> + <string>Bias value for spot shadows (prevent shadow acne).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>Boolean</string> + <string>F32</string> <key>Value</key> - <integer>0</integer> + <real>-64.0</real> </map> - <key>RenderDeferredSunShadow</key> + <key>RenderDeferredSpotShadowOffset</key> <map> <key>Comment</key> - <string>Generate shadows from the sun.</string> + <string>Offset value for spot shadows (prevent shadow acne).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>Boolean</string> + <string>F32</string> <key>Value</key> + <real>0.8</real> + </map> + + <key>RenderShadowBias</key> + <map> + <key>Comment</key> + <string>Bias value for shadows (prevent shadow acne).</string> + <key>Persist</key> <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.001</real> </map> - <key>RenderDeferredSunWash</key> + <key>RenderShadowOffset</key> <map> <key>Comment</key> - <string>Amount local lights are washed out by sun.</string> + <string>Offset value for shadows (prevent shadow acne).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.5</real> + <real>0.6</real> </map> - <key>RenderShadowNoise</key> + + <key>RenderShadowResolutionScale</key> <map> <key>Comment</key> - <string>Magnitude of noise on shadow samples.</string> + <string>Scale of shadow map resolution vs. screen resolution</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>-0.0001</real> + <real>1.0</real> </map> - <key>RenderShadowBlurSize</key> + + + + <key>RenderDeferredTreeShadowBias</key> <map> <key>Comment</key> - <string>Scale of shadow softening kernel.</string> + <string>Bias value for tree shadows (prevent shadow acne).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.7</real> + <real>1.0</real> </map> - <key>RenderShadowBlurSamples</key> + <key>RenderDeferredTreeShadowOffset</key> <map> <key>Comment</key> - <string>Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1.</string> + <string>Offset value for tree shadows (prevent shadow acne).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>U32</string> + <string>F32</string> <key>Value</key> - <real>5</real> + <real>1.0</real> </map> - <key>RenderDynamicLOD</key> - <map> - <key>Comment</key> - <string>Dynamically adjust level of detail.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>RenderFSAASamples</key> - <map> - <key>Comment</key> - <string>Number of samples to use for FSAA (0 = no AA).</string> - <key>Persist</key> - <integer>1</integer> + + <key>RenderHighlightFadeTime</key> + <map> + <key>Comment</key> + <string>Transition time for mouseover highlights.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.2</real> + </map> + + <key>RenderHighlightBrightness</key> + <map> + <key>Comment</key> + <string>Brightness of mouseover highlights.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>4.0</real> + </map> + + <key>RenderHighlightThickness</key> + <map> + <key>Comment</key> + <string>Thickness of mouseover highlights.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.6</real> + </map> + + <key>RenderHighlightColor</key> + <map> + <key>Comment</key> + <string>Brightness of mouseover highlights.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.4</real> + <real>0.98</real> + <real>0.93</real> + <real>1.0</real> + </array> + </map> + + <key>RenderSpecularResX</key> + <map> + <key>Comment</key> + <string>Spec map resolution.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>128</real> + </map> + + <key>RenderSpecularResY</key> + <map> + <key>Comment</key> + <string>Spec map resolution.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>128</real> + </map> + + <key>RenderSpecularExponent</key> + <map> + <key>Comment</key> + <string>Specular exponent for generating spec map</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1</real> + </map> + + <key>RenderDeferred</key> + <map> + <key>Comment</key> + <string>Use deferred rendering pipeline.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>RenderDeferredShadow</key> + <map> + <key>Comment</key> + <string>Enable shadows in deferred renderer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + + <key>RenderDeferredGI</key> + <map> + <key>Comment</key> + <string>Enable GI in deferred renderer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>RenderDeferredSunShadow</key> + <map> + <key>Comment</key> + <string>Generate shadows from the sun.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + + <key>RenderDeferredSun</key> + <map> + <key>Comment</key> + <string>Execute sunlight shader in deferred renderer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + + <key>RenderDeferredAtmospheric</key> + <map> + <key>Comment</key> + <string>Execute atmospheric shader in deferred renderer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + + <key>RenderDeferredBlurLight</key> + <map> + <key>Comment</key> + <string>Execute shadow softening shader in deferred renderer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + + <key>RenderDeferredLocalLights</key> + <map> + <key>Comment</key> + <string>Execute local lighting shader in deferred renderer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + + <key>RenderDeferredFullscreenLights</key> + <map> + <key>Comment</key> + <string>Execute local lighting shader in deferred renderer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + + <key>RenderDeferredSunWash</key> + <map> + <key>Comment</key> + <string>Amount local lights are washed out by sun.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.5</real> + </map> + <key>RenderShadowNoise</key> + <map> + <key>Comment</key> + <string>Magnitude of noise on shadow samples.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>-0.0001</real> + </map> + <key>RenderShadowErrorCutoff</key> + <map> + <key>Comment</key> + <string>Cutoff error value to use ortho instead of perspective projection.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>5.0</real> + </map> + <key>RenderShadowFOVCutoff</key> + <map> + <key>Comment</key> + <string>Cutoff FOV to use ortho instead of perspective projection.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.1</real> + </map> + + <key>RenderShadowGaussian</key> + <map> + <key>Comment</key> + <string>Gaussian coefficients for the two shadow/SSAO blurring passes (z component unused).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>3.0</real> + <real>2.0</real> + <real>0.0</real> + </array> + </map> + + <key>RenderShadowBlurSize</key> + <map> + <key>Comment</key> + <string>Scale of shadow softening kernel.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.8</real> + </map> + <key>RenderShadowBlurSamples</key> + <map> + <key>Comment</key> + <string>Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>4</real> + </map> + <key>RenderShadowBlurDistFactor</key> + <map> + <key>Comment</key> + <string>Distance scaler for shadow blur.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.1</real> + </map> + + <key>RenderGIBlurColorCurve</key> + <map> + <key>Comment</key> + <string>Color curve for GI softening kernel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.6</real> + <real>0.1</real> + </array> + </map> + + <key>RenderGIGaussian</key> + <map> + <key>Comment</key> + <string>Gaussian coefficient for the two GI blurring passes.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>64</real> + </map> + + <key>RenderGIBlurPasses</key> + <map> + <key>Comment</key> + <string>Scale of GI softening kernel.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>2</real> + </map> + + <key>RenderGIBlurSize</key> + <map> + <key>Comment</key> + <string>Scale of GI softening kernel.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>3.0</real> + </map> + <key>RenderGIBlurSamples</key> + <map> + <key>Comment</key> + <string>Number of samples to take for each pass of GI blur (value range 1-16). Actual number of samples is value * 2 - 1.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>6</real> + </map> + <key>RenderGIBlurDistFactor</key> + <map> + <key>Comment</key> + <string>Distance scaler for GI blur.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.0</real> + </map> + + <key>RenderDynamicLOD</key> + <map> + <key>Comment</key> + <string>Dynamically adjust level of detail.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>RenderFSAASamples</key> + <map> + <key>Comment</key> + <string>Number of samples to use for FSAA (0 = no AA).</string> + <key>Persist</key> + <integer>1</integer> <key>Type</key> <string>U32</string> <key>Value</key> @@ -9430,6 +10069,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderHighlightSelections</key> + <map> + <key>Comment</key> + <string>Show selection outlines on objects</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderHiddenSelections</key> <map> <key>Comment</key> @@ -9738,6 +10388,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderUIBuffer</key> + <map> + <key>Comment</key> + <string>Cache ui render in a screen aligned buffer.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderUnloadedAvatar</key> <map> <key>Comment</key> diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index a91e9fa15..f90d91faa 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -13,9 +13,9 @@ uniform sampler2DShadow shadowMap1; uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform sampler2DRect positionMap; +uniform sampler2DRect depthMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -26,15 +26,31 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; +varying vec3 vary_light; uniform float alpha_soften; +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = texture2DRect(positionMap, frag).xyz; + vec3 samp_pos = getPosition(frag).xyz; float shadow = 1.0; vec4 pos = vec4(vary_position, 1.0); @@ -82,7 +98,7 @@ void main() //gl_FragColor = gl_Color; gl_FragColor = color; - //gl_FragColor = vec4(1,0,1,1); + //gl_FragColor = vec4(1,0,1,1)*shadow; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index b496bd674..48baf77d5 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -20,8 +20,11 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; +varying vec3 vary_light; uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; void main() { @@ -32,8 +35,9 @@ void main() vec4 pos = (gl_ModelViewMatrix * gl_Vertex); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vary_position = pos.xyz; - + // KL this works around ATI not compiling the shader but maintains shadow offset and bias vec3 not vec4 + vary_position = pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias); + calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); @@ -54,6 +58,8 @@ void main() col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); col.rgb = scaleDownLight(col.rgb); + vary_light = gl_LightSource[0].position.xyz; + vary_ambient = col.rgb*gl_Color.rgb; vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl index 6c94f5c5a..ff64a6b0c 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl @@ -12,7 +12,7 @@ uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; vec3 atmosLighting(vec3 light); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 58aa5a9cb..4b9cca258 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -8,13 +8,18 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 diff = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy); + // Viewer 2.0 uses 0.2 but for KL's viewer if i want a complete avatar need this to be 0.0 for now. + if (diff.a < 0.0) + { + discard; + } + + gl_FragData[0] = vec4(diff.rgb, 1.0); gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 27c09db92..00083eb6b 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -10,6 +10,7 @@ uniform sampler2D diffuseMap; void main() { - gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy)); + gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a); + //gl_FragColor = vec4(1,1,1,1); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index 14da6b1ad..8c8489d08 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -28,8 +28,7 @@ void main() norm = normalize(norm); pos = gl_ProjectionMatrix * pos; - //smash geometry against near clip plane - pos.z = max(pos.z, -1.0); + pos.z = max(pos.z, -pos.w+0.01); gl_Position = pos; gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index 12a7ff7f2..471a1f040 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -10,7 +10,6 @@ mat4 getSkinnedTransform(); attribute vec4 weight; varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -30,7 +29,6 @@ void main() norm.z = dot(trans[2].xyz, gl_Normal); norm = normalize(norm); - vary_position = pos; vary_normal = norm; gl_Position = gl_ProjectionMatrix * pos; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 3c6700a87..1713fe99f 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -7,10 +7,11 @@ #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect positionMap; +uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; +uniform float dist_factor; uniform float blur_size; uniform vec2 delta; uniform vec3 kern[32]; @@ -19,30 +20,52 @@ uniform float kern_scale; varying vec2 vary_fragcoord; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; - vec3 pos = texture2DRect(positionMap, vary_fragcoord.xy).xyz; - vec2 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rg; + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + vec3 pos = getPosition(vary_fragcoord.xy).xyz; + vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); + dlt /= max(-pos.z*dist_factor, 1.0); + vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' - vec2 col = defined_weight * ccol; + vec4 col = defined_weight.xyxx * ccol; for (int i = 1; i < kern_length; i++) { vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = texture2DRect(positionMap, tc).xyz; + vec3 samppos = getPosition(tc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane if (d*d <= 0.003) { - col += texture2DRect(lightMap, tc).rg*kern[i].xy; + col += texture2DRect(lightMap, tc)*kern[i].xyxx; defined_weight += kern[i].xy; } } - col /= defined_weight; - gl_FragColor = vec4(col.r, col.g, 0.0, 1.0); + + col /= defined_weight.xyxx; + + gl_FragColor = col; + + //gl_FragColor = ccol; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index a8712bc8c..1c29dae5f 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -11,7 +11,6 @@ uniform sampler2D bumpMap; varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; -varying vec4 vary_position; void main() { @@ -22,8 +21,7 @@ void main() dot(norm,vary_mat1), dot(norm,vary_mat2)); - gl_FragData[0].rgb = gl_Color.rgb*col; - gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); - gl_FragData[2] = vec4(normalize(tnorm), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); + gl_FragData[1] = vec4(col*gl_Color.a, gl_Color.a); + gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index ba180922c..9589912c6 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -8,7 +8,6 @@ varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; -varying vec4 vary_position; void main() { @@ -16,8 +15,6 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vec3 n = normalize(gl_NormalMatrix * gl_Normal); vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz); vec3 t = cross(b, n); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index f2ba2df69..919dd5ddf 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -8,13 +8,11 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; - gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); + gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); // KL viewer 2.0 has 0.0 but this is not working right yet besides i like to see my eyes :) gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 3413a7f9d..44468cdfa 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -6,16 +6,13 @@ */ varying vec3 vary_normal; -varying vec4 vary_position; void main() { //transform vertex - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 2a811c589..e518bddb9 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -8,14 +8,9 @@ #extension GL_ARB_texture_rectangle : enable uniform sampler2D diffuseMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; +uniform sampler2DRect depthMap; uniform sampler2D noiseMap; -uniform sampler2DRect positionMap; -uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -30,12 +25,27 @@ varying vec3 vary_fragcoord; uniform float alpha_soften; +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = texture2DRect(positionMap, frag).xyz; + vec3 samp_pos = getPosition(frag).xyz; float shadow = 1.0; vec4 pos = vary_position; @@ -46,10 +56,10 @@ void main() color.rgb = fullbrightScaleSoftClip(color.rgb); - if (samp_pos.z != 0.0) + if (samp_pos.z != 0.0 && color.a < 1.0) { float dist_factor = alpha_soften; - float a = gl_Color.a; + float a = color.a; a *= a; dist_factor *= 1.0/(1.0-a); color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 6381a1ced..aff51178b 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -12,12 +12,12 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); -varying vec4 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_normal; varying vec3 vary_fragcoord; uniform float near_clip; +varying vec4 vary_position; void main() { diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl new file mode 100644 index 000000000..b351eec6e --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -0,0 +1,165 @@ +/** + * @file giF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2D noiseMap; + +uniform sampler2D diffuseGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; + +uniform sampler2D lightFunc; + +// Inputs +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +uniform mat4 inv_proj; +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_radius; +uniform float gi_intensity; +uniform int gi_samples; +uniform vec2 gi_kern[25]; +uniform vec2 gi_scale; +uniform vec3 gi_quad; +uniform vec3 gi_spec; +uniform float gi_direction_weight; +uniform float gi_light_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 giAmbient(vec3 pos, vec3 norm) +{ + vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); + gi_c.xyz /= gi_c.w; + + vec4 gi_pos = gi_mat*vec4(pos,1.0); + vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; + gi_norm = normalize(gi_norm); + + vec2 tcx = gi_norm.xy; + vec2 tcy = gi_norm.yx; + + vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); + + vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w); + + //vec3 eye_dir = vec3(0,0,-1); + //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; + //eye_dir = normalize(eye_dir); + + //float round_x = gi_scale.x; + //float round_y = gi_scale.y; + + vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5; + debug.xz = vec2(0.0,0.0); + //debug = fract(debug); + + float round_x = 1.0/64.0; + float round_y = 1.0/64.0; + + //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; + //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; + + float fda = 0.0; + vec3 fdiff = vec3(0,0,0); + + vec3 rcol = vec3(0,0,0); + + float fsa = 0.0; + + for (int i = -1; i < 2; i+=2 ) + { + for (int j = -1; j < 2; j+=2) + { + vec2 tc = vec2(i, j)*0.75; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; + //tc += gi_norm.xy*nz.z; + tc += nz.xy*2.0; + tc /= gi_samples; + tc += gi_c.xy; + + vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); + vec3 lpos = getGIPosition(tc.xy).xyz; + + vec3 at = lpos-gi_pos.xyz; + float dist = dot(at,at); + float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); + + if (da > 0.0) + { + //add angular attenuation + vec3 ldir = at; + float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0); + + float ld = -dot(ldir, lnorm); + + if (ang_atten > 0.0 && ld < 0.0) + { + vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz; + da = da*ang_atten; + fda += da; + fdiff += diff*da; + } + } + } + } + + fdiff /= max(gi_spec.y*fda, gi_quad.z); + fdiff = clamp(fdiff, vec3(0), vec3(1)); + + vec3 ret = fda*fdiff; + //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; + + //fda *= nz.z; + + //rcol.rgb *= gi_intensity; + //return rcol.rgb+vary_AmblitColor.rgb*0.25; + //return vec4(debug, 0.0); + //return vec4(fda*fdiff, 0.0); + return clamp(ret,vec3(0.0), vec3(1.0)); + //return debug.xyz; +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; + + gl_FragData[0].xyz = giAmbient(pos, norm); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl new file mode 100644 index 000000000..71dcea962 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl @@ -0,0 +1,22 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl new file mode 100644 index 000000000..e8b53b029 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -0,0 +1,15 @@ +/** + * @file luminanceF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseMap; + +varying vec2 vary_fragcoord; + +void main() +{ + gl_FragColor = texture2DRect(diffuseMap, vary_fragcoord.xy); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl new file mode 100644 index 000000000..db8775f02 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl @@ -0,0 +1,20 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 3689d1284..ce0494c74 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -7,13 +7,15 @@ #extension GL_ARB_texture_rectangle : enable +uniform sampler2DRect depthMap; uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; -uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; uniform sampler2DRect lightMap; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + uniform vec3 env_mat[3]; uniform float sun_wash; @@ -23,24 +25,48 @@ uniform int light_count; uniform vec4 light[16]; uniform vec4 light_col[16]; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; +uniform float far_z; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; - vec3 pos = texture2DRect(positionMap, frag.xy).xyz; - vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz); + vec3 pos = getPosition(frag.xy).xyz; + if (pos.z < far_z) + { + discard; + } + + vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz*2.0-1.0); vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; float noise = texture2D(noiseMap, frag.xy/128.0).b; vec3 out_col = vec3(0,0,0); + vec3 npos = normalize(-pos); for (int i = 0; i < light_count; ++i) { vec3 lv = light[i].xyz-pos; float dist2 = dot(lv,lv); - if (dist2 > light[i].w) + dist2 /= light[i].w; + if (dist2 > 1.0) { continue; } @@ -55,29 +81,41 @@ void main() da = dot(norm, lv); float fa = light_col[i].a+1.0; - float dist_atten = clamp(1.0-(dist2-light[i].w*(1.0-fa))/(light[i].w*fa), 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); dist_atten *= noise; float lit = da * dist_atten; vec3 col = light_col[i].rgb*lit*diff; + //vec3 col = vec3(dist2, light_col[i].a, lit); if (spec.a > 0.0) { - vec3 ref = reflect(normalize(pos), norm); - float sa = dot(ref,lv); - sa = max(sa, 0.0); - sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*light_col[i].rgb*spec.rgb; + //vec3 ref = dot(pos+lv, norm); + + float sa = dot(normalize(lv+npos),norm); + + if (sa > 0) + { + sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*light_col[i].rgb*spec.rgb; + } } out_col += col; } + if (dot(out_col, out_col) <= 0.0) + { + discard; + } + //attenuate point light contribution by SSAO component out_col *= texture2DRect(lightMap, frag.xy).g; gl_FragColor.rgb = out_col; gl_FragColor.a = 0.0; + + //gl_FragColor = vec4(0.1, 0.025, 0.025/4.0, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl new file mode 100644 index 000000000..021e8a277 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -0,0 +1,184 @@ +/** + * @file multiSpotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + float amb_da = proj_ambiance; + + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + + if (stc.z > 0.0) + { + stc.xy /= stc.w; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 52bad1f34..d8ccfd4a8 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -9,33 +9,54 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; -uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; uniform sampler2DRect lightMap; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2DRect depthMap; uniform vec3 env_mat[3]; uniform float sun_wash; varying vec4 vary_light; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; +uniform mat4 inv_proj; +uniform vec4 viewport; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = (pos_screen.xy-viewport.xy)*2.0; + sc /= viewport.zw; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { - vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; - frag *= screen_res; - vec3 pos = texture2DRect(positionMap, frag).xyz; + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; vec3 lv = vary_light.xyz-pos; float dist2 = dot(lv,lv); - if (dist2 > vary_light.w) + dist2 /= vary_light.w; + if (dist2 > 1.0) { discard; } - vec3 norm = texture2DRect(normalMap, frag).xyz; + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; float da = dot(norm, lv); if (da < 0.0) { @@ -46,24 +67,30 @@ void main() lv = normalize(lv); da = dot(norm, lv); - float noise = texture2D(noiseMap, frag/128.0).b; + float noise = texture2D(noiseMap, frag.xy/128.0).b; - vec3 col = texture2DRect(diffuseRect, frag).rgb; + vec3 col = texture2DRect(diffuseRect, frag.xy).rgb; float fa = gl_Color.a+1.0; - float dist_atten = clamp(1.0-(dist2-vary_light.w*(1.0-fa))/(vary_light.w*fa), 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); float lit = da * dist_atten * noise; col = gl_Color.rgb*lit*col; - vec4 spec = texture2DRect(specularRect, frag); + vec4 spec = texture2DRect(specularRect, frag.xy); if (spec.a > 0.0) { - vec3 ref = reflect(normalize(pos), norm); - float sa = dot(ref,lv); - sa = max(sa, 0.0); - sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*gl_Color.rgb*spec.rgb; + float sa = dot(normalize(lv-normalize(pos)),norm); + if (sa > 0.0) + { + sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*gl_Color.rgb*spec.rgb; + } + } + + if (dot(col, col) <= 0.0) + { + discard; } //attenuate point light contribution by SSAO component diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index a4edb8825..e815ca260 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -6,7 +6,7 @@ */ varying vec4 vary_light; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; uniform float near_clip; @@ -14,10 +14,10 @@ uniform float near_clip; void main() { //transform vertex - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); + vary_fragcoord = pos; vec4 tex = gl_MultiTexCoord0; tex.w = 1.0; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl new file mode 100644 index 000000000..71de03663 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -0,0 +1,57 @@ +/** + * @file postDeferredF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; + +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + float luminance = lum.r; + luminance = luminance*lum_quad.y+lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; + gi_col *= diff; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + sun_col *= 1.0/min(luminance, 1.0); + gi_col *= 1.0/luminance; + + vec3 col = sun_col.rgb+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + col.rgb = max(col.rgb-vec3(1.0,1.0,1.0), vec3(0.0, 0.0, 0.0)); + + gl_FragColor.a = 0.0; // max(dot(col.rgb,col.rgb)*lum_quad.x, sun_col.a); + + //gl_FragColor.rgb = vec3(lum_lod); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl new file mode 100644 index 000000000..9819232fd --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl @@ -0,0 +1,17 @@ +/** + * @file postDeferredV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl new file mode 100644 index 000000000..3556c7bb5 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -0,0 +1,107 @@ +/** + * @file postgiF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; +uniform sampler2D diffuseMap; + +uniform sampler2D lastDiffuseGIMap; +uniform sampler2D lastNormalGIMap; +uniform sampler2D lastMinpGIMap; +uniform sampler2D lastMaxpGIMap; + +uniform float gi_blend; + +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_radius; +uniform float gi_intensity; +uniform vec2 gi_kern[16]; +uniform vec2 gi_scale; + + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + + +void main() +{ + vec2 c_tc = gl_TexCoord[0].xy; + + vec3 diff = vec3(0,0,0); + vec3 minp = vec3(1024,1024,1024); + vec3 maxp = vec3(-1024,-1024,-1024); + vec3 norm = vec3(0,0,0); + + float dweight = 0.0; + + vec3 cnorm = normalize(texture2D(normalGIMap, c_tc).rgb*2.0-1.0); + + vec3 cpos = vec3(0,0,0); + float tweight = 0.0; + + for (int i = 0; i < 8; ++i) + { + for (int j = 0; j < 8; ++j) + { + vec2 tc = vec2(i-4+0.5, j-4+0.5); + float weight = 1.0-length(tc)/6.0; + tc *= 1.0/(256.0); + tc += c_tc; + + vec3 n = texture2D(normalGIMap, tc).rgb*2.0-1.0; + tweight += weight; + + diff += weight*texture2D(diffuseGIMap, tc).rgb; + + norm += n*weight; + + dweight += dot(n, cnorm); + + vec3 pos = getGIPosition(tc).xyz; + cpos += pos*weight; + + minp = min(pos, minp); + maxp = max(pos, maxp); + } + } + + dweight = abs(1.0-dweight/64.0); + float mind = min(sqrt(dweight+0.5), 1.0); + + dweight *= dweight; + + cpos /= tweight; + + diff = clamp(diff/tweight, vec3(1.0/2.2), vec3(1,1,1)); + norm = normalize(norm); + maxp = cpos; + minp = vec3(dweight, mind, cpos.z-minp.z); + + //float blend = 1.0; + //diff = mix(texture2D(lastDiffuseGIMap, c_tc).rgb, diff, blend); + //norm = mix(texture2D(lastNormalGIMap, c_tc).rgb, norm, blend); + //maxp = mix(texture2D(lastMaxpGIMap, c_tc).rgb, maxp, blend); + //minp = mix(texture2D(lastMinpGIMap, c_tc).rgb, minp, blend); + + gl_FragData[0].rgb = diff; + gl_FragData[2].xyz = normalize(norm); + gl_FragData[1].xyz = maxp; + gl_FragData[3].xyz = minp; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl new file mode 100644 index 000000000..5a8eb658e --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl @@ -0,0 +1,16 @@ +/** + * @file postgiV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_normal; + +void main() +{ + //transform vertex + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = pos; + gl_TexCoord[0].xy = pos.xy*0.5+0.5; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index b3758c363..b0b31fd4b 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -7,8 +7,11 @@ uniform sampler2D diffuseMap; +varying vec4 post_pos; void main() { gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a); + + gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index aae1beeae..7214d246a 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -5,13 +5,17 @@ * $License$ */ +varying vec4 post_pos; + void main() { //transform vertex vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex; - //smash geometry against the near clip plane (great for ortho projections) - pos.z = max(pos.z, -1.0); - gl_Position = pos; + + post_pos = pos; + + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_FrontColor = gl_Color; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index d5671a6ce..64e263ada 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -272,8 +272,4 @@ void main() gl_FragColor.rgb = col; gl_FragColor.a = 0.0; - //gl_FragColor.rg = scol_ambocc.rg; - //gl_FragColor.rgb = norm.rgb*0.5+0.5; - //gl_FragColor.rgb = vec3(ambocc); - //gl_FragColor.rgb = vec3(scol); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl new file mode 100644 index 000000000..d6534083c --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -0,0 +1,199 @@ +/** + * @file spotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + } + + float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); + float amb_da = proj_ambiance; + if (da > 0.0) + { + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + + if (stc.z > 0.0) + { + stc.xy /= stc.z+proj_near; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + /*if (spec.a > 0.0) + { + //vec3 ref = reflect(normalize(pos), norm); + float sa = dot(normalize(lv-normalize(pos)),norm);; + //sa = max(sa, 0.0); + //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); + sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*lcol*spec.rgb; + }*/ + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index d43fe6ca9..22bdd2c7f 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -7,17 +7,21 @@ #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect positionMap; -uniform sampler2DRect normalMap; uniform sampler2DRect depthMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DRectShadow shadowMap4; +uniform sampler2DRectShadow shadowMap5; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + + // Inputs -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform float ssao_radius; uniform float ssao_max_radius; @@ -27,6 +31,25 @@ uniform float ssao_factor_inv; varying vec2 vary_fragcoord; varying vec4 vary_light; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + //calculate decreases in ambient lighting when crowded out (SSAO) float calcAmbientOcclusion(vec4 pos, vec3 norm) { @@ -54,7 +77,7 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) for (int i = 0; i < 8; i++) { vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = texture2DRect(positionMap, samppos_screen).xyz; + vec3 samppos_world = getPosition(samppos_screen).xyz; vec3 diff = pos_world - samppos_world; float dist2 = dot(diff, diff); @@ -74,14 +97,18 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - return 1.0 - (float(points != 0) * angle_hidden); + return (1.0 - (float(points != 0) * angle_hidden)); } void main() { vec2 pos_screen = vary_fragcoord.xy; - vec4 pos = vec4(texture2DRect(positionMap, pos_screen).xyz, 1.0); - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; + + //try doing an unproject here + + vec4 pos = getPosition(pos_screen); + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL { @@ -90,35 +117,45 @@ void main() }*/ float shadow = 1.0; - float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); + + //vec3 debug = vec3(0,0,0); + if (dp_directional_light == 0.0) { // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup shadow = 0.0; } - else if (pos.z > -shadow_clip.w) + else if (spos.z > -shadow_clip.w) { - if (pos.z < -shadow_clip.z) + vec4 lpos; + + if (spos.z < -shadow_clip.z) { - vec4 lpos = shadow_matrix[3]*pos; - shadow = shadow2DProj(shadowMap3, lpos).x; + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (pos.z < -shadow_clip.y) + else if (spos.z < -shadow_clip.y) { - vec4 lpos = shadow_matrix[2]*pos; - shadow = shadow2DProj(shadowMap2, lpos).x; + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; } - else if (pos.z < -shadow_clip.x) + else if (spos.z < -shadow_clip.x) { - vec4 lpos = shadow_matrix[1]*pos; - shadow = shadow2DProj(shadowMap1, lpos).x; + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; } else { - vec4 lpos = shadow_matrix[0]*pos; - shadow = shadow2DProj(shadowMap0, lpos).x; + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; } // take the most-shadowed value out of these two: @@ -126,6 +163,17 @@ void main() // * an unblurred dot product between the sun and this norm // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting shadow = min(shadow, dp_directional_light); + + /*debug.r = lpos.y / (lpos.w*screen_res.y); + + lpos.xy /= lpos.w*32.0; + if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) + { + debug.gb = vec2(0.5, 0.5); + } + + debug += (1.0-shadow)*0.5;*/ + } else { @@ -135,5 +183,18 @@ void main() gl_FragColor[0] = shadow; gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - //gl_FragColor[2] is unused as of August 2008, may be used for debugging + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + lpos.xy *= screen_res; + gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x; + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + lpos.xy *= screen_res; + gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x; + + //gl_FragColor.rgb = pos.xyz; + //gl_FragColor.b = shadow; + //gl_FragColor.rgb = debug; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 211b2e039..308b9b1fd 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -12,7 +12,6 @@ uniform sampler2D detail_3; uniform sampler2D alpha_ramp; varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -28,9 +27,8 @@ void main() float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a; vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); - gl_FragData[0] = vec4(outColor.rgb, 1.0); + gl_FragData[0] = vec4(outColor.rgb, 0.0); // Kl 0.0 looks fine atm however check grass above waterline when GI enabled in future releases! gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index e9d6dcabf..3038b1477 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -6,7 +6,6 @@ */ varying vec3 vary_normal; -varying vec4 vary_position; vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) { @@ -27,7 +26,6 @@ void main() //transform vertex gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_position = gl_ModelViewMatrix * gl_Vertex; vary_normal = normalize(gl_NormalMatrix * gl_Normal); // Transform and pass tex coords diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index bc2c9816d..49c65f117 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -8,13 +8,11 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragData[0] = gl_Color*col; gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index 9131d7c2b..6b9dc2def 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -6,7 +6,6 @@ */ varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -14,8 +13,6 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 0a1f019e3..6eea65633 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -17,7 +17,7 @@ uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform float sunAngle; diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl new file mode 100644 index 000000000..623ef7a81 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl @@ -0,0 +1,31 @@ +/** + * @file colorFilterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float brightness; +uniform float contrast; +uniform vec3 contrastBase; +uniform float saturation; +uniform vec3 lumWeights; + +const float gamma = 2.0; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Modulate brightness + color *= brightness; + + /// Modulate contrast + color = mix(contrastBase, color, contrast); + + /// Modulate saturation + color = mix(vec3(dot(color, lumWeights)), color, saturation); + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl new file mode 100644 index 000000000..29c2a0948 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl @@ -0,0 +1,14 @@ +/** + * @file drawQuadV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void main(void) +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[1] = gl_MultiTexCoord1; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl new file mode 100644 index 000000000..271d5cf8d --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl @@ -0,0 +1,42 @@ +/** + * @file nightVisionF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform sampler2D NoiseTexture; +uniform float brightMult; +uniform float noiseStrength; + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = luminance(color) * brightMult; + + /// Convert into night vision color space + /// Newer NVG colors (crisper and more saturated) + vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); + + /// Add noise + float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r; + noiseValue = (noiseValue - 0.5) * noiseStrength; + + /// Older NVG colors (more muted) + // vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); + + outColor += noiseValue; + + gl_FragColor = vec4(outColor, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl new file mode 100644 index 000000000..0055a736c --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -0,0 +1,112 @@ +/** + * @file alphaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2D diffuseMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; +uniform sampler2DRect depthMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_light; + +uniform float alpha_soften; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + frag *= screen_res; + + vec3 samp_pos = getPosition(frag).xyz; + + float shadow = 1.0; + vec4 pos = vec4(vary_position, 1.0); + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; + } + } + + vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a); + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + if (samp_pos.z != 0.0) + { + float dist_factor = alpha_soften; + float a = gl_Color.a; + a *= a; + dist_factor *= 1.0/(1.0-a); + color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); + } + + //gl_FragColor = gl_Color; + gl_FragColor = color; + //gl_FragColor = vec4(1,0,1,1)*shadow; + +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl new file mode 100644 index 000000000..ab60b6512 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -0,0 +1,75 @@ +/** + * @file alphaV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_light; + +uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + vary_position = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col; + col.a = gl_Color.a; + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + col.rgb = scaleUpLight(col.rgb); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + vary_light = gl_LightSource[0].position.xyz; + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + + pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); + +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl new file mode 100644 index 000000000..fe83c3c10 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl @@ -0,0 +1,77 @@ +/** + * @file avatarAlphaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec4 vary_position; +varying vec3 vary_normal; + +void main() +{ + float shadow = 1.0; + vec4 pos = vary_position; + vec3 norm = normalize(vary_normal); + + vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; + } + } + + + vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + gl_FragColor = color; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl new file mode 100644 index 000000000..c1988d3c7 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -0,0 +1,78 @@ +/** + * @file avatarAlphaV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +mat4 getSkinnedTransform(); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec4 vary_position; +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_normal; + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getSkinnedTransform(); + pos.x = dot(trans[0], gl_Vertex); + pos.y = dot(trans[1], gl_Vertex); + pos.z = dot(trans[2], gl_Vertex); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, gl_Normal); + norm.y = dot(trans[1].xyz, gl_Normal); + norm.z = dot(trans[2].xyz, gl_Normal); + norm = normalize(norm); + + gl_Position = gl_ProjectionMatrix * pos; + vary_position = pos; + vary_normal = norm; + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col; + col.a = gl_Color.a; + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + col.rgb = scaleUpLight(col.rgb); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + +} + + diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl new file mode 100644 index 000000000..1713fe99f --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl @@ -0,0 +1,71 @@ +/** + * @file blurLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; + +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform vec3 kern[32]; +uniform int kern_length; +uniform float kern_scale; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + vec3 pos = getPosition(vary_fragcoord.xy).xyz; + vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; + + vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); + + dlt /= max(-pos.z*dist_factor, 1.0); + + vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' + vec4 col = defined_weight.xyxx * ccol; + + for (int i = 1; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; + vec3 samppos = getPosition(tc).xyz; + float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane + if (d*d <= 0.003) + { + col += texture2DRect(lightMap, tc)*kern[i].xyxx; + defined_weight += kern[i].xy; + } + } + + + + col /= defined_weight.xyxx; + + gl_FragColor = col; + + //gl_FragColor = ccol; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl new file mode 100644 index 000000000..b7f07e570 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl @@ -0,0 +1,17 @@ +/** + * @file blurLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl new file mode 100644 index 000000000..651959413 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -0,0 +1,188 @@ +/** + * @file multiSpotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); + if (dist_atten <= 0.0) + { + discard; + } + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + float amb_da = proj_ambiance; + + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + + if (stc.z > 0.0) + { + stc.xy /= stc.w; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl new file mode 100644 index 000000000..ee0e9d636 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl @@ -0,0 +1,59 @@ +/** + * @file postDeferredF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; + +uniform vec3 gi_lum_quad; +uniform vec3 sun_lum_quad; +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + + float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; + gi_col *= diff; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + float sun_lum = 1.0-lum; + sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; + + float gi_lum = lum; + gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; + gi_col *= 1.0/gi_lum; + + vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); + + //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl new file mode 100644 index 000000000..9819232fd --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl @@ -0,0 +1,17 @@ +/** + * @file postDeferredV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl new file mode 100644 index 000000000..52b79e3de --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -0,0 +1,294 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; +uniform vec3 gi_quad; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform sampler2DRect depthMap; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +vec4 getPosition(vec2 pos_screen) +{ //get position in screen space (world units) given window coordinate and depth map + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 getPositionEye() +{ + return vary_PositionEye; +} +vec3 getSunlitColor() +{ + return vary_SunlitColor; +} +vec3 getAmblitColor() +{ + return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ + return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ + return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ + vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ + vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ + vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ + vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ + vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ + light *= getAtmosAttenuation().r; + light += getAdditiveColor(); + return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + light += getAdditiveColor() * 2.0; + return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ + return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 pos = getPosition(tc).xyz; + vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; + + float da = max(dot(norm.xyz, vary_light.xyz), 0.0); + + vec4 diffuse = texture2DRect(diffuseRect, tc); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + float scol = max(scol_ambocc.r, diffuse.a); + float ambocc = scol_ambocc.g; + + calcAtmospherics(pos.xyz, ambocc); + + vec3 col = atmosAmbient(vec3(0)); + col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); + + col *= diffuse.rgb; + + if (spec.a > 0.0) + { + vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); + float sa = dot(ref, vary_light.xyz); + col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; + } + + col = atmosLighting(col); + col = scaleSoftClip(col); + + gl_FragColor.rgb = col; + + //gl_FragColor.rgb = gi_col.rgb; + gl_FragColor.a = 0.0; + + //gl_FragColor.rg = scol_ambocc.rg; + //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; + //gl_FragColor.rgb = norm.rgb*0.5+0.5; + //gl_FragColor.rgb = vec3(ambocc); + //gl_FragColor.rgb = vec3(scol); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl new file mode 100644 index 000000000..ad8af4780 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -0,0 +1,24 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl new file mode 100644 index 000000000..d6534083c --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -0,0 +1,199 @@ +/** + * @file spotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + } + + float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); + float amb_da = proj_ambiance; + if (da > 0.0) + { + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + + if (stc.z > 0.0) + { + stc.xy /= stc.z+proj_near; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + /*if (spec.a > 0.0) + { + //vec3 ref = reflect(normalize(pos), norm); + float sa = dot(normalize(lv-normalize(pos)),norm);; + //sa = max(sa, 0.0); + //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); + sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*lcol*spec.rgb; + }*/ + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl new file mode 100644 index 000000000..8ced94ee0 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -0,0 +1,203 @@ +/** + * @file sunLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DRectShadow shadowMap4; +uniform sampler2DRectShadow shadowMap5; +uniform sampler2D noiseMap; + +uniform sampler2D lightFunc; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm) +{ + vec2 kern[8]; + // exponentially (^2) distant occlusion samples spread around origin + kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; + kern[1] = vec2(1.0, 0.0) * 0.250*0.250; + kern[2] = vec2(0.0, 1.0) * 0.375*0.375; + kern[3] = vec2(0.0, -1.0) * 0.500*0.500; + kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; + kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; + kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; + kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + + vec2 pos_screen = vary_fragcoord.xy; + vec3 pos_world = pos.xyz; + vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + + float angle_hidden = 0.0; + int points = 0; + + float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + + // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) + for (int i = 0; i < 8; i++) + { + vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; + + vec3 diff = pos_world - samppos_world; + float dist2 = dot(diff, diff); + + // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area + // --> solid angle shrinking by the square of distance + //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 + //(k should vary inversely with # of samples, but this is taken care of later) + + //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces + // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); + } + + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + + return (1.0 - (float(points != 0) * angle_hidden)); +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + + //try doing an unproject here + + vec4 pos = getPosition(pos_screen); + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; + + /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL + { + gl_FragColor = vec4(0.0); // doesn't matter + return; + }*/ + + float shadow = 1.0; + float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + + vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); + + //vec3 debug = vec3(0,0,0); + + if (spos.z > -shadow_clip.w) + { + if (dp_directional_light == 0.0) + { + // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup + shadow = 0.0; + } + else + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; + } + + // take the most-shadowed value out of these two: + // * the blurred sun shadow in the light (shadow) map + // * an unblurred dot product between the sun and this norm + // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting + shadow = min(shadow, dp_directional_light); + } + + /*debug.r = lpos.y / (lpos.w*screen_res.y); + + lpos.xy /= lpos.w*32.0; + if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) + { + debug.gb = vec2(0.5, 0.5); + } + + debug += (1.0-shadow)*0.5;*/ + + } + else + { + // more distant than the shadow map covers + shadow = 1.0; + } + + gl_FragColor[0] = shadow; + gl_FragColor[1] = calcAmbientOcclusion(pos, norm); + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + lpos.xy *= screen_res; + gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x; + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + lpos.xy *= screen_res; + gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x; + + //gl_FragColor.rgb = pos.xyz; + //gl_FragColor.b = shadow; + //gl_FragColor.rgb = debug; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl new file mode 100644 index 000000000..5081485c4 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl @@ -0,0 +1,25 @@ +/** + * @file sunLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl new file mode 100644 index 000000000..734218616 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl @@ -0,0 +1,139 @@ +/** + * @file waterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 scaleSoftClip(vec3 inColor); +vec3 atmosTransport(vec3 inColor); + +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; + +uniform float sunAngle; +uniform float sunAngle2; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform float refScale; +uniform float kd; +uniform vec2 screenRes; +uniform vec3 normScale; +uniform float fresnelScale; +uniform float fresnelOffset; +uniform float blurMultiplier; +uniform vec2 screen_res; +uniform mat4 norm_mat; //region space to screen space + +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; +varying vec4 vary_position; + +void main() +{ + vec4 color; + float dist = length(view.xy); + + //normalize view vector + vec3 viewVec = normalize(view.xyz); + + //get wave normals + vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; + //get base fresnel components + + vec3 df = vec3( + dot(viewVec, wave1), + dot(viewVec, (wave2 + wave3) * 0.5), + dot(viewVec, wave3) + ) * fresnelScale + fresnelOffset; + df *= df; + + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + + float dist2 = dist; + dist = max(dist, 5.0); + + float dmod = sqrt(dist); + + vec2 dmod_scale = vec2(dmod*dmod, dmod); + + //get reflected color + vec2 refdistort1 = wave1.xy*normScale.x; + vec2 refvec1 = distort+refdistort1/dmod_scale; + vec4 refcol1 = texture2D(refTex, refvec1); + + vec2 refdistort2 = wave2.xy*normScale.y; + vec2 refvec2 = distort+refdistort2/dmod_scale; + vec4 refcol2 = texture2D(refTex, refvec2); + + vec2 refdistort3 = wave3.xy*normScale.z; + vec2 refvec3 = distort+refdistort3/dmod_scale; + vec4 refcol3 = texture2D(refTex, refvec3); + + vec4 refcol = refcol1 + refcol2 + refcol3; + float df1 = df.x + df.y + df.z; + refcol *= df1 * 0.333; + + vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; + //wavef.z *= max(-viewVec.z, 0.1); + wavef = normalize(wavef); + + float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; + + vec2 refdistort4 = wavef.xy*0.125; + refdistort4.y -= abs(refdistort4.y); + vec2 refvec4 = distort+refdistort4/dmod; + float dweight = min(dist2*blurMultiplier, 1.0); + vec4 baseCol = texture2D(refTex, refvec4); + refcol = mix(baseCol*df2, refcol, dweight); + + //get specular component + //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); + + //harden specular + //spec = pow(spec, 128.0); + + //figure out distortion vector (ripply) + vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); + + vec4 fb = texture2D(screenTex, distort2); + + //mix with reflection + // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug + color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); + + float shadow = 1.0; + vec4 pos = vary_position; + + vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + vec4 spos = pos; + + //spec *= shadow; + //color.rgb += spec * specular; + + //color.rgb = atmosTransport(color.rgb); + //color.rgb = scaleSoftClip(color.rgb); + //color.a = spec * sunAngle2; + + //wavef.z *= 0.1f; + wavef = normalize(wavef); + wavef = (norm_mat*vec4(wavef, 1.0)).xyz; + + gl_FragData[0] = vec4(color.rgb, 0.75); + gl_FragData[1] = vec4(1,1,1, 0.8); + gl_FragData[2] = vec4(wavef*0.5+0.5, 0.f); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl new file mode 100644 index 000000000..b45e5c530 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl @@ -0,0 +1,76 @@ +/** + * @file waterV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec2 d1; +uniform vec2 d2; +uniform float time; +uniform vec3 eyeVec; +uniform float waterHeight; + +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; + +varying vec4 vary_position; + +float wave(vec2 v, float t, float f, vec2 d, float s) +{ + return (dot(d, v)*f + t*s)*f; +} + +void main() +{ + //transform vertex + vec4 position = gl_Vertex; + mat4 modelViewProj = gl_ModelViewProjectionMatrix; + + vec4 oPosition; + + //get view vector + vec3 oEyeVec; + oEyeVec.xyz = position.xyz-eyeVec; + + float d = length(oEyeVec.xy); + float ld = min(d, 2560.0); + + position.xy = eyeVec.xy + oEyeVec.xy/d*ld; + view.xyz = oEyeVec; + + d = clamp(ld/1536.0-0.5, 0.0, 1.0); + d *= d; + + oPosition = position; + oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); + vary_position = gl_ModelViewMatrix * oPosition; + oPosition = modelViewProj * oPosition; + + refCoord.xyz = oPosition.xyz + vec3(0,0,0.2); + + //get wave position parameter (create sweeping horizontal waves) + vec3 v = position.xyz; + v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0; + + //push position for further horizon effect. + position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z); + position.w = 1.0; + position = position*gl_ModelViewMatrix; + + calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz); + + + //pass wave parameters to pixel shader + vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; + //get two normal map (detail map) texture coordinates + littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13; + littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1; + view.w = bigWave.y; + refCoord.w = bigWave.x; + + gl_Position = oPosition; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl new file mode 100644 index 000000000..9cc71a709 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl @@ -0,0 +1,18 @@ +/** + * @file avatarF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + gl_FragData[0] = vec4(gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb, 0.0); + gl_FragData[1] = vec4(0,0,0,0); + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +} + diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl new file mode 100644 index 000000000..6eb4a5184 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl @@ -0,0 +1,27 @@ +/** + * @file bumpF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2D bumpMap; + +varying vec3 vary_mat0; +varying vec3 vary_mat1; +varying vec3 vary_mat2; + +void main() +{ + vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; + vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0; + + vec3 tnorm = vec3(dot(norm,vary_mat0), + dot(norm,vary_mat1), + dot(norm,vary_mat2)); + + gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); + gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); + gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl new file mode 100644 index 000000000..c9f75f731 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl @@ -0,0 +1,18 @@ +/** + * @file diffuseF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; + gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); + gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl new file mode 100644 index 000000000..7325825d6 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl @@ -0,0 +1,84 @@ +/** + * @file giDownsampleF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect giLightMap; + +uniform vec2 kern[32]; +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform int kern_length; +uniform float kern_scale; +uniform vec3 blur_quad; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +float getDepth(vec2 pos_screen) +{ + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + float depth = getDepth(vary_fragcoord.xy); + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy); + dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0); + float defined_weight = kern[0].x; + vec3 col = ccol*kern[0].x; + + for (int i = 0; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; + vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0; + + float d = dot(norm.xyz, sampNorm); + + if (d > 0.5) + { + float sampdepth = getDepth(tc.xy); + sampdepth -= depth; + if (sampdepth*sampdepth < blur_quad.z) + { + col += texture2DRect(giLightMap, tc).rgb*kern[i].x; + defined_weight += kern[i].x; + } + } + } + + col /= defined_weight; + + //col = ccol; + + col = col*blur_quad.y; + + gl_FragData[0].xyz = col; + + //gl_FragColor = ccol; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl new file mode 100644 index 000000000..6adcda82a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl @@ -0,0 +1,17 @@ +/** + * @file postgiV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl new file mode 100644 index 000000000..43da836cc --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl @@ -0,0 +1,219 @@ +/** + * @file giF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DRect specularRect; + +uniform sampler2D noiseMap; + +uniform sampler2D diffuseGIMap; +uniform sampler2D specularGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; + +uniform sampler2D lightFunc; + +// Inputs +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +uniform vec4 sunlight_color; + +uniform mat4 inv_proj; +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_radius; +uniform float gi_intensity; +uniform int gi_samples; +uniform vec2 gi_kern[25]; +uniform vec2 gi_scale; +uniform vec3 gi_quad; +uniform vec3 gi_spec; +uniform float gi_direction_weight; +uniform float gi_light_offset; +uniform float gi_range; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 giAmbient(vec3 pos, vec3 norm) +{ + vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); + gi_c.xyz /= gi_c.w; + + vec4 gi_pos = gi_mat*vec4(pos,1.0); + vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; + gi_norm = normalize(gi_norm); + + vec4 c_spec = texture2DRect(specularRect, vary_fragcoord.xy); + gi_pos.xyz += (texture2D(noiseMap, vary_fragcoord.xy/128.0).x)*gi_spec.z*gi_norm.xyz; + vec2 tcx = gi_norm.xy; + vec2 tcy = gi_norm.yx; + + vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); + + vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz); + vec3 eye_ref = reflect(eye_dir, gi_norm); + + //vec3 eye_dir = vec3(0,0,-1); + //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; + //eye_dir = normalize(eye_dir); + + //float round_x = gi_scale.x; + //float round_y = gi_scale.y; + + vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb; + //debug.xz = vec2(0.0,0.0); + //debug = fract(debug); + + float round_x = 1.0/64.0; + float round_y = 1.0/64.0; + + //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; + //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; + + float da = texture2DRect(lightMap, vary_fragcoord.xy).r; + + vec3 fdiff = vec3(da); + + if (da > 0.0) + { + vec3 ha = -eye_dir; + ha.z += 1.0; + ha = normalize(ha); + + float sa = dot(ha,gi_norm); + da = min(da, texture2D(lightFunc, vec2(sa, c_spec.a)).a); + fdiff += da*(c_spec.rgb*c_spec.a*2.0); + } + + float fda = da; + + vec3 rcol = vec3(0,0,0); + + float fsa = 0.0; + + + for (int i = -1; i <= 1; i += 1 ) + { + for (int j = -1; j <= 1; j+= 1) + { + vec2 tc = vec2(i, j)*0.75+gi_norm.xy; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; + tc += gi_norm.xy*nz.z; + tc += nz.xy*2.0; + tc /= gi_samples; + tc += gi_c.xy; + + vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); + vec3 lpos = getGIPosition(tc.xy).xyz; + + vec3 at = lpos-gi_pos.xyz; + float dist = dot(at,at); + float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); + + + if (da > 0.01) + { //possible contribution of indirect light to this surface + vec3 ldir = at; + + float ld = -dot(ldir, lnorm); + + if (ld < 0.0) + { + float ang_atten = dot(ldir, gi_norm); + + if (ang_atten > 0.0) + { + vec4 spec = texture2D(specularGIMap, tc.xy); + at = normalize(at); + vec3 diff; + + { //contribution from indirect source to visible pixel + vec3 ha = at; + ha.z -= 1.0; + ha = normalize(ha); + float sa = dot(ha,lnorm); + da = min(da, texture2D(lightFunc, vec2(sa, spec.a)).a); + + diff = texture2D(diffuseGIMap, tc.xy).rgb+spec.rgb*spec.a*2.0; + } + + if (da > 0.0) + { //contribution from visible pixel to eye + vec3 ha = normalize(at-eye_dir); + float sa = dot(ha, gi_norm); + da = min(da, texture2D(lightFunc, vec2(sa, c_spec.a)).a); + fda += da; + fdiff += da*(c_spec.rgb*c_spec.a*2.0+vec3(1,1,1))*diff.rgb; + } + } + } + } + } + } + + //fdiff /= max(gi_spec.y*fda, gi_quad.z); + //fdiff = clamp(fdiff, vec3(0), vec3(1)); + fdiff *= 64.0; + fdiff *= sunlight_color.rgb; + + vec3 ret = fda*fdiff; + //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; + + //fda *= nz.z; + + //rcol.rgb *= gi_intensity; + //return rcol.rgb+vary_AmblitColor.rgb*0.25; + //return vec4(debug, 0.0); + //return vec4(fda*fdiff, 0.0); + return clamp(ret,vec3(0.0), vec3(1.0)); + //return debug.xyz; +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + + float rad = gi_range*0.5; + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; + float dist = max(length(pos.xyz)-rad, 0.0); + + float da = clamp(1.0-dist/rad, 0.0, 1.0); + gl_FragData[0].xyz = da > 0.0 ? giAmbient(pos, norm)*da : vec3(0,0,0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl new file mode 100644 index 000000000..71dcea962 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl @@ -0,0 +1,22 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl new file mode 100644 index 000000000..0de0d11b2 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl @@ -0,0 +1,16 @@ +/** + * @file luminanceF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseMap; + +varying vec2 vary_fragcoord; +uniform float fade; +void main() +{ + gl_FragColor.rgb = texture2DRect(diffuseMap, vary_fragcoord.xy).rgb; + gl_FragColor.a = fade; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl new file mode 100644 index 000000000..db8775f02 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl @@ -0,0 +1,20 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl new file mode 100644 index 000000000..609fb1d1e --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl @@ -0,0 +1,76 @@ +/** + * @file postDeferredF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; +uniform sampler2D lightFunc; + + +uniform vec3 gi_lum_quad; +uniform vec3 sun_lum_quad; +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + + float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec3 gi_col = ccol; + /*for (int i = -1; i <= 1; i+=1) + { + for (int j = -1; j <= 1; j+=1) + { + vec2 tc = vec2(i,j); + float wght = 1.0/(length(tc)+1.0); + gi_col += texture2DRect(giLightMap, vary_fragcoord.xy+vec2(i,j)).rgb * wght; + } + }*/ + + //gi_col *= 1.0+spec.a*4.0; + gi_col = (sqrt(gi_col)*gi_quad.x + gi_col*gi_quad.y)*(diff.rgb+spec.rgb*spec.a)+gi_quad.z*ambocc*ambient.rgb*diff.rgb; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + float sun_lum = 1.0-lum; + sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; + + float gi_lum = lum; + gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; + gi_col *= 1.0/gi_lum; + + + vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); + + //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + //gl_FragColor.rgb = vec3(texture2D(lightFunc, vary_fragcoord.xy/512.0-vec2(0.5, 0.5)).a); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl new file mode 100644 index 000000000..9819232fd --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl @@ -0,0 +1,17 @@ +/** + * @file postDeferredV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl new file mode 100644 index 000000000..12a5f3945 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl @@ -0,0 +1,87 @@ +/** + * @file postgiF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect giLightMap; +uniform sampler2D noiseMap; + +uniform vec2 kern[32]; +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform int kern_length; +uniform float kern_scale; +uniform vec3 blur_quad; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +float getDepth(vec2 pos_screen) +{ + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + float depth = getDepth(vary_fragcoord.xy); + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy); + dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0); + float defined_weight = kern[0].x; + vec3 col = ccol*kern[0].x; + + for (int i = 0; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; + vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0; + + float d = dot(norm.xyz, sampNorm); + + if (d > 0.5) + { + float sampdepth = getDepth(tc.xy); + sampdepth -= depth; + if (sampdepth*sampdepth < blur_quad.z) + { + col += texture2DRect(giLightMap, tc).rgb*kern[i].x; + defined_weight += kern[i].x; + } + } + } + + col /= defined_weight; + + //col = ccol; + + col = col*blur_quad.y; + + gl_FragData[0].xyz = col; + + //gl_FragColor = ccol; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl new file mode 100644 index 000000000..6adcda82a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl @@ -0,0 +1,17 @@ +/** + * @file postgiV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl new file mode 100644 index 000000000..654b18260 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -0,0 +1,312 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; +uniform sampler2D luminanceMap; + +uniform vec3 gi_quad; +uniform vec3 lum_quad; +uniform float lum_lod; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform sampler2DRect depthMap; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +vec4 getPosition(vec2 pos_screen) +{ //get position in screen space (world units) given window coordinate and depth map + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 getPositionEye() +{ + return vary_PositionEye; +} +vec3 getSunlitColor() +{ + return vary_SunlitColor; +} +vec3 getAmblitColor() +{ + return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ + return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ + return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ + vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ + vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ + vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ + vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ + vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ + light *= getAtmosAttenuation().r; + light += getAdditiveColor(); + return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + light += getAdditiveColor() * 2.0; + return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ + return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 pos = getPosition(tc).xyz; + vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; + + vec3 at = normalize(pos); + + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + + vec3 ha = normalize(vary_light.xyz-at); + + float da = dot(ha, norm.xyz); + da = texture2D(lightFunc, vec2(da, spec.a)).a; + + vec4 diffuse = texture2DRect(diffuseRect, tc); + + vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + float scol = max(scol_ambocc.r, diffuse.a); + float ambocc = scol_ambocc.g; + + calcAtmospherics(pos.xyz, ambocc); + + vec3 col = vec3(0,0,0); + + col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)*(1.0+spec.a)); + + col *= diffuse.rgb; + + col += da*spec.rgb*spec.a*vary_SunlitColor*scol_ambocc.r; + + /*if (spec.a > 0.0) + { + vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); + float sa = dot(ref, vary_light.xyz); + col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; + }*/ + + col = atmosLighting(col); + col = scaleSoftClip(col); + + col = col*vec3(1.0+1.0/2.2); + + gl_FragColor.rgb = col; + //gl_FragColor.rgb = lum; + + gl_FragColor.a = 0.0; + + //gl_FragColor.rg = scol_ambocc.rg; + //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; + //gl_FragColor.rgb = norm.rgb*0.5+0.5; + //gl_FragColor.rgb = vec3(ambocc); + //gl_FragColor.rgb = vec3(scol); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl new file mode 100644 index 000000000..ad8af4780 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl @@ -0,0 +1,24 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl new file mode 100644 index 000000000..258acee08 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl @@ -0,0 +1,18 @@ +/** + * @file treeF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005); + gl_FragData[1] = vec4(0,0,0,0); + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl new file mode 100644 index 000000000..bea1515f5 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl @@ -0,0 +1,139 @@ +/** + * @file waterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 scaleSoftClip(vec3 inColor); +vec3 atmosTransport(vec3 inColor); + +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; + +uniform float sunAngle; +uniform float sunAngle2; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform float refScale; +uniform float kd; +uniform vec2 screenRes; +uniform vec3 normScale; +uniform float fresnelScale; +uniform float fresnelOffset; +uniform float blurMultiplier; +uniform vec2 screen_res; +uniform mat4 norm_mat; //region space to screen space + +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; +varying vec4 vary_position; + +void main() +{ + vec4 color; + float dist = length(view.xy); + + //normalize view vector + vec3 viewVec = normalize(view.xyz); + + //get wave normals + vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; + //get base fresnel components + + vec3 df = vec3( + dot(viewVec, wave1), + dot(viewVec, (wave2 + wave3) * 0.5), + dot(viewVec, wave3) + ) * fresnelScale + fresnelOffset; + df *= df; + + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + + float dist2 = dist; + dist = max(dist, 5.0); + + float dmod = sqrt(dist); + + vec2 dmod_scale = vec2(dmod*dmod, dmod); + + //get reflected color + vec2 refdistort1 = wave1.xy*normScale.x; + vec2 refvec1 = distort+refdistort1/dmod_scale; + vec4 refcol1 = texture2D(refTex, refvec1); + + vec2 refdistort2 = wave2.xy*normScale.y; + vec2 refvec2 = distort+refdistort2/dmod_scale; + vec4 refcol2 = texture2D(refTex, refvec2); + + vec2 refdistort3 = wave3.xy*normScale.z; + vec2 refvec3 = distort+refdistort3/dmod_scale; + vec4 refcol3 = texture2D(refTex, refvec3); + + vec4 refcol = refcol1 + refcol2 + refcol3; + float df1 = df.x + df.y + df.z; + refcol *= df1 * 0.333; + + vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; + //wavef.z *= max(-viewVec.z, 0.1); + wavef = normalize(wavef); + + float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; + + vec2 refdistort4 = wavef.xy*0.125; + refdistort4.y -= abs(refdistort4.y); + vec2 refvec4 = distort+refdistort4/dmod; + float dweight = min(dist2*blurMultiplier, 1.0); + vec4 baseCol = texture2D(refTex, refvec4); + refcol = mix(baseCol*df2, refcol, dweight); + + //get specular component + //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); + + //harden specular + //spec = pow(spec, 128.0); + + //figure out distortion vector (ripply) + vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); + + vec4 fb = texture2D(screenTex, distort2); + + //mix with reflection + // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug + color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); + + float shadow = 1.0; + vec4 pos = vary_position; + + vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + vec4 spos = pos; + + //spec *= shadow; + //color.rgb += spec * specular; + + //color.rgb = atmosTransport(color.rgb); + //color.rgb = scaleSoftClip(color.rgb); + //color.a = spec * sunAngle2; + + //wavef.z *= 0.1f; + wavef = normalize(wavef); + wavef = (norm_mat*vec4(wavef, 1.0)).xyz; + + gl_FragData[0] = vec4(color.rgb, 0.5); + gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); + gl_FragData[2] = vec4(wavef*0.5+0.5, 0.f); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl new file mode 100644 index 000000000..94433202a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl @@ -0,0 +1,31 @@ +/** + * @file blurf.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float bloomStrength; + +varying vec4 gl_TexCoord[gl_MaxTextureCoords]; +void main(void) +{ + float blurWeights[7]; + blurWeights[0] = 0.05; + blurWeights[1] = 0.1; + blurWeights[2] = 0.2; + blurWeights[3] = 0.3; + blurWeights[4] = 0.2; + blurWeights[5] = 0.1; + blurWeights[6] = 0.05; + + vec3 color = vec3(0,0,0); + for (int i = 0; i < 7; i++){ + color += vec3(texture2DRect(RenderTexture, gl_TexCoord[i].st)) * blurWeights[i]; + } + + color *= bloomStrength; + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl new file mode 100644 index 000000000..ba65b16cc --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl @@ -0,0 +1,35 @@ +/** + * @file blurV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 texelSize; +uniform vec2 blurDirection; +uniform float blurWidth; + +void main(void) +{ + // Transform vertex + gl_Position = ftransform(); + + vec2 blurDelta = texelSize * blurDirection * vec2(blurWidth, blurWidth); + vec2 s = gl_MultiTexCoord0.st - (blurDelta * 3.0); + + // for (int i = 0; i < 7; i++) { + // gl_TexCoord[i].st = s + (i * blurDelta); + // } + + // MANUALLY UNROLL + gl_TexCoord[0].st = s; + gl_TexCoord[1].st = s + blurDelta; + gl_TexCoord[2].st = s + (2. * blurDelta); + gl_TexCoord[3].st = s + (3. * blurDelta); + gl_TexCoord[4].st = s + (4. * blurDelta); + gl_TexCoord[5].st = s + (5. * blurDelta); + gl_TexCoord[6].st = s + (6. * blurDelta); + + // gl_TexCoord[0].st = s; + // gl_TexCoord[1].st = blurDelta; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl new file mode 100644 index 000000000..623ef7a81 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl @@ -0,0 +1,31 @@ +/** + * @file colorFilterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float brightness; +uniform float contrast; +uniform vec3 contrastBase; +uniform float saturation; +uniform vec3 lumWeights; + +const float gamma = 2.0; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Modulate brightness + color *= brightness; + + /// Modulate contrast + color = mix(contrastBase, color, contrast); + + /// Modulate saturation + color = mix(vec3(dot(color, lumWeights)), color, saturation); + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl new file mode 100644 index 000000000..29c2a0948 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl @@ -0,0 +1,14 @@ +/** + * @file drawQuadV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void main(void) +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[1] = gl_MultiTexCoord1; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl new file mode 100644 index 000000000..a1583b13e --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl @@ -0,0 +1,22 @@ +/** + * @file extractF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float extractLow; +uniform float extractHigh; +uniform vec3 lumWeights; + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = smoothstep(extractLow, extractHigh, dot(color, lumWeights)); + + gl_FragColor = vec4(vec3(lum), 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl new file mode 100644 index 000000000..271d5cf8d --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl @@ -0,0 +1,42 @@ +/** + * @file nightVisionF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform sampler2D NoiseTexture; +uniform float brightMult; +uniform float noiseStrength; + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = luminance(color) * brightMult; + + /// Convert into night vision color space + /// Newer NVG colors (crisper and more saturated) + vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); + + /// Add noise + float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r; + noiseValue = (noiseValue - 0.5) * noiseStrength; + + /// Older NVG colors (more muted) + // vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); + + outColor += noiseValue; + + gl_FragColor = vec4(outColor, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl new file mode 100644 index 000000000..e55d278b8 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl @@ -0,0 +1,14 @@ +/** + * @file simpleF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + gl_FragColor = vec4(1.0 - color, 1.0); +} diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 5bcffdbc9..4342e60dc 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -223,6 +223,7 @@ LLAgent gAgent; // Statics // BOOL LLAgent::sPhantom = FALSE; +BOOL LLAgent::sDebugDisplayTarget = FALSE; const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f; @@ -6618,7 +6619,7 @@ void LLAgent::saveWearable( EWearableType type, BOOL send_update ) return; } - getAvatarObject()->wearableUpdated( type ); + // getAvatarObject()->wearableUpdated( type ); if( send_update ) { diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 3a3944860..d3c16c5df 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -765,6 +765,7 @@ class LLAgent : public LLObservable BOOL mInitialized; + static BOOL sDebugDisplayTarget; S32 mNumPendingQueries; S32* mActiveCacheQueries; diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 86c83b9e1..a9a6052f1 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -447,7 +447,7 @@ static void settings_modify() LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] gDebugGL = gSavedSettings.getBOOL("RenderDebugGL"); gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); - gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); +// gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); #if LL_VECTORIZE if (gSysCPU.hasAltivec()) { diff --git a/linden/indra/newview/llcolorswatch.cpp b/linden/indra/newview/llcolorswatch.cpp index 5905bb0f2..3222c0dd2 100644 --- a/linden/indra/newview/llcolorswatch.cpp +++ b/linden/indra/newview/llcolorswatch.cpp @@ -219,11 +219,12 @@ void LLColorSwatchCtrl::draw() gl_rect_2d(interior, mColor, TRUE); LLColor4 opaque_color = mColor; opaque_color.mV[VALPHA] = 1.f; + gGL.color4fv(opaque_color.mV); if (mAlphaGradientImage.notNull()) { gGL.pushMatrix(); { - mAlphaGradientImage->draw(interior, opaque_color); + mAlphaGradientImage->draw(interior, mColor); } gGL.popMatrix(); } diff --git a/linden/indra/newview/llcompilequeue.cpp b/linden/indra/newview/llcompilequeue.cpp index ed18a1002..a81972da0 100644 --- a/linden/indra/newview/llcompilequeue.cpp +++ b/linden/indra/newview/llcompilequeue.cpp @@ -58,7 +58,6 @@ #include "llfloaterchat.h" #include "llviewerstats.h" #include "lluictrlfactory.h" -#include "llselectmgr.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llconsole.cpp b/linden/indra/newview/llconsole.cpp index 2379da37c..a8554a037 100644 --- a/linden/indra/newview/llconsole.cpp +++ b/linden/indra/newview/llconsole.cpp @@ -63,17 +63,25 @@ const S32 CONSOLE_GUTTER_LEFT = 14; const S32 CONSOLE_GUTTER_RIGHT = 15; -LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect, +LLConsole::LLConsole(const std::string& name, const LLRect &rect, S32 font_size_index, F32 persist_time ) - : - LLFixedBuffer(max_lines), - LLView(name, rect, FALSE) + : LLFixedBuffer(), + LLView(name, rect, FALSE), + mLinePersistTime(persist_time), + mFadeTime(persist_time - FADE_DURATION), + mFont(LLFontGL::getFontSansSerif()), + mConsoleWidth(0), + mConsoleHeight(0), + mQueueMutex(NULL) { - mLinePersistTime = persist_time; // seconds - mFadeTime = persist_time - FADE_DURATION; + mTimer.reset(); - setFontSize( font_size_index ); - setMaxLines(gSavedSettings.getS32("ConsoleMaxLines")); + setFontSize( font_size_index ); +} + +LLConsole::~LLConsole() +{ + clear(); } void LLConsole::setLinePersistTime(F32 seconds) @@ -98,10 +106,10 @@ void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent) mConsoleHeight= new_height; LLView::reshape(new_width, new_height, called_from_parent); - + for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++) { - (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true); + (*paragraph_it)->updateLines((F32)getRect().getWidth(), mFont, true); } } @@ -126,7 +134,7 @@ void LLConsole::setFontSize(S32 size_index) for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++) { - (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true); + (*paragraph_it)->updateLines((F32)getRect().getWidth(), mFont, true); } } @@ -134,35 +142,49 @@ void LLConsole::draw() { LLGLSUIDefault gls_ui; - // skip lines added more than mLinePersistTime ago - F32 cur_time = mTimer.getElapsedTimeF32(); - - F32 skip_time = cur_time - mLinePersistTime; - F32 fade_time = cur_time - mFadeTime; - - updateBuffer() ; + { + LLMutexLock lock(&mQueueMutex); + for(paragraph_t::iterator paragraph_it = mNewParagraphs.begin(); paragraph_it != mNewParagraphs.end(); paragraph_it++) + { + Paragraph* paragraph = *paragraph_it; + mParagraphs.push_back(paragraph); + paragraph->updateLines((F32)getRect().getWidth(), mFont); + } + mNewParagraphs.clear(); + } if (mParagraphs.empty()) //No text to draw. { return; } + // skip lines added more than mLinePersistTime ago + F32 cur_time = mTimer.getElapsedTimeF32(); + + F32 skip_time = cur_time - mLinePersistTime; + F32 fade_time = cur_time - mFadeTime; + + U32 max_lines = gSavedSettings.getS32("ConsoleMaxLines"); U32 num_lines=0; paragraph_t::reverse_iterator paragraph_it; paragraph_it = mParagraphs.rbegin(); U32 paragraph_num=mParagraphs.size(); - + while (!mParagraphs.empty() && paragraph_it != mParagraphs.rend()) { - num_lines += (*paragraph_it).mLines.size(); - if(num_lines > mMaxLines - || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) + num_lines += (*paragraph_it)->mLines.size(); + if(num_lines > max_lines + || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) { //All lines above here are done. Lose them. for (U32 i=0;i<paragraph_num;i++) { if (!mParagraphs.empty()) + { + Paragraph* paragraph = mParagraphs.front(); mParagraphs.pop_front(); + delete paragraph; + } } break; } @@ -193,8 +215,8 @@ void LLConsole::draw() S32 bkg_width=0; for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { - S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + message_spacing); - S32 target_width = llfloor( (*paragraph_it).mMaxWidth + CONSOLE_GUTTER_RIGHT); + S32 target_height = llfloor( (*paragraph_it)->mLines.size() * line_height + message_spacing); + S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); bkg_height+= target_height; if (target_width > bkg_width) @@ -203,7 +225,7 @@ void LLConsole::draw() } // Why is this not using llfloor as above? - y_pos += ((*paragraph_it).mLines.size()) * line_height; + y_pos += ((*paragraph_it)->mLines.size()) * line_height; y_pos += message_spacing; //Extra spacing between messages. } imagep->drawSolid(-CONSOLE_GUTTER_LEFT, (S32)(y_pos + line_height - bkg_height - message_spacing), bkg_width, bkg_height, color); @@ -213,10 +235,10 @@ void LLConsole::draw() for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { //080813 Spatters: Dainty per-message block boxes -// S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + 8); - S32 target_width = llfloor( (*paragraph_it).mMaxWidth + CONSOLE_GUTTER_RIGHT); +// S32 target_height = llfloor( (*paragraph_it)->mLines.size() * line_height + 8); + S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); - y_pos += ((*paragraph_it).mLines.size()) * line_height; + y_pos += ((*paragraph_it)->mLines.size()) * line_height; //080813 Spatters: Dainty per-message block boxes // imagep->drawSolid(-14, (S32)(y_pos + line_height - target_height), target_width, target_height, color); @@ -224,9 +246,9 @@ void LLConsole::draw() F32 alpha; - if ((mLinePersistTime > 0.f) && ((*paragraph_it).mAddTime < fade_time)) + if ((mLinePersistTime > 0.f) && ((*paragraph_it)->mAddTime < fade_time)) { - alpha = ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime); + alpha = ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime); } else { @@ -235,12 +257,12 @@ void LLConsole::draw() if( alpha > 0.f ) { - for (lines_t::iterator line_it=(*paragraph_it).mLines.begin(); - line_it != (*paragraph_it).mLines.end(); + for (lines_t::iterator line_it=(*paragraph_it)->mLines.begin(); + line_it != (*paragraph_it)->mLines.end(); line_it ++) { - for (line_color_segments_t::iterator seg_it = (*line_it).mLineColorSegments.begin(); - seg_it != (*line_it).mLineColorSegments.end(); + for (line_color_segments_t::iterator seg_it = (*line_it).begin(); + seg_it != (*line_it).end(); seg_it++) { mFont->render((*seg_it).mText, 0, (*seg_it).mXPosition - 8, y_pos - y_off, @@ -263,21 +285,34 @@ void LLConsole::draw() } } -void LLConsole::addLine(const std::string& utf8line) +//virtual +void LLConsole::clear() { - LLWString wline = utf8str_to_wstring(utf8line); - addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); + mTimer.reset(); + LLMutexLock lock(&mQueueMutex); + std::for_each(mParagraphs.begin(), mParagraphs.end(), DeletePointer()); + mParagraphs.clear(); + std::for_each(mNewParagraphs.begin(), mNewParagraphs.end(), DeletePointer()); + mNewParagraphs.clear(); } -void LLConsole::addLine(const LLWString& wline) +//virtual +void LLConsole::addLine(const std::string& utf8line) { - addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); + addConsoleLine(utf8line, LLColor4(1.f, 1.f, 1.f, 1.f)); } -void LLConsole::addLine(const std::string& utf8line, F32 size, const LLColor4 &color) +void LLConsole::addConsoleLine(const std::string& utf8line, const LLColor4 &color) { LLWString wline = utf8str_to_wstring(utf8line); - addLine(wline, size, color); + addConsoleLine(wline, color); +} + +void LLConsole::addConsoleLine(const LLWString& wline, const LLColor4 &color) +{ + Paragraph* paragraph = new Paragraph(wline, color, mTimer.getElapsedTimeF32()); + LLMutexLock lock(&mQueueMutex); + mNewParagraphs.push_back ( paragraph ); } //Generate highlight color segments for this paragraph. Pass in default color of paragraph. @@ -359,7 +394,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo F32 x_position = 0; //Screen X position of text. mMaxWidth = llmax( mMaxWidth, (F32)font->getWidth( mParagraphText.substr( paragraph_offset, drawable ).c_str() ) ); - Line line; + line_color_segments_t line; U32 left_to_draw = drawable; U32 drawn = 0; @@ -368,7 +403,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo && current_color != mParagraphColorSegments.end() ) { LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, current_color_length ); - line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line. + line.push_back( LineColorSegment( color_text, //Append segment to line. (*current_color).mColor, x_position ) ); @@ -389,7 +424,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo { LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, left_to_draw ); - line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line. + line.push_back( LineColorSegment( color_text, //Append segment to line. (*current_color).mColor, x_position ) ); @@ -407,50 +442,9 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo } //Pass in the string and the default color for this block of text. -LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, LLFontGL* font, F32 screen_width) +LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time) : mParagraphText(str), mAddTime(add_time), mMaxWidth(-1) { makeParagraphColorSegments(color); - updateLines( screen_width, font ); } -void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color) -{ - Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() ); - - mParagraphs.push_back ( paragraph ); - -#if LL_WINDOWS && LL_LCD_COMPILE - // add to LCD screen - AddNewDebugConsoleToLCD(wline); -#endif -} - -// -//check if there are some messages stored in the buffer -//if yes, output them. -// -void LLConsole::updateBuffer() -{ - BOOL need_clear = FALSE ; - - mMutex.lock() ; - if(!mLines.empty()) - { - S32 end = mLines.size() ; - LLColor4 color(1.f, 1.f, 1.f, 1.f) ; - for(S32 i = 0 ; i < end ; i++) - { - Paragraph paragraph(mLines[i], color, mAddTimes[i], mFont, (F32)getRect().getWidth() ); - mParagraphs.push_back ( paragraph ); - } - - need_clear = TRUE ; - } - mMutex.unlock() ; - - if(need_clear) - { - clear() ; - } -} diff --git a/linden/indra/newview/llconsole.h b/linden/indra/newview/llconsole.h index 2915c48b6..578670e33 100644 --- a/linden/indra/newview/llconsole.h +++ b/linden/indra/newview/llconsole.h @@ -33,7 +33,8 @@ #ifndef LL_LLCONSOLE_H #define LL_LLCONSOLE_H -#include "llfixedbuffer.h" +#include "llerrorcontrol.h" // For LLLineBuffer +#include "llthread.h" #include "llview.h" #include "v4color.h" #include <deque> @@ -47,10 +48,10 @@ class LLConsole : public LLFixedBuffer, public LLView F32 mLinePersistTime; // Age at which to stop drawing. F32 mFadeTime; // Age at which to start fading LLFontGL* mFont; - S32 mLastBoxHeight; - S32 mLastBoxWidth; S32 mConsoleWidth; S32 mConsoleHeight; + LLMutex mQueueMutex; + LLTimer mTimer; public: //A paragraph color segment defines the color of text in a line @@ -80,14 +81,7 @@ class LLConsole : public LLFixedBuffer, public LLView typedef std::list<LineColorSegment> line_color_segments_t; - //A line is composed of one or more color segments. - class Line - { - public: - line_color_segments_t mLineColorSegments; - }; - - typedef std::list<Line> lines_t; + typedef std::list<line_color_segments_t> lines_t; typedef std::list<ParagraphColorSegment> paragraph_color_segments_t; //A paragraph is a processed element containing the entire text of the @@ -98,7 +92,7 @@ class LLConsole : public LLFixedBuffer, public LLView class Paragraph { public: - Paragraph (LLWString str, const LLColor4 &color, F32 add_time, LLFontGL* font, F32 screen_width); + Paragraph (LLWString str, const LLColor4 &color, F32 add_time); void makeParagraphColorSegments ( const LLColor4 &color); void updateLines ( F32 screen_width, LLFontGL* font, bool force_resize=false ); public: @@ -111,35 +105,32 @@ class LLConsole : public LLFixedBuffer, public LLView }; //The console contains a deque of paragraphs which represent the individual messages. - typedef std::deque<Paragraph> paragraph_t; + typedef std::deque<Paragraph*> paragraph_t; paragraph_t mParagraphs; + paragraph_t mNewParagraphs; // Font size: // -1 = monospace, 0 means small, font size = 1 means big - LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect, - S32 font_size_index, F32 persist_time ); - ~LLConsole(){}; + LLConsole(const std::string& name, const LLRect &rect, + S32 font_size_index, F32 persist_time ); + ~LLConsole(); // each line lasts this long after being added - void setLinePersistTime(F32 seconds); + void setLinePersistTime(F32 seconds); - void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); // -1 = monospace, 0 means small, font size = 1 means big - void setFontSize(S32 size_index); + void setFontSize(S32 size_index); - void addLine(const std::string& utf8line, F32 size, const LLColor4 &color); - void addLine(const LLWString& wline, F32 size, const LLColor4 &color); + // From LLLineBuffer + /*virtual*/ void clear(); + /*virtual*/ void addLine(const std::string& utf8line); + void addConsoleLine(const std::string& utf8line, const LLColor4 &color); + void addConsoleLine(const LLWString& wline, const LLColor4 &color); // Overrides /*virtual*/ void draw(); - - //do not make these two "virtual" - void addLine(const std::string& utf8line); - void addLine(const LLWString& line); - -private: - void updateBuffer() ; }; extern LLConsole* gConsole; diff --git a/linden/indra/newview/lldebugview.cpp b/linden/indra/newview/lldebugview.cpp index 40f520206..a6d6f2dd0 100644 --- a/linden/indra/newview/lldebugview.cpp +++ b/linden/indra/newview/lldebugview.cpp @@ -62,7 +62,7 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect) LLRect r; r.set(10, rect.getHeight() - 100, rect.getWidth()/2, 100); - mDebugConsolep = new LLConsole("debug console", 20, r, -1, 0.f ); + mDebugConsolep = new LLConsole("debug console", r, -1, 0.f ); mDebugConsolep->setFollowsBottom(); mDebugConsolep->setFollowsLeft(); mDebugConsolep->setVisible( FALSE ); @@ -98,6 +98,27 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect) addChild(gTextureView); //gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE); +/* +//there seems to be some debug code, we don't have +#if !LL_RELEASE_FOR_DOWNLOAD + r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100); + gTextureSizeView = new LLTextureSizeView("gTextureSizeView"); + gTextureSizeView->setRect(r); + gTextureSizeView->setFollowsBottom(); + gTextureSizeView->setFollowsLeft(); + addChild(gTextureSizeView); + + + r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureMemByCategory.size() * 30, 100); + gTextureCategoryView = new LLTextureSizeView("gTextureCategoryView"); + gTextureCategoryView->setRect(r); + gTextureCategoryView->setFollowsBottom(); + gTextureCategoryView->setFollowsLeft(); + gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY); + addChild(gTextureCategoryView); +#endif +*/ + const S32 VELOCITY_LEFT = 10; // 370; const S32 VELOCITY_WIDTH = 500; const S32 VELOCITY_TOP = 140; @@ -115,5 +136,6 @@ LLDebugView::~LLDebugView() // These have already been deleted. Fix the globals appropriately. gDebugView = NULL; gTextureView = NULL; + gTextureSizeView = NULL; } diff --git a/linden/indra/newview/lldrawable.cpp b/linden/indra/newview/lldrawable.cpp index 14aa38aa2..99577e30a 100644 --- a/linden/indra/newview/lldrawable.cpp +++ b/linden/indra/newview/lldrawable.cpp @@ -102,7 +102,7 @@ void LLDrawable::init() mVObjp = NULL; // mFaces mSpatialGroupp = NULL; - mVisible = sCurVisible - 2;//invisible for the current frame and the last frame. + mVisible = 0; mRadius = 0.f; mGeneration = -1; @@ -125,7 +125,7 @@ void LLDrawable::destroy() if (LLSpatialGroup::sNoDelete) { - llerrs << "Illegal deletion of LLDrawable!" << llendl; + llwarns << "Illegal deletion of LLDrawable!" << llendl; } std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); @@ -234,7 +234,7 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) LLMemType mt(LLMemType::MTYPE_DRAWABLE); LLFace *face = new LLFace(this, mVObjp); - if (!face) llerrs << "Allocating new Face: " << mFaces.size() << llendl; + if (!face) llwarns << "Allocating new Face: " << mFaces.size() << llendl; if (face) { @@ -346,7 +346,7 @@ void LLDrawable::deleteFaces(S32 offset, S32 count) void LLDrawable::update() { - llerrs << "Shouldn't be called!" << llendl; + llwarns << "Shouldn't be called!" << llendl; } @@ -368,7 +368,7 @@ void LLDrawable::makeActive() pcode == LLViewerObject::LL_VO_GROUND || pcode == LLViewerObject::LL_VO_SKY) { - llerrs << "Static viewer object has active drawable!" << llendl; + llwarns << "Static viewer object has active drawable!" << llendl; } } #endif @@ -692,19 +692,22 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) pos += volume->getRegion()->getOriginAgent(); } - for (S32 i = 0; i < getNumFaces(); i++) + if (isState(LLDrawable::HAS_ALPHA)) { - LLFace* facep = getFace(i); - if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) + for (S32 i = 0; i < getNumFaces(); i++) { - LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; - LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); - LLVector3 at = camera.getAtAxis(); - for (U32 j = 0; j < 3; j++) + LLFace* facep = getFace(i); + if (facep->getPoolType() == LLDrawPool::POOL_ALPHA) { - v.mV[j] -= box.mV[j] * at.mV[j]; + LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; + LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); + const LLVector3& at = camera.getAtAxis(); + for (U32 j = 0; j < 3; j++) + { + v.mV[j] -= box.mV[j] * at.mV[j]; + } + facep->mDistance = v * camera.getAtAxis(); } - facep->mDistance = v * camera.getAtAxis(); } } } @@ -736,7 +739,11 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - if (isActive()) + if (!isActive()) + { + //gPipeline.markMoved(this); + } + else { if (isRoot()) { @@ -1003,8 +1010,8 @@ BOOL LLDrawable::isVisible() const // Spatial Partition Bridging Drawable //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask) -: LLSpatialPartition(data_mask, FALSE) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) // KL Sd version +: LLSpatialPartition(data_mask, render_by_group, FALSE) { mDrawable = root; root->setSpatialBridge(this); @@ -1134,26 +1141,26 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, { if (isActive() && !mParent->isActive()) { - llerrs << "Active drawable has static parent!" << llendl; + llwarns << "Active drawable has static parent!" << llendl; } if (isStatic() && !mParent->isStatic()) { - llerrs << "Static drawable has active parent!" << llendl; + llwarns << "Static drawable has active parent!" << llendl; } if (mSpatialBridge) { - llerrs << "Child drawable has spatial bridge!" << llendl; + llwarns << "Child drawable has spatial bridge!" << llendl; } } else if (isActive() && !mSpatialBridge) { - llerrs << "Active root drawable has no spatial bridge!" << llendl; + llwarns << "Active root drawable has no spatial bridge!" << llendl; } else if (isStatic() && mSpatialBridge.notNull()) { - llerrs << "Static drawable has spatial bridge!" << llendl; + llwarns << "Static drawable has spatial bridge!" << llendl; } } #endif @@ -1277,12 +1284,25 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) return; } - LLCamera camera = transformCamera(camera_in); + if (mDrawable->getVObj()) + { + if (mDrawable->getVObj()->isAttachment()) + { + LLDrawable* parent = mDrawable->getParent(); + if (parent && parent->getVObj()) + { + LLVOAvatar* av = parent->getVObj()->asAvatar(); + if (av && av->isImpostor()) + { + return; + } + } + } + + LLCamera camera = transformCamera(camera_in); mDrawable->updateDistance(camera, force_update); - if (mDrawable->getVObj()) - { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -1304,7 +1324,7 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) void LLSpatialBridge::makeActive() { //it is an error to make a spatial bridge active (it's already active) - llerrs << "makeActive called on spatial bridge" << llendl; + llwarns << "makeActive called on spatial bridge" << llendl; } void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) @@ -1420,9 +1440,9 @@ void LLDrawable::updateFaceSize(S32 idx) } LLBridgePartition::LLBridgePartition() -: LLSpatialPartition(0, TRUE) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; + //mRenderByGroup = FALSE; // KL mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; mLODPeriod = 16; diff --git a/linden/indra/newview/lldrawable.h b/linden/indra/newview/lldrawable.h index 71b75dc4c..e6753b56b 100644 --- a/linden/indra/newview/lldrawable.h +++ b/linden/indra/newview/lldrawable.h @@ -267,7 +267,8 @@ class LLDrawable : public LLRefCount BUILT = 0x08000000, FORCE_INVISIBLE = 0x10000000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) CLEAR_INVISIBLE = 0x20000000, // clear FORCE_INVISIBLE next draw frame - REBUILD_SHADOW = 0x40000000 + REBUILD_SHADOW = 0x40000000, + HAS_ALPHA = 0x80000000, } EDrawableFlags; LLXformMatrix mXform; diff --git a/linden/indra/newview/lldrawpool.h b/linden/indra/newview/lldrawpool.h index 87c3ccaff..905271034 100644 --- a/linden/indra/newview/lldrawpool.h +++ b/linden/indra/newview/lldrawpool.h @@ -67,6 +67,11 @@ class LLDrawPool POOL_GLOW, POOL_ALPHA, NUM_POOL_TYPES, + // * invisiprims work by rendering to the depth buffer but not the color buffer, occluding anything rendered after them + // - and the LLDrawPool types enum controls what order things are rendered in + // - so, it has absolute control over what invisprims block + // ...invisiprims being rendered in pool_invisible + // ...shiny/bump mapped objects in rendered in POOL_BUMP }; LLDrawPool(const U32 type); diff --git a/linden/indra/newview/lldrawpoolalpha.cpp b/linden/indra/newview/lldrawpoolalpha.cpp index 4b552acd5..c9c06f4f5 100644 --- a/linden/indra/newview/lldrawpoolalpha.cpp +++ b/linden/indra/newview/lldrawpoolalpha.cpp @@ -88,7 +88,12 @@ void LLDrawPoolAlpha::beginDeferredPass(S32 pass) void LLDrawPoolAlpha::endDeferredPass(S32 pass) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f); + +} + +void LLDrawPoolAlpha::renderDeferred(S32 pass) +{ + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); gDeferredTreeProgram.bind(); @@ -99,11 +104,6 @@ void LLDrawPoolAlpha::endDeferredPass(S32 pass) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } -void LLDrawPoolAlpha::renderDeferred(S32 pass) -{ - -} - S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { @@ -261,6 +261,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; + S32 diffuse_channel = 0; + //BOOL is_particle = FALSE; BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) || gPipeline.canUseWindLightShadersOnObjects(); @@ -291,19 +293,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) LLRenderPass::applyModelMatrix(params); - if (params.mTexture.notNull()) - { - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(params.mTexture.get()); - - if (params.mTextureMatrix) - { - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - } - if (params.mFullbright) { // Turn off lighting if it hasn't already been so. @@ -344,11 +333,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; } current_shader = target_shader; if (deferred_render) { gPipeline.bindDeferredShader(*current_shader); + diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } else { @@ -357,11 +348,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } else if (!use_shaders && current_shader != NULL) { - LLGLSLShader::bindNoShader(); if (deferred_render) { gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; } + LLGLSLShader::bindNoShader(); current_shader = NULL; } @@ -369,6 +361,24 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { params.mGroup->rebuildMesh(); } + + + if (params.mTexture.notNull()) + { + gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get(), TRUE, TRUE); + if(params.mViewerTexture.notNull()) + { + params.mViewerTexture->addTextureStats(params.mVSize); + } + if (params.mTextureMatrix) + { + gGL.getTexUnit(0)->activate(); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } + params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); @@ -383,6 +393,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } + if (deferred_render && current_shader != NULL) + { + gPipeline.unbindDeferredShader(*current_shader); + LLVertexBuffer::unbind(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + } + if (!light_enabled) { gPipeline.enableLightsDynamic(); diff --git a/linden/indra/newview/lldrawpoolavatar.cpp b/linden/indra/newview/lldrawpoolavatar.cpp index 80c7d73e6..af7b5e386 100644 --- a/linden/indra/newview/lldrawpoolavatar.cpp +++ b/linden/indra/newview/lldrawpoolavatar.cpp @@ -94,6 +94,7 @@ BOOL gAvatarEmbossBumpMap = FALSE; static BOOL sRenderingSkinned = FALSE; S32 normal_channel = -1; S32 specular_channel = -1; +S32 diffuse_channel = -1; LLDrawPoolAvatar::LLDrawPoolAvatar() : LLFacePool(POOL_AVATAR) @@ -447,7 +448,8 @@ void LLDrawPoolAvatar::beginDeferredImpostor() normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); - + diffuse_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); // KL SD + sVertexProgram->bind(); } @@ -456,6 +458,7 @@ void LLDrawPoolAvatar::endDeferredImpostor() sShaderLevel = mVertexShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); + sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); // KL SD sVertexProgram->unbind(); gGL.getTexUnit(0)->activate(); } @@ -699,7 +702,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) avatarp->mImpostor.bindTexture(1, specular_channel); } } - avatarp->renderImpostor(); + // avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel); // KL SD + avatarp->renderImpostor(); } else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred) { @@ -752,6 +756,67 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if( !single_avatar || (avatarp == single_avatar) ) { + if (LLVOAvatar::sShowCollisionVolumes) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + avatarp->renderCollisionVolumes(); + } + + if (avatarp->isSelf() && LLAgent::sDebugDisplayTarget) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLVector3 pos = avatarp->getPositionAgent(); + + gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + pos = avatarp->mDrawable->getPositionAgent(); + gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + pos = avatarp->mRoot.getWorldPosition(); + gGL.color4f(1.0f, 1.0f, 1.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + pos = avatarp->mPelvisp->getWorldPosition(); + gGL.color4f(0.0f, 0.0f, 1.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + color.setColor(1.0f, 1.0f, 1.0f, 1.0f); + } + avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } } diff --git a/linden/indra/newview/lldrawpoolbump.cpp b/linden/indra/newview/lldrawpoolbump.cpp index fb7a21376..dcaa7420a 100644 --- a/linden/indra/newview/lldrawpoolbump.cpp +++ b/linden/indra/newview/lldrawpoolbump.cpp @@ -140,7 +140,7 @@ void LLStandardBumpmap::restoreGL() return; } - llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; +// llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = gImageList.getImageFromFile(bump_file, @@ -309,8 +309,8 @@ void LLDrawPoolBump::endRenderPass(S32 pass) void LLDrawPoolBump::beginShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { return; } @@ -384,8 +384,8 @@ void LLDrawPoolBump::beginShiny(bool invisible) void LLDrawPoolBump::renderShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { return; } @@ -411,8 +411,8 @@ void LLDrawPoolBump::renderShiny(bool invisible) void LLDrawPoolBump::endShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { return; } @@ -572,7 +572,11 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) LLImageGL* bump = NULL; U8 bump_code = params.mBump; - LLViewerImage* tex = params.mTexture; + LLViewerImage* tex = params.mViewerTexture; + if(!tex) + { + return FALSE ; + } switch( bump_code ) { @@ -1226,7 +1230,10 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) if (params.mTexture.notNull()) { gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); - //params.mTexture->addTextureStats(params.mVSize); + if(params.mViewerTexture.notNull()) + { + params.mViewerTexture->addTextureStats(params.mVSize); + } } else { diff --git a/linden/indra/newview/lldrawpoolsky.cpp b/linden/indra/newview/lldrawpoolsky.cpp index f0ed38057..7f21adcc9 100644 --- a/linden/indra/newview/lldrawpoolsky.cpp +++ b/linden/indra/newview/lldrawpoolsky.cpp @@ -61,8 +61,8 @@ LLDrawPool *LLDrawPoolSky::instancePool() void LLDrawPoolSky::prerender() { - mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); - gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); + mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); +// gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); } void LLDrawPoolSky::render(S32 pass) @@ -97,6 +97,7 @@ void LLDrawPoolSky::render(S32 pass) } + LLVOSky *voskyp = gSky.mVOSkyp; LLGLSPipelineSkyBox gls_skybox; LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -119,9 +120,43 @@ void LLDrawPoolSky::render(S32 pass) { renderSkyCubeFace(i); } + + LLFace *hbfaces[3]; + hbfaces[0] = NULL; + hbfaces[1] = NULL; + hbfaces[2] = NULL; + for (S32 curr_face = 0; curr_face < face_count; curr_face++) + { + LLFace* facep = mDrawFace[curr_face]; + if (voskyp->isSameFace(LLVOSky::FACE_SUN, facep)) + { + hbfaces[0] = facep; + } + if (voskyp->isSameFace(LLVOSky::FACE_MOON, facep)) + { + hbfaces[1] = facep; + } + if (voskyp->isSameFace(LLVOSky::FACE_BLOOM, facep)) + { + hbfaces[2] = facep; + } + } LLGLEnable blend(GL_BLEND); + if (hbfaces[2]) + { + // renderSunHalo(hbfaces[2]); + } + if (hbfaces[0]) + { + // renderHeavenlyBody(0, hbfaces[0]); + } + if (hbfaces[1]) + { + // renderHeavenlyBody(1, hbfaces[1]); + } + glPopMatrix(); } @@ -146,6 +181,35 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side) } } +void LLDrawPoolSky::renderHeavenlyBody(U8 hb, LLFace* face) +{ + if ( !mHB[hb]->getDraw() ) return; + if (! face->getGeomCount()) return; + + LLImageGL* tex = face->getTexture(); + gGL.getTexUnit(0)->bind(tex); + LLColor4 color(mHB[hb]->getInterpColor()); + LLOverrideFaceColor override(this, color); + face->renderIndexed(); +} + + + +void LLDrawPoolSky::renderSunHalo(LLFace* face) +{ + if (! mHB[0]->getDraw()) return; + if (! face->getGeomCount()) return; + + LLImageGL* tex = face->getTexture(); + gGL.getTexUnit(0)->bind(tex); + LLColor4 color(mHB[0]->getInterpColor()); + color.mV[3] = llclamp(mHB[0]->getHaloBrighness(), 0.f, 1.f); + + LLOverrideFaceColor override(this, color); + face->renderIndexed(); +} + + void LLDrawPoolSky::renderForSelect() { } diff --git a/linden/indra/newview/lldrawpoolsky.h b/linden/indra/newview/lldrawpoolsky.h index 8595d73ae..f35b11473 100644 --- a/linden/indra/newview/lldrawpoolsky.h +++ b/linden/indra/newview/lldrawpoolsky.h @@ -36,12 +36,14 @@ #include "lldrawpool.h" class LLSkyTex; +class LLHeavenBody; class LLGLSLShader; class LLDrawPoolSky : public LLFacePool { private: LLSkyTex *mSkyTex; + LLHeavenBody *mHB[2]; // Sun and Moon LLGLSLShader *mShader; public: @@ -67,6 +69,8 @@ class LLDrawPoolSky : public LLFacePool /*virtual*/ void renderForSelect(); /*virtual*/ void endRenderPass(S32 pass); void setSkyTex(LLSkyTex* const st) { mSkyTex = st; } + void setSun(LLHeavenBody* sun_flag) { mHB[0] = sun_flag; } + void setMoon(LLHeavenBody* moon) { mHB[1] = moon; } void renderSkyCubeFace(U8 side); void renderHeavenlyBody(U8 hb, LLFace* face); diff --git a/linden/indra/newview/lldrawpoolterrain.cpp b/linden/indra/newview/lldrawpoolterrain.cpp index cac5162bc..3ee955a8c 100644 --- a/linden/indra/newview/lldrawpoolterrain.cpp +++ b/linden/indra/newview/lldrawpoolterrain.cpp @@ -73,19 +73,19 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) : TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); - gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); + //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c", TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_TERRAIN); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } LLDrawPoolTerrain::~LLDrawPoolTerrain() diff --git a/linden/indra/newview/lldrawpooltree.cpp b/linden/indra/newview/lldrawpooltree.cpp index 46cd2d5c4..873f0f623 100644 --- a/linden/indra/newview/lldrawpooltree.cpp +++ b/linden/indra/newview/lldrawpooltree.cpp @@ -52,7 +52,7 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) : LLFacePool(POOL_TREE), mTexturep(texturep) { - gGL.getTexUnit(0)->bind(mTexturep.get()); +// gGL.getTexUnit(0)->bind(mTexturep.get()); mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); } @@ -108,7 +108,7 @@ void LLDrawPoolTree::render(S32 pass) } else { - gGL.getTexUnit(sDiffTex)->bind(mTexturep); + gGL.getTexUnit(sDiffTex)->bind(mTexturep, TRUE); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) @@ -138,7 +138,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass) void LLDrawPoolTree::beginDeferredPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); // KL Render-pipeline has this set at 0.f ... NOOOOOO! make shitty trees :) shader = &gDeferredTreeProgram; shader->bind(); @@ -164,6 +164,9 @@ void LLDrawPoolTree::beginShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), + gSavedSettings.getF32("RenderDeferredTreeShadowBias")); + gDeferredShadowProgram.bind(); } @@ -176,7 +179,11 @@ void LLDrawPoolTree::endShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - gDeferredShadowProgram.unbind(); + + glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"), + gSavedSettings.getF32("RenderDeferredSpotShadowBias")); + + //gDeferredShadowProgram.unbind(); } diff --git a/linden/indra/newview/lldrawpoolwater.cpp b/linden/indra/newview/lldrawpoolwater.cpp index ce3425dd9..5c0363e3a 100644 --- a/linden/indra/newview/lldrawpoolwater.cpp +++ b/linden/indra/newview/lldrawpoolwater.cpp @@ -98,7 +98,7 @@ void LLDrawPoolWater::restoreGL() LLDrawPool *LLDrawPoolWater::instancePool() { - llerrs << "Should never be calling instancePool on a water pool!" << llendl; + llwarns << "Should never be calling instancePool on a water pool!" << llendl; return NULL; } @@ -401,6 +401,15 @@ void LLDrawPoolWater::shade() shader = &gWaterProgram; } + if (deferred_render) + { + gPipeline.bindDeferredShader(*shader); + } + else + { + shader->bind(); + } + sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); @@ -436,15 +445,6 @@ void LLDrawPoolWater::shade() S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); - if (deferred_render) - { - gPipeline.bindDeferredShader(*shader); - } - else - { - shader->bind(); - } - if (screentex > -1) { shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); diff --git a/linden/indra/newview/lldynamictexture.cpp b/linden/indra/newview/lldynamictexture.cpp index 61f5a8905..e219d4bc4 100644 --- a/linden/indra/newview/lldynamictexture.cpp +++ b/linden/indra/newview/lldynamictexture.cpp @@ -41,6 +41,7 @@ #include "llvertexbuffer.h" #include "llviewerdisplay.h" #include "llrender.h" +#include "pipeline.h" // static LLDynamicTexture::instance_list_t LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ]; @@ -58,9 +59,14 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder mClamp(clamp) { llassert((1 <= components) && (components <= 4)); - - generateGLTexture(); - + if(!LLPipeline::sRenderDeferred) + { + generateGLTexture(); + } + else + { + gPipeline.markGLRebuild(this); // KL SD well for this to work its either gotta be one or the other so lets slap in the if/else can't do any harm. + } llassert( 0 <= order && order < ORDER_COUNT ); LLDynamicTexture::sInstances[ order ].insert(this); } @@ -77,6 +83,11 @@ LLDynamicTexture::~LLDynamicTexture() } } +void LLDynamicTexture::updateGL() +{ + generateGLTexture(); +} + //----------------------------------------------------------------------------- // releaseGLTexture() //----------------------------------------------------------------------------- @@ -101,7 +112,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima { if (mComponents < 1 || mComponents > 4) { - llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl; + llwarns << "Bad number of components in dynamic texture: " << mComponents << llendl; } releaseGLTexture(); LLPointer<LLImageRaw> raw_image = new LLImageRaw(mWidth, mHeight, mComponents); @@ -111,7 +122,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); } // llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; - mTexture->createGLTexture(0, raw_image, 0, TRUE, LLViewerImageBoostLevel::DYNAMIC_TEX); + mTexture->createGLTexture(0, raw_image); mTexture->setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); mTexture->setGLTextureCreated(false); } diff --git a/linden/indra/newview/lldynamictexture.h b/linden/indra/newview/lldynamictexture.h index 5a20eaef9..14807991b 100644 --- a/linden/indra/newview/lldynamictexture.h +++ b/linden/indra/newview/lldynamictexture.h @@ -37,7 +37,7 @@ #include "llcoord.h" #include "llimagegl.h" -class LLDynamicTexture +class LLDynamicTexture : public LLGLUpdate { public: enum EOrder { ORDER_FIRST = 0, ORDER_MIDDLE = 1, ORDER_LAST = 2, ORDER_RESET = 3, ORDER_COUNT = 4 }; @@ -49,6 +49,8 @@ class LLDynamicTexture BOOL clamp); virtual ~LLDynamicTexture(); + void updateGL(); + S32 getOriginX() { return mOrigin.mX; } S32 getOriginY() { return mOrigin.mY; } S32 getWidth() { return mWidth; } diff --git a/linden/indra/newview/llface.cpp b/linden/indra/newview/llface.cpp index aa8cd15dd..ae57a3c2c 100644 --- a/linden/indra/newview/llface.cpp +++ b/linden/indra/newview/llface.cpp @@ -176,8 +176,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mLastIndicesCount = mIndicesCount; mLastIndicesIndex = mIndicesIndex; - mImportanceToCamera = 0.f ; - mBoundingSphereRadius = 0.0f ; + mAtlasInfop = NULL ; + mUsingAtlas = FALSE ; } @@ -205,12 +205,14 @@ void LLFace::destroy() if (group) { group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); } } } setDrawInfo(NULL); + removeAtlas(); mDrawablep = NULL; mVObjp = NULL; } @@ -223,7 +225,7 @@ void LLFace::initClass() void LLFace::setWorldMatrix(const LLMatrix4 &mat) { - llerrs << "Faces on this drawable are not independently modifiable\n" << llendl; + llwarns << "Faces on this drawable are not independently modifiable\n" << llendl; } void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) @@ -232,7 +234,7 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) if (!new_pool) { - llerrs << "Setting pool to null!" << llendl; + llwarns << "Setting pool to null!" << llendl; } if (new_pool != mDrawPoolp) @@ -270,6 +272,7 @@ void LLFace::setTexture(LLViewerImage* tex) if(mTexture.notNull()) { mTexture->removeFace(this) ; + removeAtlas() ; } mTexture = tex ; @@ -453,8 +456,15 @@ void LLFace::renderForSelect(U32 data_mask) void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) { - if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL || - mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY)) + if (mDrawablep->getSpatialGroup() == NULL) + { + return; + } + + mDrawablep->getSpatialGroup()->rebuildGeom(); + mDrawablep->getSpatialGroup()->rebuildMesh(); + + if(mDrawablep.isNull() || mVertexBuffer.isNull()) { return; } @@ -473,17 +483,10 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); } - setFaceColor(color); - renderSetColor(); - + glColor4fv(color.mV); mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays("", LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); -#endif mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); - unsetFaceColor(); - unsetFaceColor(); gGL.popMatrix(); } } @@ -727,8 +730,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, } mCenterLocal = (newMin+newMax)*0.5f; - LLVector3 tmp = (newMin - newMax) ; - mBoundingSphereRadius = tmp.length() * 0.5f ; + // LLVector3 tmp = (newMin - newMax) ; + // mBoundingSphereRadius = tmp.length() * 0.5f ; updateCenterAgent(); } @@ -963,6 +966,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getBinormalStrider(binormals, mGeomIndex); } + F32 tcoord_xoffset = 0.f ; + F32 tcoord_yoffset = 0.f ; + F32 tcoord_xscale = 1.f ; + F32 tcoord_yscale = 1.f ; + BOOL in_atlas = FALSE ; + if (rebuild_tcoord) { mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex); @@ -970,6 +979,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex); } + + in_atlas = isAtlasInUse() ; + if(in_atlas) + { + const LLVector2* tmp = getTexCoordOffset() ; + tcoord_xoffset = tmp->mV[0] ; + tcoord_yoffset = tmp->mV[1] ; + + tmp = getTexCoordScale() ; + tcoord_xscale = tmp->mV[0] ; + tcoord_yscale = tmp->mV[1] ; + } } if (rebuild_color) { @@ -1057,7 +1078,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 0.75f }; - if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) + if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || LLPipeline::sRenderBump && tep->getShiny())) { color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } @@ -1179,6 +1200,93 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, xform(tc, cos_ang, sin_ang, os, ot, ms, mt); } + if(in_atlas) + { + // + //manually calculate tex-coord per vertex for varying address modes. + //should be removed if shader can handle this. + // + + S32 int_part = 0 ; + switch(mTexture->getAddressMode()) + { + case LLTexUnit::TAM_CLAMP: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 0.f ; + } + else if(tc.mV[0] > 1.f) + { + tc.mV[0] = 1.f; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 0.f ; + } + else if(tc.mV[1] > 1.f) + { + tc.mV[1] = 1.f; + } + break; + case LLTexUnit::TAM_MIRROR: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = -tc.mV[0] ; + } + int_part = (S32)tc.mV[0] ; + if(int_part & 1) //odd number + { + tc.mV[0] = int_part + 1 - tc.mV[0] ; + } + else //even number + { + tc.mV[0] -= int_part ; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = -tc.mV[1] ; + } + int_part = (S32)tc.mV[1] ; + if(int_part & 1) //odd number + { + tc.mV[1] = int_part + 1 - tc.mV[1] ; + } + else //even number + { + tc.mV[1] -= int_part ; + } + break; + case LLTexUnit::TAM_WRAP: + if(tc.mV[0] > 1.f) + tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; + else if(tc.mV[0] < -1.f) + tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; + + if(tc.mV[1] > 1.f) + tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; + else if(tc.mV[1] < -1.f) + tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; + + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 1.0f + tc.mV[0] ; + } + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 1.0f + tc.mV[1] ; + } + break; + default: + break; + } + + tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; + tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; + } + + *tex_coords++ = tc; if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) @@ -1245,159 +1353,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, return TRUE; } -const F32 LEAST_IMPORTANCE = 0.05f ; -const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; - -F32 LLFace::getTextureVirtualSize() -{ - F32 radius; - F32 cos_angle_to_view_dir; - mPixelArea = calcPixelArea(cos_angle_to_view_dir, radius); - - if (mPixelArea <= 0) - { - return 0.f; - } - - //get area of circle in texture space - LLVector2 tdim = mTexExtents[1] - mTexExtents[0]; - F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; - if (texel_area <= 0) - { - // Probably animated, use default - texel_area = 1.f; - } - - F32 face_area; - if (mVObjp->isSculpted() && texel_area > 1.f) - { - //sculpts can break assumptions about texel area - face_area = mPixelArea; - } - else - { - //apply texel area to face area to get accurate ratio - //face_area /= llclamp(texel_area, 1.f/64.f, 16.f); - face_area = mPixelArea / llclamp(texel_area, 0.015625f, 1024.f); - } - - if(face_area > LLViewerImage::sMaxSmallImageSize) - { - if(mImportanceToCamera < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res. - { - face_area = LLViewerImage::sMaxSmallImageSize ; - } - else if(face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. - { - if(mImportanceToCamera < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res. - { - face_area = LLViewerImage::sMinLargeImageSize ; - } - else if(mTexture.notNull() && mTexture->isLargeImage()) - { - face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius ); - } - } - } - - return face_area; -} - -F32 LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) -{ - //get area of circle around face - LLVector3 center = getPositionAgent(); - LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f; - - LLVector3 lookAt = center - LLViewerCamera::getInstance()->getOrigin(); - F32 dist = lookAt.normVec() ; - - //get area of circle around node - F32 app_angle = atanf(size.length()/dist); - radius = app_angle*LLDrawable::sCurPixelAngle; - F32 face_area = radius*radius * 3.14159f; - - if(dist < mBoundingSphereRadius) //camera is very close - { - cos_angle_to_view_dir = 1.0f ; - mImportanceToCamera = 1.0f ; - } - else - { - cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; - mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ; - } - - return face_area ; -} - -//the projection of the face partially overlaps with the screen -F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ) -{ - F32 screen_radius = (F32)llmax(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()) ; - F32 center_angle = acosf(cos_angle_to_view_dir) ; - F32 d = center_angle * LLDrawable::sCurPixelAngle ; - - if(d + radius > screen_radius + 5.f) - { - //---------------------------------------------- - //calculate the intersection area of two circles - //F32 radius_square = radius * radius ; - //F32 d_square = d * d ; - //F32 screen_radius_square = screen_radius * screen_radius ; - //face_area = - // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) + - // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) - - // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ; - //---------------------------------------------- - - //the above calculation is too expensive - //the below is a good estimation: bounding box of the bounding sphere: - F32 alpha = 0.5f * (radius + screen_radius - d) / radius ; - alpha = llclamp(alpha, 0.f, 1.f) ; - return alpha * alpha ; - } - return 1.0f ; -} - -const S8 FACE_IMPORTANCE_LEVEL = 4 ; -const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight} - {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ; -const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] = //{cos(angle), importance_weight} - {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ; - -//static -F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) -{ - F32 importance = 0.f ; - - if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && - dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) - { - F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; - F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); - - if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f) - { - //if camera moves or rotates too fast, ignore the importance factor - return 0.f ; - } - - //F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ; - - S32 i = 0 ; - for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i); - i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; - F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ; - - for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ; - i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; - importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ; - } - - return importance ; -} - BOOL LLFace::verify(const U32* indices_array) const { BOOL ok = TRUE; @@ -1586,3 +1541,153 @@ LLVector3 LLFace::getPositionAgent() const return mCenterLocal * getRenderMatrix(); } } + +// +//atlas +// +void LLFace::removeAtlas() +{ + setAtlasInUse(FALSE) ; + mAtlasInfop = NULL ; +} + +const LLTextureAtlas* LLFace::getAtlas()const +{ + if(mAtlasInfop) + { + return mAtlasInfop->getAtlas() ; + } + return NULL ; +} + +const LLVector2* LLFace::getTexCoordOffset()const +{ + if(isAtlasInUse()) + { + return mAtlasInfop->getTexCoordOffset() ; + } + return NULL ; +} +const LLVector2* LLFace::getTexCoordScale() const +{ + if(isAtlasInUse()) + { + return mAtlasInfop->getTexCoordScale() ; + } + return NULL ; +} + +BOOL LLFace::isAtlasInUse()const +{ + return mUsingAtlas ; +} + +BOOL LLFace::canUseAtlas()const +{ + //no drawable or no spatial group, do not use atlas + if(!mDrawablep || !mDrawablep->getSpatialGroup()) + { + return FALSE ; + } + + //if bump face, do not use atlas + if(getTextureEntry() && getTextureEntry()->getBumpmap()) + { + return FALSE ; + } + + //if animated texture, do not use atlas + if(isState(TEXTURE_ANIM)) + { + return FALSE ; + } + + return TRUE ; +} + +void LLFace::setAtlasInUse(BOOL flag) +{ + //no valid atlas to use. + if(flag && (!mAtlasInfop || !mAtlasInfop->isValid())) + { + flag = FALSE ; + } + + if(!flag && !mUsingAtlas) + { + return ; + } + + // + //at this stage (flag || mUsingAtlas) is always true. + // + + //rebuild the tex coords + if(mDrawablep) + { + gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD); + mUsingAtlas = flag ; + } + else + { + mUsingAtlas = FALSE ; + } +} + +LLTextureAtlasSlot* LLFace::getAtlasInfo() +{ + return mAtlasInfop ; +} + +void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp) +{ + if(mAtlasInfop != atlasp) + { + if(mAtlasInfop) + { + //llwarns << "Atlas slot changed!" << llendl ; + } + mAtlasInfop = atlasp ; + } +} + +LLImageGL* LLFace::getGLTexture() const +{ + if(isAtlasInUse()) + { + return (LLImageGL*)mAtlasInfop->getAtlas() ; + } + + return (LLImageGL*)mTexture ; +} + +//switch to atlas or switch back to gl texture +//return TRUE if using atlas. +BOOL LLFace::switchTexture() +{ + //no valid atlas or texture + if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture) + { + return FALSE ; + } + + if(mTexture->getTexelsInAtlas() >= (U32)mVSize || mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture()) + { + //switch to use atlas + //atlas resolution is qualified, use it. + if(!mUsingAtlas) + { + setAtlasInUse(TRUE) ; + } + } + else //if atlas not qualified. + { + //switch back to GL texture + if(mUsingAtlas && mTexture->isGLTextureCreated() && mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas()) + { + setAtlasInUse(FALSE) ; + } + } + + return mUsingAtlas ; +} diff --git a/linden/indra/newview/llface.h b/linden/indra/newview/llface.h index 4893e825d..9f76d6b91 100644 --- a/linden/indra/newview/llface.h +++ b/linden/indra/newview/llface.h @@ -48,6 +48,7 @@ #include "llviewerimage.h" #include "llstat.h" #include "lldrawable.h" +#include "lltextureatlasmanager.h" class LLFacePool; class LLVolume; @@ -56,6 +57,7 @@ class LLTextureEntry; class LLVertexProgram; class LLViewerImage; class LLGeometryManager; +class LLTextureAtlasSlot; const F32 MIN_ALPHA_SIZE = 1024.f; const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -189,14 +191,18 @@ class LLFace void setIndicesIndex(S32 idx) { mIndicesIndex = idx; } void setDrawInfo(LLDrawInfo* draw_info); - F32 getTextureVirtualSize() ; - F32 getImportanceToCamera()const {return mImportanceToCamera ;} - -private: - F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ); - F32 calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ; -public: - static F32 calcImportanceToCamera(F32 to_view_dir, F32 dist); + // KL was atlas S19 + LLImageGL* getGLTexture() const; + LLTextureAtlasSlot* getAtlasInfo() ; + void setAtlasInUse(BOOL flag); + void setAtlasInfo(LLTextureAtlasSlot* atlasp); + BOOL isAtlasInUse()const; + BOOL canUseAtlas() const; + const LLVector2* getTexCoordScale() const ; + const LLVector2* getTexCoordOffset()const; + const LLTextureAtlas* getAtlas()const ; + void removeAtlas() ; + BOOL switchTexture() ; public: @@ -212,7 +218,7 @@ class LLFace LLMatrix4* mTextureMatrix; LLDrawInfo* mDrawInfo; -private: +protected: friend class LLGeometryManager; friend class LLVolumeGeometryManager; @@ -242,12 +248,10 @@ class LLFace F32 mVSize; F32 mPixelArea; - //importance factor, in the range [0, 1.0]. - //1.0: the most important. - //based on the distance from the face to the view point and the angle from the face center to the view direction. - F32 mImportanceToCamera ; - F32 mBoundingSphereRadius ; - + //atlas + LLPointer<LLTextureAtlasSlot> mAtlasInfop ; + BOOL mUsingAtlas ; + protected: static BOOL sSafeRenderSelect; @@ -275,9 +279,9 @@ class LLFace const LLTextureEntry* lte = lhs->getTextureEntry(); const LLTextureEntry* rte = rhs->getTextureEntry(); - if (lhs->getTexture() != rhs->getTexture()) + if(lhs->getGLTexture() != rhs->getGLTexture()) // KL SD get GL { - return lhs->getTexture() < rhs->getTexture(); + return lhs->getGLTexture() < rhs->getGLTexture(); // not getTexture? } else if (lte->getBumpShinyFullbright() != rte->getBumpShinyFullbright()) { diff --git a/linden/indra/newview/llfloaterassetbrowser.cpp b/linden/indra/newview/llfloaterassetbrowser.cpp index af81c4a68..9b4139066 100644 --- a/linden/indra/newview/llfloaterassetbrowser.cpp +++ b/linden/indra/newview/llfloaterassetbrowser.cpp @@ -63,7 +63,7 @@ LLFloaterAssetBrowser::~LLFloaterAssetBrowser() mTextureAssets.clear(); mMaxIndex = 0; mFirstIndex = 0; - mMouseOverIndex = 0; + mMouseOverIndex = NULL; mMouseOverUUID = LLUUID::null; mMouseOverAssetUUID = LLUUID::null; mFloaterTitle = ""; @@ -79,7 +79,7 @@ void LLFloaterAssetBrowser::initialize() mAssetInfoIndex = 0; mFloaterHeight = getRect().getHeight(); mFloaterWidth = getRect().getWidth(); - mMouseOverIndex = 0; + mMouseOverIndex = NULL; mMouseOverUUID = LLUUID::null; mMouseOverAssetUUID = LLUUID::null; mFloaterTitle = ""; @@ -122,7 +122,7 @@ void LLFloaterAssetBrowser::createThumbnails() temp.mUUID = itemp->getUUID(); temp.mName = itemp->getName(); temp.mTexturep = NULL; - temp.mAssetRect = LLRect::null; + temp.mAssetRect = NULL; mTextureAssets.push_back(temp); } @@ -131,14 +131,14 @@ void LLFloaterAssetBrowser::createThumbnails() { mTextureAssets[i].mTexturep = gImageList.getImage(mTextureAssets[i].mAssetUUID, MIPMAP_YES, IMMEDIATE_NO); mTextureAssets[i].mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); - //mTextureAssets[i].mTexturep->processTextureStats(); + mTextureAssets[i].mTexturep->processTextureStats(); } //Generate the asset info text - /*for(S32 i = 0; i < items.count(); i++) + for(S32 i = 0; i < items.count(); i++) { - LLString asset_info; - LLString dimensions; + std::string asset_info; + std::string dimensions; asset_info.append(mTextureAssets[i].mName); @@ -151,7 +151,7 @@ void LLFloaterAssetBrowser::createThumbnails() asset_info.append(dimensions); mTextureAssets[i].mAssetInfo = asset_info; - }*/ + } mFloaterTitle = llformat("Asset Browser (%d assets fetched)", mTextureAssets.size()); setTitle(mFloaterTitle); @@ -288,7 +288,7 @@ void LLFloaterAssetBrowser::draw() if(mImageAssetID.notNull()) { mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); - //mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); mTexturep->processTextureStats(); mTextureAssets[i].mWidth = mTexturep->mFullWidth; mTextureAssets[i].mHeight = mTexturep->mFullHeight; diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index 2daa5aa4b..5f43406e4 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp @@ -582,7 +582,8 @@ void LLFloaterChat::addChat(const LLChat& chat, // We display anything if it's not an IM. If it's an IM, check pref... if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatConsole") ) { - gConsole->addLine(chat.mText, size, text_color); + gConsole->addConsoleLine(chat.mText, text_color); + } } diff --git a/linden/indra/newview/llfloaterhardwaresettings.cpp b/linden/indra/newview/llfloaterhardwaresettings.cpp index 7886e394a..8c91f5a50 100644 --- a/linden/indra/newview/llfloaterhardwaresettings.cpp +++ b/linden/indra/newview/llfloaterhardwaresettings.cpp @@ -68,6 +68,7 @@ void LLFloaterHardwareSettings::onClickHelp(void* data) void LLFloaterHardwareSettings::initCallbacks(void) { + childSetCommitCallback("fbo", refreshState); } // menu maintenance functions @@ -83,7 +84,8 @@ void LLFloaterHardwareSettings::refresh() mVideoCardMem = gSavedSettings.getS32("TextureMemory"); mFogRatio = gSavedSettings.getF32("RenderFogRatio"); mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); - + mRenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); + mRenderUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); childSetValue("fsaa", (LLSD::Integer) mFSAASamples); refreshEnabledState(); } @@ -101,6 +103,20 @@ void LLFloaterHardwareSettings::refreshEnabledState() childSetEnabled("vbo", FALSE); } + if (!gGLManager.mHasFramebufferObject) + { + childSetEnabled("fbo", FALSE); + } + + if (!gGLManager.mHasDrawBuffers || !gSavedSettings.getBOOL("RenderUseFBO")) + { + childSetEnabled("deferred", FALSE); + } + else + { + childSetEnabled("deferred", TRUE); + } + // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance childSetEnabled("gamma", !gPipeline.canUseWindLightShaders()); childSetEnabled("(brightness, lower is brighter)", !gPipeline.canUseWindLightShaders()); @@ -108,6 +124,12 @@ void LLFloaterHardwareSettings::refreshEnabledState() } +//static +void LLFloaterHardwareSettings::refreshState(LLUICtrl*, void*) +{ + LLFloaterHardwareSettings::instance()->refreshEnabledState(); +} + // static instance of it LLFloaterHardwareSettings* LLFloaterHardwareSettings::instance() { @@ -202,7 +224,8 @@ void LLFloaterHardwareSettings::cancel() gSavedSettings.setS32("TextureMemory", mVideoCardMem); gSavedSettings.setF32("RenderFogRatio", mFogRatio); gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); - + gSavedSettings.setBOOL("RenderUseFBO", mRenderUseFBO); + gSavedSettings.setBOOL("RenderDeferred", mRenderDeferred); close(); } diff --git a/linden/indra/newview/llfloaterhardwaresettings.h b/linden/indra/newview/llfloaterhardwaresettings.h index 04a33f69d..e564e1c10 100644 --- a/linden/indra/newview/llfloaterhardwaresettings.h +++ b/linden/indra/newview/llfloaterhardwaresettings.h @@ -61,6 +61,8 @@ class LLFloaterHardwareSettings : public LLFloater /// OK button static void onBtnOK( void* userdata ); + static void refreshState(LLUICtrl*, void*); + //// menu management /// show off our menu @@ -88,6 +90,8 @@ class LLFloaterHardwareSettings : public LLFloater LLSliderCtrl* mCtrlVideoCardMem; BOOL mUseVBO; + BOOL mRenderUseFBO; + BOOL mRenderDeferred; BOOL mUseAniso; U32 mFSAASamples; F32 mGamma; diff --git a/linden/indra/newview/llfloaterlagmeter.cpp b/linden/indra/newview/llfloaterlagmeter.cpp index 8fe455fde..2ae2e32a0 100644 --- a/linden/indra/newview/llfloaterlagmeter.cpp +++ b/linden/indra/newview/llfloaterlagmeter.cpp @@ -180,7 +180,7 @@ void LLFloaterLagMeter::determineClient() { mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); } - else if((BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes)) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) + else if((LLViewerImage::sBoundTextureMemoryInBytes >> 20) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) { mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); } diff --git a/linden/indra/newview/llfloaterpostprocess.cpp b/linden/indra/newview/llfloaterpostprocess.cpp index de9b598b1..c5b2018ec 100644 --- a/linden/indra/newview/llfloaterpostprocess.cpp +++ b/linden/indra/newview/llfloaterpostprocess.cpp @@ -52,28 +52,29 @@ LLFloaterPostProcess::LLFloaterPostProcess() : LLFloater(std::string("Post-Proce LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml"); /// Color Filter Callbacks - childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); + //childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); + childSetCommitCallback("wmiColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); //childSetCommitCallback("ColorFilterGamma", &LLFloaterPostProcess::onFloatControlMoved, &(gPostProcess->tweaks.gamma())); - childSetCommitCallback("ColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness"); - childSetCommitCallback("ColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation"); - childSetCommitCallback("ColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast"); + childSetCommitCallback("wmiColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness"); + childSetCommitCallback("wmiColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation"); + childSetCommitCallback("wmiColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast"); - childSetCommitCallback("ColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base"); - childSetCommitCallback("ColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base"); - childSetCommitCallback("ColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base"); - childSetCommitCallback("ColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base"); /// Night Vision Callbacks - childSetCommitCallback("NightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision"); - childSetCommitCallback("NightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier"); - childSetCommitCallback("NightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size"); - childSetCommitCallback("NightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength"); + childSetCommitCallback("wmiNightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision"); + childSetCommitCallback("wmiNightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier"); + childSetCommitCallback("wmiNightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size"); + childSetCommitCallback("wmiNightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength"); /// Bloom Callbacks - childSetCommitCallback("BloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom"); - childSetCommitCallback("BloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low"); - childSetCommitCallback("BloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); - childSetCommitCallback("BloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); + childSetCommitCallback("wmiBloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom"); + childSetCommitCallback("wmiBloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low"); + childSetCommitCallback("wmiBloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); + childSetCommitCallback("wmiBloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); // Effect loading and saving. LLComboBox* comboBox = getChild<LLComboBox>("PPEffectsCombo"); @@ -113,6 +114,7 @@ void LLFloaterPostProcess::onBoolToggle(LLUICtrl* ctrl, void* userData) // check the bool LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl); gPostProcess->tweaks[boolVariableName] = cbCtrl->getValue(); + } // Float Moved @@ -247,25 +249,25 @@ void LLFloaterPostProcess::syncMenu() comboBox->selectByValue(gPostProcess->getSelectedEffect()); /// Sync Color Filter Menu - childSetValue("ColorFilterToggle", gPostProcess->tweaks.useColorFilter()); + childSetValue("wmiColorFilterToggle", gPostProcess->tweaks.useColorFilter()); //childSetValue("ColorFilterGamma", gPostProcess->tweaks.gamma()); - childSetValue("ColorFilterBrightness", gPostProcess->tweaks.brightness()); - childSetValue("ColorFilterSaturation", gPostProcess->tweaks.saturation()); - childSetValue("ColorFilterContrast", gPostProcess->tweaks.contrast()); - childSetValue("ColorFilterBaseR", gPostProcess->tweaks.contrastBaseR()); - childSetValue("ColorFilterBaseG", gPostProcess->tweaks.contrastBaseG()); - childSetValue("ColorFilterBaseB", gPostProcess->tweaks.contrastBaseB()); - childSetValue("ColorFilterBaseI", gPostProcess->tweaks.contrastBaseIntensity()); + childSetValue("wmiColorFilterBrightness", gPostProcess->tweaks.brightness()); + childSetValue("wmiColorFilterSaturation", gPostProcess->tweaks.saturation()); + childSetValue("wmiColorFilterContrast", gPostProcess->tweaks.contrast()); + childSetValue("wmiColorFilterBaseR", gPostProcess->tweaks.contrastBaseR()); + childSetValue("wmiColorFilterBaseG", gPostProcess->tweaks.contrastBaseG()); + childSetValue("wmiColorFilterBaseB", gPostProcess->tweaks.contrastBaseB()); + childSetValue("wmiColorFilterBaseI", gPostProcess->tweaks.contrastBaseIntensity()); /// Sync Night Vision Menu - childSetValue("NightVisionToggle", gPostProcess->tweaks.useNightVisionShader()); - childSetValue("NightVisionBrightMult", gPostProcess->tweaks.brightMult()); - childSetValue("NightVisionNoiseSize", gPostProcess->tweaks.noiseSize()); - childSetValue("NightVisionNoiseStrength", gPostProcess->tweaks.noiseStrength()); + childSetValue("wmiNightVisionToggle", gPostProcess->tweaks.useNightVisionShader()); + childSetValue("wmiNightVisionBrightMult", gPostProcess->tweaks.brightMult()); + childSetValue("wmiNightVisionNoiseSize", gPostProcess->tweaks.noiseSize()); + childSetValue("wmiNightVisionNoiseStrength", gPostProcess->tweaks.noiseStrength()); /// Sync Bloom Menu - childSetValue("BloomToggle", LLSD(gPostProcess->tweaks.useBloomShader())); - childSetValue("BloomExtract", gPostProcess->tweaks.extractLow()); - childSetValue("BloomSize", gPostProcess->tweaks.bloomWidth()); - childSetValue("BloomStrength", gPostProcess->tweaks.bloomStrength()); + childSetValue("wmiBloomToggle", LLSD(gPostProcess->tweaks.useBloomShader())); + childSetValue("wmiBloomExtract", gPostProcess->tweaks.extractLow()); + childSetValue("wmiBloomSize", gPostProcess->tweaks.bloomWidth()); + childSetValue("wmiBloomStrength", gPostProcess->tweaks.bloomStrength()); } diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp index a7f41eae4..9209f4183 100644 --- a/linden/indra/newview/llfloaterreporter.cpp +++ b/linden/indra/newview/llfloaterreporter.cpp @@ -952,7 +952,8 @@ void LLFloaterReporter::takeScreenshot() // store in the image list so it doesn't try to fetch from the server LLPointer<LLViewerImage> image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid); - image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + image_in_list->createGLTexture(0, raw); + gImageList.addImage(image_in_list); // the texture picker then uses that texture diff --git a/linden/indra/newview/llhudeffect.cpp b/linden/indra/newview/llhudeffect.cpp index c1d46f98d..20bbb321e 100644 --- a/linden/indra/newview/llhudeffect.cpp +++ b/linden/indra/newview/llhudeffect.cpp @@ -78,7 +78,7 @@ void LLHUDEffect::unpackData(LLMessageSystem *mesgsys, S32 blocknum) void LLHUDEffect::render() { - llerrs << "Never call this!" << llendl; + llwarns << "Never call this!" << llendl; // Then why the &*^&*^ is it here? } void LLHUDEffect::setID(const LLUUID &id) diff --git a/linden/indra/newview/llhudtext.cpp b/linden/indra/newview/llhudtext.cpp index 661a786a8..b170337c0 100644 --- a/linden/indra/newview/llhudtext.cpp +++ b/linden/indra/newview/llhudtext.cpp @@ -1111,6 +1111,8 @@ void LLHUDText::renderAllHUD() LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); // KL not entirely sure why but render pipeline has this twice? + LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); diff --git a/linden/indra/newview/llmanip.cpp b/linden/indra/newview/llmanip.cpp index 45550fcfb..0c88c477e 100644 --- a/linden/indra/newview/llmanip.cpp +++ b/linden/indra/newview/llmanip.cpp @@ -60,7 +60,7 @@ #include "llglheaders.h" // Local constants... -const S32 VERTICAL_OFFSET = 50; +const S32 VERTICAL_OFFSET = 100; // KL adjusted to compensate for toolbars move to the top of the screen! F32 LLManip::sHelpTextVisibleTime = 2.f; F32 LLManip::sHelpTextFadeTime = 2.f; diff --git a/linden/indra/newview/llmaniptranslate.h b/linden/indra/newview/llmaniptranslate.h index 77f12ff91..25ff35cc7 100644 --- a/linden/indra/newview/llmaniptranslate.h +++ b/linden/indra/newview/llmaniptranslate.h @@ -116,7 +116,7 @@ class LLManipTranslate : public LLManip LLVector3d mDragCursorStartGlobal; LLVector3d mDragSelectionStartGlobal; LLTimer mUpdateTimer; - typedef std::multiset<ManipulatorHandle*, compare_manipulators> minpulator_list_t; + typedef std::set<ManipulatorHandle*, compare_manipulators> minpulator_list_t; minpulator_list_t mProjectedManipulators; LLVector4 mManipulatorVertices[18]; F32 mSnapOffsetMeters; diff --git a/linden/indra/newview/llmediactrl.cpp b/linden/indra/newview/llmediactrl.cpp index 153059897..a517332bd 100644 --- a/linden/indra/newview/llmediactrl.cpp +++ b/linden/indra/newview/llmediactrl.cpp @@ -1012,8 +1012,7 @@ BOOL LLWebBrowserTexture::render() x_pos, y_pos, width, - height, - TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) + height); } media_plugin->resetDirty(); diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index db4422d66..e903df792 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp @@ -491,7 +491,6 @@ void LLOverlayBar::toggleMusicPlay(void*) // if ( gAudiop->isInternetStreamPlaying() == 0 ) { gAudiop->startInternetStream(parcel->getMusicURL()); -//awfixme sTitleObserver.init(parcel->getMusicURL()); } } } diff --git a/linden/indra/newview/llpanelvolume.cpp b/linden/indra/newview/llpanelvolume.cpp index 6d014a23d..4270f0bba 100644 --- a/linden/indra/newview/llpanelvolume.cpp +++ b/linden/indra/newview/llpanelvolume.cpp @@ -53,6 +53,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcolorswatch.h" +#include "lltexturectrl.h" #include "llcombobox.h" #include "llfirstuse.h" #include "llfocusmgr.h" @@ -111,12 +112,28 @@ BOOL LLPanelVolume::postBuild() LightColorSwatch->setOnSelectCallback(onLightSelectColor); childSetCommitCallback("colorswatch",onCommitLight,this); } + + LLTextureCtrl* LightTexPicker = getChild<LLTextureCtrl>("light texture control"); + if (LightTexPicker) + { + LightTexPicker->setOnCancelCallback(onLightCancelTexture); + LightTexPicker->setOnSelectCallback(onLightSelectTexture); + childSetCommitCallback("light texture control", onCommitLight, this); + } + childSetCommitCallback("Light Intensity",onCommitLight,this); childSetValidate("Light Intensity",precommitValidate); childSetCommitCallback("Light Radius",onCommitLight,this); childSetValidate("Light Radius",precommitValidate); childSetCommitCallback("Light Falloff",onCommitLight,this); childSetValidate("Light Falloff",precommitValidate); + + childSetCommitCallback("Light FOV", onCommitLight, this); + childSetValidate("Light FOV", precommitValidate); + childSetCommitCallback("Light Focus", onCommitLight, this); + childSetValidate("Light Focus", precommitValidate); + childSetCommitCallback("Light Ambiance", onCommitLight, this); + childSetValidate("Light Ambiance", precommitValidate); } // Start with everyone disabled @@ -221,14 +238,32 @@ void LLPanelVolume::getState( ) LightColorSwatch->setValid( TRUE ); LightColorSwatch->set(volobjp->getLightBaseColor()); } + + LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(TRUE); + LightTextureCtrl->setValid(TRUE); + LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); + } + childSetEnabled("Light Intensity",true); childSetEnabled("Light Radius",true); childSetEnabled("Light Falloff",true); + childSetEnabled("Light FOV", true); + childSetEnabled("Light Focus", true); + childSetEnabled("Light Ambiance", true); + childSetValue("Light Intensity",volobjp->getLightIntensity()); childSetValue("Light Radius",volobjp->getLightRadius()); childSetValue("Light Falloff",volobjp->getLightFalloff()); + LLVector3 params = volobjp->getSpotLightParams(); + childSetValue("Light FOV", params.mV[0]); + childSetValue("Light Focus", params.mV[1]); + childSetValue("Light Ambiance", params.mV[2]); + mLightSavedColor = volobjp->getLightColor(); } else @@ -244,9 +279,20 @@ void LLPanelVolume::getState( ) LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } + LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(FALSE); + LightTextureCtrl->setValid(FALSE); + } + childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); + + childSetEnabled("Light FOV",false); + childSetEnabled("Light Focus",false); + childSetEnabled("Light Ambiance",false); } // Flexible properties @@ -362,6 +408,13 @@ void LLPanelVolume::clearCtrls() LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } + LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); + if(LightTextureCtrl) + { + LightTextureCtrl->setEnabled( FALSE ); + LightTextureCtrl->setValid( FALSE ); + } + childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); @@ -438,6 +491,16 @@ void LLPanelVolume::onLightCancelColor(LLUICtrl* ctrl, void* userdata) onLightSelectColor(NULL, userdata); } +void LLPanelVolume::onLightCancelTexture(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setImageAssetID(self->mLightSavedTexture); + } +} + void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*) userdata; @@ -459,6 +522,25 @@ void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) } } +void LLPanelVolume::onLightSelectTexture(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLViewerObject* objectp = self->mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *)objectp; + + + LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); + volobjp->setLightTextureID(id); + self->mLightSavedTexture = id; + } +} // static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { @@ -474,12 +556,47 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) volobjp->setLightIntensity((F32)self->childGetValue("Light Intensity").asReal()); volobjp->setLightRadius((F32)self->childGetValue("Light Radius").asReal()); volobjp->setLightFalloff((F32)self->childGetValue("Light Falloff").asReal()); + LLColorSwatchCtrl* LightColorSwatch = self->getChild<LLColorSwatchCtrl>("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); volobjp->setLightColor(LLColor3(clr)); } + + LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); + if (id.notNull()) + { + if (volobjp->getLightTextureID().isNull()) + { //this commit is making this a spot light, set UI to default params + volobjp->setLightTextureID(id); + LLVector3 spot_params = volobjp->getSpotLightParams(); + self->childSetValue("Light FOV", spot_params.mV[0]); + self->childSetValue("Light Focus", spot_params.mV[1]); + self->childSetValue("Light Ambiance", spot_params.mV[2]); + } + else + { //modifying existing params + LLVector3 spot_params; + spot_params.mV[0] = (F32) self->childGetValue("Light FOV").asReal(); + spot_params.mV[1] = (F32) self->childGetValue("Light Focus").asReal(); + spot_params.mV[2] = (F32) self->childGetValue("Light Ambiance").asReal(); + volobjp->setSpotLightParams(spot_params); + } + } + else if (volobjp->getLightTextureID().notNull()) + { //no longer a spot light + volobjp->setLightTextureID(id); + //self->childDisable("Light FOV"); + //self->childDisable("Light Focus"); + //self->childDisable("Light Ambiance"); + } + } + + } // static diff --git a/linden/indra/newview/llpanelvolume.h b/linden/indra/newview/llpanelvolume.h index 841880b14..5d206fc3b 100644 --- a/linden/indra/newview/llpanelvolume.h +++ b/linden/indra/newview/llpanelvolume.h @@ -74,6 +74,10 @@ class LLPanelVolume : public LLPanel static void onLightCancelColor(LLUICtrl* ctrl, void* userdata); static void onLightSelectColor(LLUICtrl* ctrl, void* userdata); + static void onLightCancelTexture(LLUICtrl* ctrl, void* userdata); + static void onLightSelectTexture(LLUICtrl* ctrl, void* userdata); + + protected: void getState(); @@ -99,6 +103,7 @@ class LLPanelVolume : public LLPanel */ LLColor4 mLightSavedColor; + LLUUID mLightSavedTexture; LLPointer<LLViewerObject> mObject; LLPointer<LLViewerObject> mRootObject; }; diff --git a/linden/indra/newview/llpostprocess.cpp b/linden/indra/newview/llpostprocess.cpp new file mode 100644 index 000000000..c7d5dad60 --- /dev/null +++ b/linden/indra/newview/llpostprocess.cpp @@ -0,0 +1,594 @@ +/** + * @file llpostprocess.cpp + * @brief LLPostProcess class implementation + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "linden_common.h" + +#include "llpostprocess.h" +#include "llglslshader.h" +#include "llsdserialize.h" +#include "llrender.h" + +#include "llviewershadermgr.h" // KL throwing some includes at postprocess see if we can get the bastard working! +#include "pipeline.h" +#include "llimagegl.h" + + + +LLPostProcess * gPostProcess = NULL; + + +static const unsigned int NOISE_SIZE = 512; + +/// CALCULATING LUMINANCE (Using NTSC lum weights) +/// http://en.wikipedia.org/wiki/Luma_%28video%29 +static const float LUMINANCE_R = 0.299f; +static const float LUMINANCE_G = 0.587f; +static const float LUMINANCE_B = 0.114f; + +static const char * const XML_FILENAME = "postprocesseffects.xml"; + +LLPostProcess::LLPostProcess(void) : + initialized(false), + mAllEffects(LLSD::emptyMap()), + screenW(1), screenH(1) +{ + mSceneRenderTexture = NULL ; + mNoiseTexture = NULL ; + mTempBloomTexture = NULL ; + + // Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); + LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL; + + llifstream effectsXML(pathName); + + if (effectsXML) + { + LLPointer<LLSDParser> parser = new LLSDXMLParser(); + + parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED); + } + + if (!mAllEffects.has("default")) + { + LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap()); + + defaultEffect["enable_night_vision"] = LLSD::Boolean(false); + defaultEffect["enable_bloom"] = LLSD::Boolean(false); + defaultEffect["enable_color_filter"] = LLSD::Boolean(false); + + /// NVG Defaults + defaultEffect["brightness_multiplier"] = 3.0; + defaultEffect["noise_size"] = 25.0; + defaultEffect["noise_strength"] = 0.4; + + // TODO BTest potentially add this to tweaks? + noiseTextureScale = 1.0f; + + /// Bloom Defaults + defaultEffect["extract_low"] = 0.95; + defaultEffect["extract_high"] = 1.0; + defaultEffect["bloom_width"] = 2.25; + defaultEffect["bloom_strength"] = 1.5; + + /// Color Filter Defaults + defaultEffect["brightness"] = 1.0; + defaultEffect["contrast"] = 1.0; + defaultEffect["saturation"] = 1.0; + + LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray()); + contrastBase.append(1.0); + contrastBase.append(1.0); + contrastBase.append(1.0); + contrastBase.append(0.5); + } + + setSelectedEffect("default"); + +} + +LLPostProcess::~LLPostProcess(void) +{ + invalidate() ; +} + +// static +void LLPostProcess::initClass(void) +{ + //this will cause system to crash at second time login + //if first time login fails due to network connection --- bao + //***llassert_always(gPostProcess == NULL); + //replaced by the following line: + if(gPostProcess) + return ; + + + gPostProcess = new LLPostProcess(); +} + +// static +void LLPostProcess::cleanupClass() +{ + delete gPostProcess; + gPostProcess = NULL; +} + +void LLPostProcess::setSelectedEffect(std::string const & effectName) +{ + mSelectedEffectName = effectName; + static_cast<LLSD &>(tweaks) = mAllEffects[effectName]; +} + +void LLPostProcess::saveEffect(std::string const & effectName) +{ + // Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. + mAllEffects[effectName] = tweaks; + + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); + //llinfos << "Saving PostProcess Effects settings to " << pathName << llendl; + + llofstream effectsXML(pathName); + + LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); + + formatter->format(mAllEffects, effectsXML); + +} +void LLPostProcess::invalidate() +{ + mSceneRenderTexture = NULL ; + mNoiseTexture = NULL ; + mTempBloomTexture = NULL ; + initialized = FALSE ; +} + +void LLPostProcess::apply(unsigned int width, unsigned int height) +{ + if (!initialized || width != screenW || height != screenH){ + initialize(width, height); + } + if (shadersEnabled()){ + doEffects(); + } +} + +void LLPostProcess::initialize(unsigned int width, unsigned int height) +{ + screenW = width; + screenH = height; + createTexture(mSceneRenderTexture, screenW, screenH); + initialized = true; + + checkError(); + createNightVisionShader(); + createBloomShader(); + createColorFilterShader(); + checkError(); +} + +inline bool LLPostProcess::shadersEnabled(void) +{ + return (tweaks.useColorFilter().asBoolean() || + tweaks.useNightVisionShader().asBoolean() || + tweaks.useBloomShader().asBoolean() ); + +} + +void LLPostProcess::applyShaders(void) +{ + if (tweaks.useColorFilter()){ + applyColorFilterShader(); + checkError(); + } + if (tweaks.useNightVisionShader()){ + /// If any of the above shaders have been called update the frame buffer; + if (tweaks.useColorFilter()) + { + U32 tex = mSceneRenderTexture->getTexName() ; + copyFrameBuffer(tex, screenW, screenH); + } + applyNightVisionShader(); + checkError(); + } + if (tweaks.useBloomShader()){ + /// If any of the above shaders have been called update the frame buffer; + if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean()) + { + U32 tex = mSceneRenderTexture->getTexName() ; + copyFrameBuffer(tex, screenW, screenH); + } + applyBloomShader(); + checkError(); + } +} + +void LLPostProcess::applyColorFilterShader(void) +{ + // Do nothing. moved back to newview work in progress KL + gPostColorFilterProgram.bind(); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); + + U32 tex = mSceneRenderTexture->getTexName() ; // KL + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, tex); + + getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject); + glUniform1iARB(colorFilterUniforms["RenderTexture"], 0); + glUniform1fARB(colorFilterUniforms["brightness"], tweaks.getBrightness()); + glUniform1fARB(colorFilterUniforms["contrast"], tweaks.getContrast()); + float baseI = (tweaks.getContrastBaseR() + tweaks.getContrastBaseG() + tweaks.getContrastBaseB()) / 3.0f; + baseI = tweaks.getContrastBaseIntensity() / ((baseI < 0.001f) ? 0.001f : baseI); + float baseR = tweaks.getContrastBaseR() * baseI; + float baseG = tweaks.getContrastBaseG() * baseI; + float baseB = tweaks.getContrastBaseB() * baseI; + glUniform3fARB(colorFilterUniforms["contrastBase"], baseR, baseG, baseB); + glUniform1fARB(colorFilterUniforms["saturation"], tweaks.getSaturation()); + glUniform3fARB(colorFilterUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); + + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_REPLACE); + LLGLDepthTest depth(GL_FALSE); + + /// Draw a screen space quad + drawOrthoQuad(screenW, screenH, QUAD_NORMAL); + gPostColorFilterProgram.unbind(); + +} + +void LLPostProcess::createColorFilterShader(void) +{ + /// Define uniform names + colorFilterUniforms["RenderTexture"] = 0; + colorFilterUniforms["brightness"] = 0; + colorFilterUniforms["contrast"] = 0; + colorFilterUniforms["contrastBase"] = 0; + colorFilterUniforms["saturation"] = 0; + colorFilterUniforms["lumWeights"] = 0; +} + +void LLPostProcess::applyNightVisionShader(void) +{ + // KL re-enabled and moved back to newview + gPostNightVisionProgram.bind(); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); + + getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject); + U32 sceneRenderTexture = mSceneRenderTexture->getTexName() ; // KL + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture); + glUniform1iARB(nightVisionUniforms["RenderTexture"], 0); + + gGL.getTexUnit(1)->activate(); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + U32 noiseTexture = mNoiseTexture->getTexName(); //KL + gGL.getTexUnit(1)->bindManual(LLTexUnit::TT_TEXTURE, noiseTexture); + glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1); + + + glUniform1fARB(nightVisionUniforms["brightMult"], tweaks.getBrightMult()); + glUniform1fARB(nightVisionUniforms["noiseStrength"], tweaks.getNoiseStrength()); + noiseTextureScale = 0.01f + ((101.f - tweaks.getNoiseSize()) / 100.f); + noiseTextureScale *= (screenH / NOISE_SIZE); + + + glUniform3fARB(nightVisionUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); + + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_REPLACE); + LLGLDepthTest depth(GL_FALSE); + + /// Draw a screen space quad + drawOrthoQuad(screenW, screenH, QUAD_NOISE); + gPostNightVisionProgram.unbind(); + gGL.getTexUnit(0)->activate(); + +} + +void LLPostProcess::createNightVisionShader(void) +{ + /// Define uniform names + nightVisionUniforms["RenderTexture"] = 0; + nightVisionUniforms["NoiseTexture"] = 0; + nightVisionUniforms["brightMult"] = 0; + nightVisionUniforms["noiseStrength"] = 0; + nightVisionUniforms["lumWeights"] = 0; + + createNoiseTexture(mNoiseTexture); +} + +void LLPostProcess::applyBloomShader(void) +{ + +} + +void LLPostProcess::createBloomShader(void) +{ + createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); + + /// Create Bloom Extract Shader + bloomExtractUniforms["RenderTexture"] = 0; + bloomExtractUniforms["extractLow"] = 0; + bloomExtractUniforms["extractHigh"] = 0; + bloomExtractUniforms["lumWeights"] = 0; + + /// Create Bloom Blur Shader + bloomBlurUniforms["RenderTexture"] = 0; + bloomBlurUniforms["bloomStrength"] = 0; + bloomBlurUniforms["texelSize"] = 0; + bloomBlurUniforms["blurDirection"] = 0; + bloomBlurUniforms["blurWidth"] = 0; +} + +void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog) +{ + /// Find uniform locations and insert into map + std::map<const char *, GLuint>::iterator i; + for (i = uniforms.begin(); i != uniforms.end(); ++i){ + i->second = glGetUniformLocationARB(prog, i->first); + } +} + +void LLPostProcess::doEffects(void) +{ + /// Save GL State + glPushAttrib(GL_ALL_ATTRIB_BITS); + glPushClientAttrib(GL_ALL_ATTRIB_BITS); + + /// Copy the screen buffer to the render texture + { + U32 tex = mSceneRenderTexture->getTexName() ; + copyFrameBuffer(tex, screenW, screenH); + } + + /// Clear the frame buffer. + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + /// Change to an orthogonal view + viewOrthogonal(screenW, screenH); + + checkError(); + applyShaders(); + + LLGLSLShader::bindNoShader(); + checkError(); + + /// Change to a perspective view + viewPerspective(); + + /// Reset GL State + glPopClientAttrib(); + glPopAttrib(); + checkError(); +} + +void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height) +{ + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture); + glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); +} + +void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type) +{ + + float noiseX = 0.f; + float noiseY = 0.f; + float screenRatio = 1.0f; + + if (type == QUAD_NOISE){ + noiseX = ((float) rand() / (float) RAND_MAX); + noiseY = ((float) rand() / (float) RAND_MAX); + screenRatio = (float) width / (float) height; + } + + + glBegin(GL_QUADS); + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height * 2.0f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + noiseX, + noiseTextureScale + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, (GLfloat) height * 0.5f); + } + glVertex2f(0.f, (GLfloat) screenH - height); + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + noiseX, + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, 0.f); + } + glVertex2f(0.f, (GLfloat) height + (screenH - height)); + + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, 0.f); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, 0.f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + screenRatio * noiseTextureScale + noiseX, + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, 0.f); + } + glVertex2f((GLfloat) width, (GLfloat) height + (screenH - height)); + + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, (GLfloat) height); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, (GLfloat) height * 2.0f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + screenRatio * noiseTextureScale + noiseX, + noiseTextureScale + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, (GLfloat) height * 0.5f); + } + glVertex2f((GLfloat) width, (GLfloat) screenH - height); + glEnd(); + +} + +void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height) +{ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f ); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); +} + +void LLPostProcess::viewPerspective(void) +{ + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); +} + +void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height) +{ + viewPerspective(); + viewOrthogonal(width, height); +} + +void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height) +{ + std::vector<GLubyte> data(width * height * 4, 0) ; + + texture = new LLImageGL(FALSE) ; + if(texture->createGLTexture()) + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture->getTexName()); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + } +} + +void LLPostProcess::createNoiseTexture(LLPointer<LLImageGL>& texture) +{ + std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE); + for (unsigned int i = 0; i < NOISE_SIZE; i++){ + for (unsigned int k = 0; k < NOISE_SIZE; k++){ + buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); + } + } + + texture = new LLImageGL(FALSE) ; + if(texture->createGLTexture()) + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName()); + LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + } +} + +bool LLPostProcess::checkError(void) +{ + GLenum glErr; + bool retCode = false; + + glErr = glGetError(); + while (glErr != GL_NO_ERROR) + { + // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl; + char const * err_str_raw = (const char *) gluErrorString(glErr); + + if(err_str_raw == NULL) + { + std::ostringstream err_builder; + err_builder << "unknown error number " << glErr; + mShaderErrorString = err_builder.str(); + } + else + { + mShaderErrorString = err_str_raw; + } + + retCode = true; + glErr = glGetError(); + } + return retCode; +} + +void LLPostProcess::checkShaderError(GLhandleARB shader) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog; + + checkError(); // Check for OpenGL errors + + glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength); + + checkError(); // Check for OpenGL errors + + if (infologLength > 0) + { + infoLog = (GLchar *)malloc(infologLength); + if (infoLog == NULL) + { + /// Could not allocate infolog buffer + return; + } + glGetInfoLogARB(shader, infologLength, &charsWritten, infoLog); + // shaderErrorLog << (char *) infoLog << std::endl; + mShaderErrorString = (char *) infoLog; + free(infoLog); + } + checkError(); // Check for OpenGL errors +} \ No newline at end of file diff --git a/linden/indra/newview/llpostprocess.h b/linden/indra/newview/llpostprocess.h new file mode 100644 index 000000000..d6926e48c --- /dev/null +++ b/linden/indra/newview/llpostprocess.h @@ -0,0 +1,274 @@ +/** + * @file llpostprocess.h + * @brief LLPostProcess class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_POSTPROCESS_H +#define LL_POSTPROCESS_H + +#include <map> +#include <fstream> +#include "llgl.h" +#include "llglheaders.h" + +class LLPostProcess +{ +public: + + typedef enum _QuadType { + QUAD_NORMAL, + QUAD_NOISE, + QUAD_BLOOM_EXTRACT, + QUAD_BLOOM_COMBINE + } QuadType; + + /// GLSL Shader Encapsulation Struct + typedef std::map<const char *, GLuint> glslUniforms; + + struct PostProcessTweaks : public LLSD { + inline PostProcessTweaks() : LLSD(LLSD::emptyMap()) + { + } + + inline LLSD & brightMult() { + return (*this)["brightness_multiplier"]; + } + + inline LLSD & noiseStrength() { + return (*this)["noise_strength"]; + } + + inline LLSD & noiseSize() { + return (*this)["noise_size"]; + } + + inline LLSD & extractLow() { + return (*this)["extract_low"]; + } + + inline LLSD & extractHigh() { + return (*this)["extract_high"]; + } + + inline LLSD & bloomWidth() { + return (*this)["bloom_width"]; + } + + inline LLSD & bloomStrength() { + return (*this)["bloom_strength"]; + } + + inline LLSD & brightness() { + return (*this)["brightness"]; + } + + inline LLSD & contrast() { + return (*this)["contrast"]; + } + + inline LLSD & contrastBaseR() { + return (*this)["contrast_base"][0]; + } + + inline LLSD & contrastBaseG() { + return (*this)["contrast_base"][1]; + } + + inline LLSD & contrastBaseB() { + return (*this)["contrast_base"][2]; + } + + inline LLSD & contrastBaseIntensity() { + return (*this)["contrast_base"][3]; + } + + inline LLSD & saturation() { + return (*this)["saturation"]; + } + + inline LLSD & useNightVisionShader() { + return (*this)["enable_night_vision"]; + } + + inline LLSD & useBloomShader() { + return (*this)["enable_bloom"]; + } + + inline LLSD & useColorFilter() { + return (*this)["enable_color_filter"]; + } + + + inline F32 getBrightMult() const { + return F32((*this)["brightness_multiplier"].asReal()); + } + + inline F32 getNoiseStrength() const { + return F32((*this)["noise_strength"].asReal()); + } + + inline F32 getNoiseSize() const { + return F32((*this)["noise_size"].asReal()); + } + + inline F32 getExtractLow() const { + return F32((*this)["extract_low"].asReal()); + } + + inline F32 getExtractHigh() const { + return F32((*this)["extract_high"].asReal()); + } + + inline F32 getBloomWidth() const { + return F32((*this)["bloom_width"].asReal()); + } + + inline F32 getBloomStrength() const { + return F32((*this)["bloom_strength"].asReal()); + } + + inline F32 getBrightness() const { + return F32((*this)["brightness"].asReal()); + } + + inline F32 getContrast() const { + return F32((*this)["contrast"].asReal()); + } + + inline F32 getContrastBaseR() const { + return F32((*this)["contrast_base"][0].asReal()); + } + + inline F32 getContrastBaseG() const { + return F32((*this)["contrast_base"][1].asReal()); + } + + inline F32 getContrastBaseB() const { + return F32((*this)["contrast_base"][2].asReal()); + } + + inline F32 getContrastBaseIntensity() const { + return F32((*this)["contrast_base"][3].asReal()); + } + + inline F32 getSaturation() const { + return F32((*this)["saturation"].asReal()); + } + + }; + + bool initialized; + PostProcessTweaks tweaks; + + // the map of all availible effects + LLSD mAllEffects; + +private: + LLPointer<LLImageGL> mSceneRenderTexture ; + LLPointer<LLImageGL> mNoiseTexture ; + LLPointer<LLImageGL> mTempBloomTexture ; + + + +public: + LLPostProcess(void); + + ~LLPostProcess(void); + + void apply(unsigned int width, unsigned int height); + void invalidate() ; + + /// Perform global initialization for this class. + static void initClass(void); + + // Cleanup of global data that's only inited once per class. + static void cleanupClass(); + + void setSelectedEffect(std::string const & effectName); + + inline std::string const & getSelectedEffect(void) const { + return mSelectedEffectName; + } + + void saveEffect(std::string const & effectName); + +private: + /// read in from file + std::string mShaderErrorString; + unsigned int screenW; + unsigned int screenH; + + float noiseTextureScale; + + /// Shader Uniforms + glslUniforms nightVisionUniforms; + glslUniforms bloomExtractUniforms; + glslUniforms bloomBlurUniforms; + glslUniforms colorFilterUniforms; + + // the name of currently selected effect in mAllEffects + //invariant: tweaks == mAllEffects[mSelectedEffectName] + std::string mSelectedEffectName; + + /// General functions + void initialize(unsigned int width, unsigned int height); + void doEffects(void); + void applyShaders(void); + bool shadersEnabled(void); + + /// Night Vision Functions + void createNightVisionShader(void); + void applyNightVisionShader(void); + + /// Bloom Functions + void createBloomShader(void); + void applyBloomShader(void); + + /// Color Filter Functions + void createColorFilterShader(void); + void applyColorFilterShader(void); + + /// OpenGL Helper Functions + void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog); + void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height); + void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height); + void createNoiseTexture(LLPointer<LLImageGL>& texture); + bool checkError(void); + void checkShaderError(GLhandleARB shader); + void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type); + void viewOrthogonal(unsigned int width, unsigned int height); + void changeOrthogonal(unsigned int width, unsigned int height); + void viewPerspective(void); +}; + +extern LLPostProcess * gPostProcess; + + +#endif // LL_POSTPROCESS_H diff --git a/linden/indra/newview/llpreview.cpp b/linden/indra/newview/llpreview.cpp index f679a7505..019bd5fca 100644 --- a/linden/indra/newview/llpreview.cpp +++ b/linden/indra/newview/llpreview.cpp @@ -641,6 +641,7 @@ void LLPreview::setAssetId(const LLUUID& asset_id) LLViewerObject* object = gObjectList.findObject(mObjectUUID); if(NULL == object) { + llwarns << "LLPreview::setAssetId() called on unrecognized object, UUID : " << mObjectUUID << llendl; return; } object->updateViewerInventoryAsset(item, asset_id); diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index b2904b9fc..0fa8285f6 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -764,7 +764,7 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab } else { - llerrs << "LLSelectMgr::add face " << face << " out-of-range" << llendl; + llwarns << "LLSelectMgr::add face " << face << " out-of-range" << llendl; return; } @@ -1187,7 +1187,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) } else { - llerrs << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl; + llwarns << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl; return; } @@ -1210,7 +1210,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) else { // ...out of range face - llerrs << "LLSelectMgr::remove - TE " << te << " out of range" << llendl; + llwarns << "LLSelectMgr::remove - TE " << te << " out of range" << llendl; } updateSelectionCenter(); @@ -1709,7 +1709,7 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright) } sendfunc(fullbright); getSelection()->applyToObjects(&sendfunc); } - +/* void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url) { U8 media_flags = LLTextureEntry::MF_NONE; @@ -1752,7 +1752,7 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& } sendfunc(media_type, media_url); getSelection()->applyToObjects(&sendfunc); } - +*/ void LLSelectMgr::selectionSetGlow(F32 glow) { struct f1 : public LLSelectedTEFunctor @@ -3344,7 +3344,7 @@ void LLSelectMgr::packPermissionsHead(void* user_data) /* void LLSelectMgr::sendSelect() { - llerrs << "Not implemented" << llendl; + llwarns << "Not implemented" << llendl; } */ @@ -4156,7 +4156,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name, break; default: - llerrs << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl; + llwarns << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl; } // bail if nothing selected @@ -4563,11 +4563,6 @@ extern LLGLdouble gGLModelView[16]; void LLSelectMgr::updateSilhouettes() { - if (!mRenderSilhouettes || !LLSelectMgr::sRenderSelectionHighlights) - { - return; - } - S32 num_sils_genned = 0; LLVector3d cameraPos = gAgent.getCameraPositionGlobal(); @@ -5781,8 +5776,7 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) } if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) || - (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove()) || - (gSavedSettings.getBOOL("SelectCopyableOnly") && !object->permCopy())) + (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove())) { // only select my own objects return FALSE; diff --git a/linden/indra/newview/llselectmgr.h b/linden/indra/newview/llselectmgr.h index 6278049ae..b56577073 100644 --- a/linden/indra/newview/llselectmgr.h +++ b/linden/indra/newview/llselectmgr.h @@ -503,7 +503,7 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr> void selectionSetTexGen( U8 texgen ); void selectionSetShiny( U8 shiny ); void selectionSetFullbright( U8 fullbright ); - void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); +// void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); void selectionSetClickAction(U8 action); void selectionSetIncludeInSearch(bool include_in_search); void selectionSetGlow(const F32 glow); diff --git a/linden/indra/newview/llsky.cpp b/linden/indra/newview/llsky.cpp index ac7e865de..b779aa0f8 100644 --- a/linden/indra/newview/llsky.cpp +++ b/linden/indra/newview/llsky.cpp @@ -422,6 +422,20 @@ void LLSky::updateFog(const F32 distance) void LLSky::updateCull() { + /*if (mVOSkyp.notNull() && mVOSkyp->mDrawable.notNull()) + { + gPipeline.markVisible(mVOSkyp->mDrawable); + } + else + { + llinfos << "No sky drawable!" << llendl; + }*/ + + /*if (mVOGroundp.notNull() && mVOGroundp->mDrawable.notNull()) + { + gPipeline.markVisible(mVOGroundp->mDrawable); + }*/ + // *TODO: do culling for wl sky properly -Brad } diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index 31b537c56..114d3b5ef 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp @@ -48,6 +48,7 @@ #include "llrender.h" #include "lloctree.h" #include "llvoavatar.h" +#include "lltextureatlas.h" const F32 SG_OCCLUSION_FUDGE = 0.25f; #define SG_DISCARD_TOLERANCE 0.01f @@ -95,7 +96,7 @@ void sg_assert(BOOL expr) #if LL_OCTREE_PARANOIA_CHECK if (!expr) { - llerrs << "Octree invalid!" << llendl; + llwarns << "Octree invalid!" << llendl; } #endif } @@ -281,10 +282,10 @@ S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3 LLSpatialGroup::~LLSpatialGroup() { - if (sNoDelete) + /*if (sNoDelete) { - llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; - } + llwarns << "Illegal deletion of LLSpatialGroup!" << llendl; + }*/ if (isState(DEAD)) { @@ -302,6 +303,129 @@ LLSpatialGroup::~LLSpatialGroup() LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); clearDrawMap(); + clearAtlasList() ; +} + +BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp) +{ + S8 type = atlasp->getComponents() - 1 ; + for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) + { + if(atlasp == *iter) + { + return TRUE ; + } + } + return FALSE ; +} + +void LLSpatialGroup::addAtlas(LLTextureAtlas* atlasp, S8 recursive_level) +{ + if(!hasAtlas(atlasp)) + { + mAtlasList[atlasp->getComponents() - 1].push_back(atlasp) ; + atlasp->addSpatialGroup(this) ; + } + + --recursive_level; + if(recursive_level)//levels propagating up. + { + LLSpatialGroup* parent = getParent() ; + if(parent) + { + parent->addAtlas(atlasp, recursive_level) ; + } + } +} + +void LLSpatialGroup::removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group, S8 recursive_level) +{ + mAtlasList[atlasp->getComponents() - 1].remove(atlasp) ; + if(remove_group) + { + atlasp->removeSpatialGroup(this) ; + } + + --recursive_level; + if(recursive_level)//levels propagating up. + { + LLSpatialGroup* parent = getParent() ; + if(parent) + { + parent->removeAtlas(atlasp, recursive_level) ; + } + } +} + +void LLSpatialGroup::clearAtlasList() +{ + std::list<LLTextureAtlas*>::iterator iter ; + for(S8 i = 0 ; i < 4 ; i++) + { + if(mAtlasList[i].size() > 0) + { + for(iter = mAtlasList[i].begin(); iter != mAtlasList[i].end() ; ++iter) + { + ((LLTextureAtlas*)*iter)->removeSpatialGroup(this) ; + } + mAtlasList[i].clear() ; + } + } +} + +LLTextureAtlas* LLSpatialGroup::getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level) +{ + S8 type = ncomponents - 1 ; + if(mAtlasList[type].size() > 0) + { + for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) + { + if(!((LLTextureAtlas*)*iter)->isFull(to_be_reserved)) + { + return *iter ; + } + } + } + + --recursive_level; + if(recursive_level) + { + LLSpatialGroup* parent = getParent() ; + if(parent) + { + return parent->getAtlas(ncomponents, to_be_reserved, recursive_level) ; + } + } + return NULL ; +} + +void LLSpatialGroup::setCurUpdatingSlot(LLTextureAtlasSlot* slotp) +{ + mCurUpdatingSlotp = slotp; + + //if(!hasAtlas(mCurUpdatingSlotp->getAtlas())) + //{ + // addAtlas(mCurUpdatingSlotp->getAtlas()) ; + //} +} + +LLTextureAtlasSlot* LLSpatialGroup::getCurUpdatingSlot(LLViewerImage* imagep, S8 recursive_level) +{ + if(gFrameCount && mCurUpdatingTime == gFrameCount && mCurUpdatingTexture == imagep) + { + return mCurUpdatingSlotp ; + } + + //--recursive_level ; + //if(recursive_level) + //{ + // LLSpatialGroup* parent = getParent() ; + // if(parent) + // { + // return parent->getCurUpdatingSlot(imagep, recursive_level) ; + // } + //} + return NULL ; } void LLSpatialGroup::clearDrawMap() @@ -348,7 +472,7 @@ void LLSpatialGroup::validate() LLSpatialPartition* part = drawable->asPartition(); if (!part) { - llerrs << "Drawable reports it is a spatial bridge but not a partition." << llendl; + llwarns << "Drawable reports it is a spatial bridge but not a partition." << llendl; } LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); group->validate(); @@ -411,7 +535,7 @@ class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> if (mInheritedMask && !group->isState(mInheritedMask)) { - llerrs << "Spatial group failed inherited mask test." << llendl; + llwarns << "Spatial group failed inherited mask test." << llendl; } if (group->isState(LLSpatialGroup::DIRTY)) @@ -427,7 +551,7 @@ class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> { if (!parent->isState(state)) { - llerrs << "Spatial group failed parent state check." << llendl; + llwarns << "Spatial group failed parent state check." << llendl; } parent = parent->getParent(); } @@ -448,39 +572,39 @@ void validate_draw_info(LLDrawInfo& params) #if LL_OCTREE_PARANOIA_CHECK if (params.mVertexBuffer.isNull()) { - llerrs << "Draw batch has no vertex buffer." << llendl; + llwarns << "Draw batch has no vertex buffer." << llendl; } //bad range if (params.mStart >= params.mEnd) { - llerrs << "Draw batch has invalid range." << llendl; + llwarns << "Draw batch has invalid range." << llendl; } if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts()) { - llerrs << "Draw batch has buffer overrun error." << llendl; + llwarns << "Draw batch has buffer overrun error." << llendl; } if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices()) { - llerrs << "Draw batch has index buffer ovverrun error." << llendl; + llwarns << "Draw batch has index buffer ovverrun error." << llendl; } //bad indices - U32* indicesp = (U32*) params.mVertexBuffer->getIndicesPointer(); + U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); // KL 16 indices for SD not 32 if (indicesp) { for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) { - if (indicesp[i] < params.mStart) + if (indicesp[i] < (U16)params.mStart) //KL { - llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; + llwarns << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; } - if (indicesp[i] > params.mEnd) + if (indicesp[i] > (U16)params.mEnd) // KL { - llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; + llwarns << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; } } } @@ -540,6 +664,7 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc drawablep->setSpatialGroup(this); validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY | DISCARD_QUERY); + gPipeline.markRebuild(this, TRUE); if (drawablep->isSpatialBridge()) { mBridgeList.push_back((LLSpatialBridge*) drawablep); @@ -572,22 +697,23 @@ void LLSpatialGroup::rebuildMesh() void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - if (!gPipeline.hasRenderType(mDrawableType)) + /*if (!gPipeline.hasRenderType(mDrawableType)) { return; - } - - if (!LLPipeline::sSkipUpdate && group->changeLOD()) - { - group->mLastUpdateDistance = group->mDistance; - group->mLastUpdateViewAngle = group->mViewAngle; - } + }*/ if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) { + /*if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && mRenderByGroup) + { + llwarns << "WTF?" << llendl; + }*/ return; } + group->mLastUpdateDistance = group->mDistance; + group->mLastUpdateViewAngle = group->mViewAngle; + LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); group->clearDrawMap(); @@ -625,6 +751,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->clearState(LLSpatialGroup::GEOM_DIRTY); } + void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) { @@ -663,8 +790,11 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO drawablep = *i; minMax = drawablep->getSpatialExtents(); + update_min_max(newMin, newMax, minMax[0]); + update_min_max(newMin, newMax, minMax[1]); + //bin up the object - for (U32 i = 0; i < 3; i++) + /*for (U32 i = 0; i < 3; i++) { if (minMax[0].mV[i] < newMin.mV[i]) { @@ -674,7 +804,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO { newMax.mV[i] = minMax[1].mV[i]; } - } + }*/ } mObjectBounds[0] = (newMin + newMax) * 0.5f; @@ -738,6 +868,10 @@ LLSpatialGroup* LLSpatialGroup::getParent() return NULL; } + if(!mOctreeNode) + { + return NULL; + } OctreeNode* parent = mOctreeNode->getOctParent(); if (parent) @@ -763,6 +897,8 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { drawablep->setSpatialGroup(NULL); setState(GEOM_DIRTY); + gPipeline.markRebuild(this, TRUE); + if (drawablep->isSpatialBridge()) { for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i) @@ -799,6 +935,7 @@ void LLSpatialGroup::shift(const LLVector3 &offset) //if (!mSpatialPartition->mRenderByGroup) { setState(GEOM_DIRTY); + gPipeline.markRebuild(this, TRUE); } if (mOcclusionVerts) @@ -948,7 +1085,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds), mViewAngle(0.f), - mLastUpdateViewAngle(-1.f) + mLastUpdateViewAngle(-1.f), + mAtlasList(4), + mCurUpdatingTime(0), + mCurUpdatingSlotp(NULL), + mCurUpdatingTexture (NULL) { sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -956,6 +1097,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : sg_assert(mOctreeNode->getListenerCount() == 0); mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); + gPipeline.markRebuild(this, TRUE); mBounds[0] = LLVector3(node->getCenter()); mBounds[1] = LLVector3(node->getSize()); @@ -975,7 +1117,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #if !LL_RELEASE_FOR_DOWNLOAD if (isState(LLSpatialGroup::OBJECT_DIRTY)) { - llerrs << "Spatial group dirty on distance update." << llendl; + llwarns << "Spatial group dirty on distance update." << llendl; } #endif if (!getData().empty() && !LLSpatialPartition::sFreezeState) @@ -1014,6 +1156,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, //not setting this node to dirty would be a very good thing group->setState(LLSpatialGroup::ALPHA_DIRTY); + gPipeline.markRebuild(group, FALSE); } } } @@ -1050,6 +1193,18 @@ F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); } +F32 LLSpatialGroup::getUpdateUrgency() const +{ + if (!isVisible()) + { + return 0.f; + } + else + { + return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance; + } +} + BOOL LLSpatialGroup::needsUpdate() { return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; @@ -1157,6 +1312,8 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo void LLSpatialGroup::destroyGL() { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); + gPipeline.markRebuild(this, TRUE); + mLastUpdateTime = gFrameTimeSeconds; mVertexBuffer = NULL; mBufferMap.clear(); @@ -1339,7 +1496,8 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) +: mRenderByGroup(render_by_group) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); mOcclusionEnabled = TRUE; @@ -1351,7 +1509,7 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) mBufferUsage = buffer_usage; mDepthMask = FALSE; mSlopRatio = 0.25f; - mRenderByGroup = TRUE; + //mRenderByGroup = TRUE; mInfiniteFarClip = FALSE; LLGLNamePool::registerPool(&sQueryPool); @@ -1647,13 +1805,76 @@ class LLOctreeCullVisExtents: public LLOctreeCullShadow return false; } + virtual void traverse(const LLSpatialGroup::TreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (earlyFail(group)) + { + return; + } + + if (mRes == 2) + { + //fully in, don't traverse further (won't effect extents + } + else if (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) + { //don't need to do frustum check + LLSpatialGroup::OctreeTraveler::traverse(n); + } + else + { + mRes = frustumCheck(group); + + if (mRes) + { //at least partially in, run on down + LLSpatialGroup::OctreeTraveler::traverse(n); + } + + mRes = 0; + } + } + virtual void processGroup(LLSpatialGroup* group) { - if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) - { //megaprims and water edge patches be damned! + if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) + { + llwarns << "WTF?" << llendl; + } + + if (mRes < 2) + { + + if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) == 2) + { + mEmpty = FALSE; + update_min_max(mMin, mMax, group->mObjectExtents[0]); + update_min_max(mMin, mMax, group->mObjectExtents[1]); + } + else + { + if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) + { //megaprims and water edge patches be damned! + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = i->get(); + const LLVector3* ext = drawable->getSpatialExtents(); + + if (mCamera->AABBInFrustum((ext[1]+ext[0])*0.5f, (ext[1]-ext[0])*0.5f)) + { + mEmpty = FALSE; + update_min_max(mMin, mMax, ext[0]); + update_min_max(mMin, mMax, ext[1]); + } + } + } + } + } + else + { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mObjectExtents[0]); - update_min_max(mMin, mMax, group->mObjectExtents[1]); + update_min_max(mMin, mMax, group->mExtents[0]); + update_min_max(mMin, mMax, group->mExtents[1]); } } @@ -2431,6 +2652,39 @@ void renderBatchSize(LLDrawInfo* params) pushVerts(params, LLVertexBuffer::MAP_VERTEX); } +void renderShadowFrusta(LLDrawInfo* params) +{ + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ADD); + + LLVector3 center = (params->mExtents[1]+params->mExtents[0])*0.5f; + LLVector3 size = (params->mExtents[1]-params->mExtents[0])*0.5f; + + if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size)) + { + glColor3f(1,0,0); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + if (gPipeline.mShadowCamera[5].AABBInFrustum(center, size)) + { + glColor3f(0,1,0); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + if (gPipeline.mShadowCamera[6].AABBInFrustum(center, size)) + { + glColor3f(0,0,1); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + if (gPipeline.mShadowCamera[7].AABBInFrustum(center, size)) + { + glColor3f(1,0,1); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + + gGL.setSceneBlendType(LLRender::BT_ALPHA); +} + + void renderLights(LLDrawable* drawablep) { if (!drawablep->isLight()) @@ -2566,6 +2820,9 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> //draw tight fit bounding boxes for spatial group if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) { + group->rebuildGeom(); + group->rebuildMesh(); + renderOctree(group); stop_glerror(); } @@ -2573,6 +2830,9 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> //render visibility wireframe if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { + group->rebuildGeom(); + group->rebuildMesh(); + gGL.flush(); glPushMatrix(); gGLLastMatrix = NULL; @@ -2598,6 +2858,19 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> LLVector3 nodeCenter = group->mBounds[0]; LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); + group->rebuildGeom(); + group->rebuildMesh(); + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) + { + if (!group->getData().empty()) + { + gGL.color3f(0,0,1); + drawBoxOutline(group->mObjectBounds[0], + group->mObjectBounds[1]); + } + } + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) { LLDrawable* drawable = *i; @@ -2607,6 +2880,16 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> renderBoundingBox(drawable); } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BUILD_QUEUE)) + { + if (drawable->isState(LLDrawable::IN_REBUILD_Q2)) + { + gGL.color4f(0.6f, 0.6f, 0.1f, 1.f); + const LLVector3* ext = drawable->getSpatialExtents(); + drawBoxOutline((ext[0]+ext[1])*0.5f, (ext[1]-ext[0])*0.5f); + } + } + if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { renderTexturePriority(drawable); @@ -2627,9 +2910,9 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> renderRaycast(drawable); } - LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); + // LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); - if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) + /* if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) { renderAvatarCollisionVolumes(avatar); } @@ -2637,7 +2920,7 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET)) { renderAgentTarget(avatar); - } + } */ } @@ -2655,6 +2938,10 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> { renderBatchSize(draw_info); } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + renderShadowFrusta(draw_info); + } } } } @@ -2705,7 +2992,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } -void LLSpatialPartition::renderDebug() +void LLSpatialPartition::renderDebug() // KL SD version { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | LLPipeline::RENDER_DEBUG_OCCLUSION | @@ -2716,8 +3003,8 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | LLPipeline::RENDER_DEBUG_RAYCAST | - LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | - LLPipeline::RENDER_DEBUG_AGENT_TARGET)) + LLPipeline::RENDER_DEBUG_BUILD_QUEUE | + LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { return; } @@ -2752,6 +3039,12 @@ void LLSpatialPartition::renderDebug() render_debug.traverse(mOctree); } +void LLSpatialGroup::drawObjectBox(LLColor4 col) +{ + gGL.color4fv(col.mV); + drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); +} + BOOL LLSpatialPartition::isVisible(const LLVector3& v) { @@ -2896,11 +3189,12 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, con } LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* texture, LLVertexBuffer* buffer, + LLImageGL* gl_texture, LLViewerImage* texture, LLVertexBuffer* buffer, BOOL fullbright, U8 bump, BOOL particle, F32 part_size) : mVertexBuffer(buffer), - mTexture(texture), + mTexture(gl_texture), + mViewerTexture(texture), mTextureMatrix(NULL), mModelMatrix(NULL), mStart(start), @@ -2920,22 +3214,22 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, if (mStart >= mVertexBuffer->getRequestedVerts() || mEnd >= mVertexBuffer->getRequestedVerts()) { - llerrs << "Invalid draw info vertex range." << llendl; + llwarns << "Invalid draw info vertex range." << llendl; } if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) { - llerrs << "Invalid draw info index range." << llendl; + llwarns << "Invalid draw info index range." << llendl; } } LLDrawInfo::~LLDrawInfo() { - if (LLSpatialGroup::sNoDelete) + /*if (LLSpatialGroup::sNoDelete) { - llerrs << "LLDrawInfo deleted illegally!" << llendl; - } + llwarns << "LLDrawInfo deleted illegally!" << llendl; + }*/ if (mFace) { @@ -3140,7 +3434,7 @@ void LLCullResult::assertDrawMapsEmpty() { if (mRenderMapSize[i] != 0) { - llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl; + llwarns << "Stale LLDrawInfo's in LLCullResult!" << llendl; } } } diff --git a/linden/indra/newview/llspatialpartition.h b/linden/indra/newview/llspatialpartition.h index df96152df..8af5222e4 100644 --- a/linden/indra/newview/llspatialpartition.h +++ b/linden/indra/newview/llspatialpartition.h @@ -52,6 +52,8 @@ class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; +class LLTextureAtlas; +class LLTextureAtlasSlot; S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); @@ -66,12 +68,13 @@ class LLDrawInfo : public LLRefCount public: LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* image, LLVertexBuffer* buffer, + LLImageGL* gl_image, LLViewerImage* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); LLPointer<LLVertexBuffer> mVertexBuffer; - LLPointer<LLViewerImage> mTexture; + LLPointer<LLImageGL> mTexture; + LLPointer<LLViewerImage> mViewerTexture; LLColor4U mGlowColor; S32 mDebugColor; const LLMatrix4* mTextureMatrix; @@ -159,11 +162,13 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t; typedef std::set<LLPointer<LLSpatialGroup> > sg_set_t; + typedef std::list<LLPointer<LLSpatialGroup> > sg_list_t; typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t; typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t; typedef std::map<U32, drawmap_elem_t > draw_map_t; typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t; - typedef std::map<LLPointer<LLViewerImage>, buffer_list_t> buffer_texture_map_t; + typedef std::map<LLPointer<LLImageGL>, buffer_list_t> buffer_texture_map_t; // KL render-pipeline +// typedef std::map<LLPointer<LLViewerImage>, buffer_list_t> buffer_texture_map_t; // KL standard typedef std::map<U32, buffer_texture_map_t> buffer_map_t; typedef LLOctreeListener<LLDrawable> BaseType; @@ -183,6 +188,14 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> } }; + struct CompareUpdateUrgency + { + bool operator()(const LLPointer<LLSpatialGroup> lhs, const LLPointer<LLSpatialGroup> rhs) + { + return lhs->getUpdateUrgency() > rhs->getUpdateUrgency(); + } + }; + struct CompareDepthGreater { bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs) @@ -209,6 +222,10 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> IMAGE_DIRTY = 0x00004000, OCCLUSION_DIRTY = 0x00008000, MESH_DIRTY = 0x00010000, + NEW_DRAWINFO = 0x00020000, + IN_BUILD_Q1 = 0x00040000, + IN_BUILD_Q2 = 0x00080000, + } eSpatialState; typedef enum @@ -252,6 +269,7 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> void updateDistance(LLCamera& camera); BOOL needsUpdate(); + F32 getUpdateUrgency() const; BOOL changeLOD(); void rebuildGeom(); void rebuildMesh(); @@ -261,6 +279,8 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> element_list& getData() { return mOctreeNode->getData(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } + void drawObjectBox(LLColor4 col); + //LISTENER FUNCTIONS virtual void handleInsertion(const TreeNode* node, LLDrawable* face); virtual void handleRemoval(const TreeNode* node, LLDrawable* face); @@ -269,6 +289,36 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); +//------------------- +//for atlas use +//------------------- + //atlas + void setCurUpdatingTime(U32 t) {mCurUpdatingTime = t ;} + U32 getCurUpdatingTime() const { return mCurUpdatingTime ;} + + void setCurUpdatingSlot(LLTextureAtlasSlot* slotp) ; + LLTextureAtlasSlot* getCurUpdatingSlot(LLViewerImage* imagep, S8 recursive_level = 3) ; + + void setCurUpdatingTexture(LLViewerImage* tex){ mCurUpdatingTexture = tex ;} + LLViewerImage* getCurUpdatingTexture() const { return mCurUpdatingTexture ;} + + BOOL hasAtlas(LLTextureAtlas* atlasp) ; + LLTextureAtlas* getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level = 3) ; + void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; + void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; + void clearAtlasList() ; +private: + U32 mCurUpdatingTime ; + //do not make the below two to use LLPointer + //because mCurUpdatingTime invalidates them automatically. + LLTextureAtlasSlot* mCurUpdatingSlotp ; + LLViewerImage* mCurUpdatingTexture ; + + std::vector< std::list<LLTextureAtlas*> > mAtlasList ; +//------------------- +//end for atlas use +//------------------- + protected: virtual ~LLSpatialGroup(); @@ -327,7 +377,7 @@ class LLSpatialPartition: public LLGeometryManager public: static BOOL sFreezeState; //if true, no spatialgroup state updates will be made - LLSpatialPartition(U32 data_mask, U32 mBufferUsage = GL_STATIC_DRAW_ARB); + LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -373,7 +423,7 @@ class LLSpatialPartition: public LLGeometryManager BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; - BOOL mRenderByGroup; + const BOOL mRenderByGroup; U32 mLODSeed; U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) U32 mVertexDataMask; @@ -392,7 +442,7 @@ class LLSpatialBridge : public LLDrawable, public LLSpatialPartition public: typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t; - LLSpatialBridge(LLDrawable* root, U32 data_mask); + LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); virtual BOOL isSpatialBridge() const { return TRUE; } diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 87d48c840..237a967d3 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -3723,7 +3723,7 @@ void init_start_screen(S32 location_id) } raw->expandToPowerOfTwo(); - gStartImageGL->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + gStartImageGL->createGLTexture(0, raw); } diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index a27f0e225..2e20aced1 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp @@ -149,7 +149,7 @@ LLSurface::~LLSurface() } else { - llerrs << "Terrain pool not empty!" << llendl; + llwarns << "Terrain pool not empty!" << llendl; } } @@ -238,6 +238,7 @@ void LLSurface::createSTexture() if (!mSTexturep) { // Fill with dummy gray data. + // GL NOT ACTIVE HERE LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3); U8 *default_texture = raw->getData(); for (S32 i = 0; i < sTextureSize; i++) @@ -255,6 +256,7 @@ void LLSurface::createSTexture() gGL.getTexUnit(0)->bind(mSTexturep.get()); mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); gImageList.addImage(mSTexturep); + } } @@ -275,9 +277,10 @@ void LLSurface::createWaterTexture() *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; } } - mWaterTexturep = new LLViewerImage(raw, FALSE); + + mWaterTexturep = new LLViewerImage(sTextureSize/2, sTextureSize/2, 4, FALSE); mWaterTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mWaterTexturep.get()); + gGL.getTexUnit(0)->bind(mWaterTexturep); mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); gImageList.addImage(mWaterTexturep); } @@ -629,6 +632,8 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent) BOOL LLSurface::idleUpdate(F32 max_update_time) { +//SG2: LLMemType mt_ius(LLMemType::MTYPE_IDLE_UPDATE_SURFACE); + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN)) { return FALSE; @@ -1133,12 +1138,12 @@ LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const { if ((x < 0) || (x >= mPatchesPerEdge)) { - llerrs << "Asking for patch out of bounds" << llendl; + llwarns << "Asking for patch out of bounds" << llendl; return NULL; } if ((y < 0) || (y >= mPatchesPerEdge)) { - llerrs << "Asking for patch out of bounds" << llendl; + llwarns << "Asking for patch out of bounds" << llendl; return NULL; } @@ -1277,6 +1282,11 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, } } + if (!mWaterTexturep->getHasGLTexture()) + { + mWaterTexturep->createGLTexture(0, raw); + } + mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); return TRUE; } diff --git a/linden/indra/newview/llsurfacepatch.cpp b/linden/indra/newview/llsurfacepatch.cpp index 5fac5fd1e..04b732a89 100644 --- a/linden/indra/newview/llsurfacepatch.cpp +++ b/linden/indra/newview/llsurfacepatch.cpp @@ -712,17 +712,7 @@ BOOL LLSurfacePatch::updateTexture() if (mVObjp) { mVObjp->dirtyGeom(); - } - updateCompositionStats(); - F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], - tex_patch_size, tex_patch_size)) - { - mSTexUpdate = FALSE; - - // Also generate the water texture - mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], - tex_patch_size, tex_patch_size); + gPipeline.markGLRebuild(mVObjp); return TRUE; } } @@ -735,6 +725,28 @@ BOOL LLSurfacePatch::updateTexture() } } +void LLSurfacePatch::updateGL() // KL SD +{ + F32 meters_per_grid = getSurface()->getMetersPerGrid(); + F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); + + LLViewerRegion *regionp = getSurface()->getRegion(); + LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); + + LLVLComposition* comp = regionp->getComposition(); + + updateCompositionStats(); + F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; + if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], + tex_patch_size, tex_patch_size)) + { + mSTexUpdate = FALSE; + + // Also generate the water texture + mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], + tex_patch_size, tex_patch_size); + } +} // KL void LLSurfacePatch::dirtyZ() { diff --git a/linden/indra/newview/llsurfacepatch.h b/linden/indra/newview/llsurfacepatch.h index 7e84f7f6c..1f9658d4a 100644 --- a/linden/indra/newview/llsurfacepatch.h +++ b/linden/indra/newview/llsurfacepatch.h @@ -90,6 +90,7 @@ class LLSurfacePatch void updateCameraDistanceRegion( const LLVector3 &pos_region); void updateVisibility(); + void updateGL(); void dirtyZ(); // Dirty the z values of this patch void setHasReceivedData(); diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp index 5175cbb77..fb5be846d 100644 --- a/linden/indra/newview/lltexlayer.cpp +++ b/linden/indra/newview/lltexlayer.cpp @@ -813,14 +813,19 @@ void LLTexLayerSet::requestUpdate() if( mUpdatesEnabled ) { createComposite(); - mComposite->requestUpdate(); + if (mComposite) + { + mComposite->requestUpdate(); + } } } void LLTexLayerSet::requestUpload() { - createComposite(); - mComposite->requestUpload(); + if (mComposite) + { + mComposite->requestUpload(); + } } void LLTexLayerSet::cancelUpload() @@ -834,6 +839,15 @@ void LLTexLayerSet::cancelUpload() void LLTexLayerSet::createComposite() { if( !mComposite ) + { + gPipeline.markGLRebuild(this); + } + //updateGL(); // KL +} + +void LLTexLayerSet::updateGL() +{ + if (!mComposite) { S32 width = mInfo->mWidth; S32 height = mInfo->mHeight; @@ -865,7 +879,7 @@ void LLTexLayerSet::setUpdatesEnabled( BOOL b ) void LLTexLayerSet::updateComposite() { createComposite(); - mComposite->updateImmediate(); + //mComposite->updateImmediate(); //KL exception here this needs fixing for S19 } LLTexLayerSetBuffer* LLTexLayerSet::getComposite() @@ -2104,7 +2118,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height ) // Create the GL texture, and then hang onto it for future use. if( mNeedsCreateTexture ) { - mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerImageBoostLevel::TEXLAYER_CACHE); + mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0); mNeedsCreateTexture = FALSE; gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -2560,7 +2574,7 @@ LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL i image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); } - image_gl->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + image_gl->createGLTexture(0, image_raw, 0); gGL.getTexUnit(0)->bind(image_gl); image_gl->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/linden/indra/newview/lltexlayer.h b/linden/indra/newview/lltexlayer.h index 020ba86f1..b841fa3b0 100644 --- a/linden/indra/newview/lltexlayer.h +++ b/linden/indra/newview/lltexlayer.h @@ -249,7 +249,7 @@ class LLTexLayerSetBuffer : public LLDynamicTexture // LLTexLayerSet // An ordered set of texture layers that get composited into a single texture. //----------------------------------------------------------------------------- -class LLTexLayerSet +class LLTexLayerSet : public LLGLUpdate { friend class LLTexLayerSetBuffer; public: @@ -284,7 +284,7 @@ class LLTexLayerSet LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } BOOL isVisible() const { return mIsVisible; } - + /*virtual*/ void updateGL(); public: static BOOL sHasCaches; diff --git a/linden/indra/newview/lltextureatlasmanager.cpp b/linden/indra/newview/lltextureatlasmanager.cpp new file mode 100644 index 000000000..df6a39de4 --- /dev/null +++ b/linden/indra/newview/lltextureatlasmanager.cpp @@ -0,0 +1,274 @@ +/** + * @file lltextureatlasmanager.cpp + * @brief LLTextureAtlasManager class implementation. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" +#include "linden_common.h" +#include "llerror.h" +#include "llmath.h" +#include "lltextureatlas.h" +#include "lltextureatlasmanager.h" +#include "llspatialpartition.h" + +const S8 MAX_NUM_EMPTY_ATLAS = 2 ; +const F32 MIN_ATLAS_FULLNESS = 0.6f ; + +//********************************************************************************************* +//implementation of class LLTextureAtlasInfo +//********************************************************************************************* +LLTextureAtlasSlot::LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) : + mAtlasp(atlasp), + mGroupp(groupp), + mCol(col), + mRow(row), + mReservedSlotWidth(slot_width), + mValid(FALSE), + mUpdatedTime(0), + mTexCoordOffset(xoffset, yoffset), + mTexCoordScale(1.f, 1.f) +{ + llassert_always(mAtlasp || mGroupp || mReservedSlotWidth) ; +} + +LLTextureAtlasSlot::~LLTextureAtlasSlot() +{ + if(mAtlasp) + { + mAtlasp->releaseSlot(mCol, mRow, mReservedSlotWidth) ; + if(mAtlasp->isEmpty()) + { + LLTextureAtlasManager::getInstance()->releaseAtlas(mAtlasp) ; + } + mAtlasp = NULL ; + } +} + +//void LLTextureAtlasSlot::setAtlas(LLTextureAtlas* atlasp) +//{ +// mAtlasp = atlasp ; +//} +//void LLTextureAtlasSlot::setSlotPos(S16 col, S16 row) +//{ +// mCol = col ; +// mRow = row ; +//} +//void LLTextureAtlasSlot::setSlotWidth(S8 width) +//{ +// //slot is a square with each edge length a power-of-two number +// mReservedSlotWidth = width ; +//} +//void LLTextureAtlasSlot::setTexCoordOffset(F32 xoffset, F32 yoffset) +//{ +// mTexCoordOffset.mV[0] = xoffset ; +// mTexCoordOffset.mV[1] = yoffset ; +//} + +void LLTextureAtlasSlot::setSpatialGroup(LLSpatialGroup* groupp) +{ + mGroupp = groupp ; +} +void LLTextureAtlasSlot::setTexCoordScale(F32 xscale, F32 yscale) +{ + mTexCoordScale.mV[0] = xscale ; + mTexCoordScale.mV[1] = yscale ; +} +//********************************************************************************************* +//END of implementation of class LLTextureAtlasInfo +//********************************************************************************************* + +//********************************************************************************************* +//implementation of class LLTextureAtlasManager +//********************************************************************************************* +LLTextureAtlasManager::LLTextureAtlasManager() : + mAtlasMap(4), + mEmptyAtlasMap(4) +{ +} + +LLTextureAtlasManager::~LLTextureAtlasManager() +{ + for(S32 i = 0 ; i < 4 ; i++) + { + for(ll_texture_atlas_list_t::iterator j = mAtlasMap[i].begin() ; j != mAtlasMap[i].end() ; ++j) + { + *j = NULL ; + } + for(ll_texture_atlas_list_t::iterator j = mEmptyAtlasMap[i].begin() ; j != mEmptyAtlasMap[i].end() ; ++j) + { + *j = NULL ; + } + + mAtlasMap[i].clear() ; + mEmptyAtlasMap[i].clear() ; + } + mAtlasMap.clear() ; + mEmptyAtlasMap.clear() ; +} + +//return TRUE if qualified +BOOL LLTextureAtlasManager::canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) +{ + if(ncomponents < 1 || ncomponents > 4) + { + return FALSE ; + } + //only support GL_TEXTURE_2D + if(GL_TEXTURE_2D != target) + { + return FALSE ; + } + //real image size overflows + if(w < 8 || w > LLTextureAtlas::sMaxSubTextureSize || h < 8 || h > LLTextureAtlas::sMaxSubTextureSize) + { + return FALSE ; + } + + //if non-power-of-two number + if((w & (w - 1)) || (h & (h - 1))) + { + return FALSE ; + } + + return TRUE ; +} + +void LLTextureAtlasManager::releaseAtlas(LLTextureAtlas* atlasp) +{ + LLSpatialGroup* groupp = atlasp->getLastSpatialGroup() ; + while(groupp) + { + groupp->removeAtlas(atlasp, FALSE) ; + atlasp->removeLastSpatialGroup() ; + + groupp = atlasp->getLastSpatialGroup() ; + } + + S8 type = atlasp->getComponents() - 1 ; + //insert to the empty list + if(mEmptyAtlasMap[type].size() < MAX_NUM_EMPTY_ATLAS) + { + mEmptyAtlasMap[type].push_back(atlasp) ; + } + + //delete the atlasp + mAtlasMap[type].remove(atlasp) ; +} + +// +//this function reserves an appropriate slot from atlas pool for an image. +//return non-NULL if succeeds. +//Note: +//1, this function does not check if the image this slot assigned for qualifies for atlas or not, +// call LLTextureAtlasManager::canAddToAtlas(...) to do the check before calling this function. +//2, this function also dose not check if the image is already in atlas. It always assigns a new slot anyway. +//3, this function tries to group sub-textures from same spatial group into ONE atlas to improve render batching. +// +LLPointer<LLTextureAtlasSlot> LLTextureAtlasManager::reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, + LLSpatialGroup* groupp, LLViewerImage* imagep) +{ + if(!groupp) + { + //do not insert to atlas if does not have a group. + return NULL ; + } + + //bits_len must <= 8 and is a power of two number, i.e.: must be one of these numbers: 1, 2, 4, 8. + if(sub_texture_size > LLTextureAtlas::sMaxSubTextureSize) + { + sub_texture_size = LLTextureAtlas::sMaxSubTextureSize ; + } + S8 bits_len = sub_texture_size / LLTextureAtlas::sSlotSize ; + if(bits_len < 1) + { + bits_len = 1 ; + } + + S16 col = -1, row = -1; + S8 total_bits = bits_len * bits_len ; + + //insert to the atlas reserved by the same spatial group + LLPointer<LLTextureAtlas> atlasp = groupp->getAtlas(ncomponents, total_bits) ; + if(atlasp.notNull()) + { + if(!atlasp->getNextAvailableSlot(bits_len, col, row)) + { + //failed + atlasp = NULL ; + } + } + + //search an atlas to fit for 'size' + if(!atlasp) + { + S8 atlas_index = ncomponents - 1 ; + ll_texture_atlas_list_t::iterator iter = mAtlasMap[atlas_index].begin() ; + for(; iter != mAtlasMap[atlas_index].end(); ++iter) + { + LLTextureAtlas* cur = (LLTextureAtlas*)*iter ; + if(cur->getFullness() < MIN_ATLAS_FULLNESS)//this atlas is empty enough for this group to insert more sub-textures later if necessary. + { + if(cur->getNextAvailableSlot(bits_len, col, row)) + { + atlasp = cur ; + groupp->addAtlas(atlasp) ; + break ; + } + } + } + } + + //create a new atlas if necessary + if(!atlasp) + { + if(mEmptyAtlasMap[ncomponents - 1].size() > 0) + { + //there is an empty one + atlasp = mEmptyAtlasMap[ncomponents - 1].back() ; + mEmptyAtlasMap[ncomponents - 1].pop_back() ; + } + else + { + atlasp = new LLTextureAtlas(ncomponents, 16) ; + } + mAtlasMap[ncomponents - 1].push_back(atlasp) ; + atlasp->getNextAvailableSlot(bits_len, col, row) ; + groupp->addAtlas(atlasp) ; + } + + F32 xoffset, yoffset ; + atlasp->getTexCoordOffset(col, row, xoffset, yoffset) ; + LLPointer<LLTextureAtlasSlot> slot_infop = new LLTextureAtlasSlot(atlasp, groupp, col, row, xoffset, yoffset, bits_len) ; + + return slot_infop ; +} + +//********************************************************************************************* +//END of implementation of class LLTextureAtlasManager +//********************************************************************************************* diff --git a/linden/indra/newview/lltextureatlasmanager.h b/linden/indra/newview/lltextureatlasmanager.h new file mode 100644 index 000000000..70689bf33 --- /dev/null +++ b/linden/indra/newview/lltextureatlasmanager.h @@ -0,0 +1,112 @@ +/** + * @file lltextureatlasmanager.h + * @brief LLTextureAtlasManager base class. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#ifndef LL_TEXTUREATLASMANAGER_H +#define LL_TEXTUREATLASMANAGER_H + +#include "llmemory.h" + +class LLSpatialGroup ; +class LLViewerImage ; + +//just use it as a structure. +class LLTextureAtlasSlot : public LLRefCount +{ +public: + LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) ; + +protected: + virtual ~LLTextureAtlasSlot(); + +public: + + // + //do not allow to change those values + // + //void setAtlas(LLTextureAtlas* atlasp) ; + //void setSlotPos(S16 col, S16 row) ; + //void setSlotWidth(S8 width) ; + //void setTexCoordOffset(F32 xoffser, F32 yoffset) ; + // + + void setSpatialGroup(LLSpatialGroup* groupp) ; + void setTexCoordScale(F32 xscale, F32 yscale) ; + void setValid() {mValid = TRUE ;} + + LLTextureAtlas* getAtlas()const {return mAtlasp;} + LLSpatialGroup* getSpatialGroup() const {return mGroupp ;} + S16 getSlotCol()const {return mCol;} + S16 getSlotRow()const {return mRow;} + S8 getSlotWidth()const{return mReservedSlotWidth;} + BOOL isValid()const { return mValid;} + const LLVector2* getTexCoordOffset()const {return &mTexCoordOffset;} + const LLVector2* getTexCoordScale() const {return &mTexCoordScale;} + + void setUpdatedTime(U32 t) {mUpdatedTime = t;} + U32 getUpdatedTime()const {return mUpdatedTime;} + +private: + LLTextureAtlas* mAtlasp; + S16 mCol ;//col of the slot + S16 mRow ;//row of the slot + S8 mReservedSlotWidth ; //slot is a square with each edge length a power-of-two number + LLSpatialGroup* mGroupp ; + BOOL mValid ; + + LLVector2 mTexCoordOffset ; + LLVector2 mTexCoordScale ; + + U32 mUpdatedTime ; +} ; + +class LLTextureAtlasManager : public LLSingleton<LLTextureAtlasManager> +{ +private: + typedef std::list<LLPointer<LLTextureAtlas> > ll_texture_atlas_list_t ; + +public: + LLTextureAtlasManager(); + ~LLTextureAtlasManager(); + + LLPointer<LLTextureAtlasSlot> reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, + LLSpatialGroup* groupp, LLViewerImage* imagep) ; + void releaseAtlas(LLTextureAtlas* atlasp); + + BOOL canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) ; + +private: + std::vector<ll_texture_atlas_list_t> mAtlasMap ; + std::vector<ll_texture_atlas_list_t> mEmptyAtlasMap ; //delay some empty atlases deletion to avoid possible creation of new atlas immediately. +}; + +#endif diff --git a/linden/indra/newview/lltextureview.cpp b/linden/indra/newview/lltextureview.cpp index 04cebf580..903a6e5e1 100644 --- a/linden/indra/newview/lltextureview.cpp +++ b/linden/indra/newview/lltextureview.cpp @@ -57,14 +57,16 @@ extern F32 texmem_lower_bound_scale; LLTextureView *gTextureView = NULL; +LLTextureSizeView *gTextureSizeView = NULL; +LLTextureSizeView *gTextureCategoryView = NULL; //static std::set<LLViewerImage*> LLTextureView::sDebugImages; //////////////////////////////////////////////////////////////////////////// -static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max"); -static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max"); +static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download]"); +static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download]"); static std::string title_string2("State"); static std::string title_string3("Pkt Bnd"); static std::string title_string4(" W x H (Dis) Mem"); @@ -201,13 +203,14 @@ void LLTextureBar::draw() } else { - tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)", + tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x) %1.2f", uuid_str.c_str(), mImagep->mMaxVirtualSize, mImagep->mDesiredDiscardLevel, mImagep->mRequestedDiscardLevel, mImagep->getDecodePriority(), - mImagep->mFetchPriority); + mImagep->mFetchPriority, + mImagep->mDownloadProgress); } LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(), @@ -253,7 +256,7 @@ void LLTextureBar::draw() // Draw the progress bar. S32 bar_width = 100; - S32 bar_left = 260; + S32 bar_left = 330; left = bar_left; right = left + bar_width; @@ -262,7 +265,7 @@ void LLTextureBar::draw() F32 data_progress = mImagep->mDownloadProgress; - if (data_progress > 0.0f) + if (data_progress > 0.0f && data_progress <= 1.0f) { // Downloaded bytes right = left + llfloor(data_progress * (F32)bar_width); @@ -272,6 +275,16 @@ void LLTextureBar::draw() gl_rect_2d(left, top, right, bottom); } } + else if (data_progress > 1.0f) + { + // Small cached textures generate this oddity. SNOW-168 + right = left + bar_width; + if (right > left) + { + gGL.color4f(0.f, 0.33f, 0.f, 0.75f); + gl_rect_2d(left, top, right, bottom); + } + } S32 pip_width = 6; S32 pip_space = 14; @@ -386,9 +399,9 @@ class LLGLTexMemBar : public LLView void LLGLTexMemBar::draw() { - S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes); + S32 bound_mem = (LLViewerImage::sBoundTextureMemoryInBytes >> 20); S32 max_bound_mem = LLViewerImage::sMaxBoundTextureMemInMegaBytes; - S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sTotalTextureMemoryInBytes); + S32 total_mem = (LLViewerImage::sTotalTextureMemoryInBytes >> 20); S32 max_total_mem = LLViewerImage::sMaxTotalTextureMemInMegaBytes; F32 discard_bias = LLViewerImage::sDesiredDiscardBias; S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); @@ -478,28 +491,25 @@ void LLGLTexMemBar::draw() #endif //---------------------------------------------------------------------------- - text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d RAW:%d HTP:%d", + text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d RAW:%d HTP:%d BW: %.0f/%.0f", gImageList.getNumImages(), - LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), - LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, - LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(), + LLAppViewer::getTextureFetch()->getNumRequests(), + LLAppViewer::getTextureFetch()->getNumDeletes(), + LLAppViewer::getTextureFetch()->mPacketCount, + LLAppViewer::getTextureFetch()->mBadPacketCount, + LLAppViewer::getTextureCache()->getNumReads(), + LLAppViewer::getTextureCache()->getNumWrites(), LLLFSThread::sLocal->getPending(), LLAppViewer::getImageDecodeThread()->getPending(), LLImageRaw::sRawImageCount, - LLAppViewer::getTextureFetch()->getNumHTTPRequests()); + LLAppViewer::getTextureFetch()->getNumHTTPRequests(), + LLAppViewer::getTextureFetch()->getTextureBandwidth(), + gSavedSettings.getF32("ThrottleBandwidthKBPS")); LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*2, text_color, LLFontGL::LEFT, LLFontGL::TOP); - - left = 550; - F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth(); - F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); - color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color; - color[VALPHA] = text_color[VALPHA]; - text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*2, - color, LLFontGL::LEFT, LLFontGL::TOP); + left = 600; S32 dx1 = 0; if (LLAppViewer::getTextureFetch()->mDebugPause) @@ -566,7 +576,7 @@ class LLGLTexSizeBar void setTop(S32 loaded, S32 bound, F32 scale) {mTopLoaded = loaded ; mTopBound = bound; mScale = scale ;} void draw(); - BOOL handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) ; + BOOL handleHover(S32 x, S32 y, MASK mask) ; private: S32 mIndex ; @@ -579,16 +589,19 @@ class LLGLTexSizeBar F32 mScale ; }; -BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) +BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask) { +#if !LL_RELEASE_FOR_DOWNLOAD if(y > mBottom && (y < mBottom + (S32)(mTopLoaded * mScale) || y < mBottom + (S32)(mTopBound * mScale))) { - LLImageGL::setCurTexSizebar(mIndex, set_pick_size); + LLImageGL::setCurTexSizebar(mIndex); } +#endif return TRUE ; } void LLGLTexSizeBar::draw() { +#if !LL_RELEASE_FOR_DOWNLOAD LLGLSUIDefault gls_ui; if(LLImageGL::sCurTexSizeBar == mIndex) @@ -609,6 +622,7 @@ void LLGLTexSizeBar::draw() F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ; gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ; +#endif } //////////////////////////////////////////////////////////////////////////// @@ -913,31 +927,7 @@ LLTextureSizeView::~LLTextureSizeView() } void LLTextureSizeView::draw() { - if(mType == TEXTURE_MEM_OVER_SIZE) - { - drawTextureSizeGraph(); - } - else - { - drawTextureCategoryGraph() ; - } - - LLView::draw(); -} - -BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) -{ - if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) - { - mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ; - } - - return TRUE ; -} - -//draw real-time texture mem bar over size -void LLTextureSizeView::drawTextureSizeGraph() -{ +#if !LL_RELEASE_FOR_DOWNLOAD if(mTextureSizeBar.size() == 0) { S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); @@ -958,16 +948,29 @@ void LLTextureSizeView::drawTextureSizeGraph() mTextureSizeBar[i]->draw() ; } LLImageGL::resetCurTexSizebar(); + + LLView::draw(); +#endif +} + +BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) +{ + if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) + { + mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask) ; + } + + return TRUE ; } //draw background of texture size bar graph F32 LLTextureSizeView::drawTextureSizeDistributionGraph() { - //scale F32 scale = 1.0f ; - +#if !LL_RELEASE_FOR_DOWNLOAD LLGLSUIDefault gls_ui; + //scale { S32 count = 0 ; for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++) @@ -1055,138 +1058,9 @@ F32 LLTextureSizeView::drawTextureSizeDistributionGraph() //title text = llformat("Texture Size Distribution") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - return scale ; -} - -//draw real-time texture mem bar over category -void LLTextureSizeView::drawTextureCategoryGraph() -{ - if(mTextureSizeBar.size() == 0) - { - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - mTextureSizeBar.resize(LLImageGL::sTextureMemByCategory.size()) ; - mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; - - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth , - line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ; - } - } - - F32 size_bar_scale = drawTextureCategoryDistributionGraph() ; - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[i] >> 20, LLImageGL::sTextureMemByCategoryBound[i] >> 20, size_bar_scale) ; - mTextureSizeBar[i]->draw() ; - } - LLImageGL::resetCurTexSizebar(); -} - -//draw background for TEXTURE_MEM_OVER_CATEGORY -F32 LLTextureSizeView::drawTextureCategoryDistributionGraph() -{ - //scale - F32 scale = 4.0f ; - - LLGLSUIDefault gls_ui; - - { - S32 count = 0 ; - for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++) - { - S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ; - if(tmp > count) - { - count = tmp ; - } - } - if(count > mTextureSizeBarRect.getHeight() * 0.25f) - { - scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ; - } - } - - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 left = mTextureSizeBarRect.mLeft ; - S32 bottom = mTextureSizeBarRect.mBottom ; - S32 right = mTextureSizeBarRect.mRight ; - S32 top = mTextureSizeBarRect.mTop ; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - //background rect - gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); - gl_line_2d(left, bottom, right, bottom) ; //x axis - gl_line_2d(left, bottom, left, top) ; //y axis - - //ruler - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - gl_line_2d(left, i, right, i) ; - } - - //texts - //-------------------------------------------------- - F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; - std::string text; - - //------- - //x axis: size label - static char category[LLViewerImageBoostLevel::MAX_GL_IMAGE_CATEGORY][4] = - {"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Tbp", "Scr", "Fnt", "Bmp", "Dyn", "Tlc", "Mdi", "ALT", "Oth" } ; - - text = llformat("%s", category[0]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) - { - text = llformat("%s", category[i]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - //------- - - //y axis: number label - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - text = llformat("%d", (S32)((i - bottom) / scale)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - - text = llformat("MB") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - //-------------------------------------------------- - F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; - text = llformat("Loaded") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, - loaded_color, - LLFontGL::LEFT, LLFontGL::TOP); - - F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; - text = llformat("Bound") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, - bound_color, LLFontGL::LEFT, LLFontGL::TOP); - - //-------------------------------------------------- - - //title - text = llformat("Texture Category Distribution") ; LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, text_color, LLFontGL::LEFT, LLFontGL::TOP); +#endif return scale ; } diff --git a/linden/indra/newview/lltoolpie.h b/linden/indra/newview/lltoolpie.h index 001886f72..54bf4094a 100644 --- a/linden/indra/newview/lltoolpie.h +++ b/linden/indra/newview/lltoolpie.h @@ -86,7 +86,6 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie> LLPickInfo mPick; U8 mClickAction; LLSafeHandle<LLObjectSelection> mLeftClickSelection; -protected: LLPointer<LLViewerObject> mClickActionObject; }; diff --git a/linden/indra/newview/llviewercamera.cpp b/linden/indra/newview/llviewercamera.cpp index dade65f1a..6cef2af27 100644 --- a/linden/indra/newview/llviewercamera.cpp +++ b/linden/indra/newview/llviewercamera.cpp @@ -769,8 +769,8 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0; - if (( !in_frustum && all_verts) || - (in_frustum && !all_verts)) + if ( !in_frustum && all_verts || + in_frustum && !all_verts) { return !all_verts; } diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 1531e6c03..4c9c0983f 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -90,7 +90,7 @@ std::string gCurrentVersion; extern BOOL gResizeScreenTexture; extern BOOL gDebugGL; -extern BOOL gAuditTexture; +//extern BOOL gAuditTexture; //////////////////////////////////////////////////////////////////////////// // Listeners @@ -418,12 +418,12 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue) LLVOAvatar::sUseImpostors = newvalue.asBoolean(); return true; } - +/* static bool handleAuditTextureChanged(const LLSD& newvalue) { gAuditTexture = newvalue.asBoolean(); return true; -} +}*/ static bool handleRenderDebugGLChanged(const LLSD& newvalue) { @@ -528,6 +528,11 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + + gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("EnableRippleWater")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); @@ -539,6 +544,9 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _1)); gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _1)); gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1)); + gSavedSettings.getControl("RenderDeferredShadow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1)); gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _1)); gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1)); @@ -584,7 +592,7 @@ void settings_setup_listeners() gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _1)); - gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); +// gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index ad186d58c..8e066c821 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -128,6 +128,11 @@ void display_startup() return; } + gPipeline.updateGL(); + + // Update images? + gImageList.updateImages(0.01f); + LLGLSDefault gls_default; // Required for HTML update in login screen @@ -599,6 +604,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.updateGeom(max_geom_update_time); stop_glerror(); + gPipeline.updateGL(); + stop_glerror(); + gFrameStats.start(LLFrameStats::UPDATE_CULL); S32 water_clip = 0; if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && @@ -688,6 +696,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } + LLVertexBuffer::unbind(); // KL + LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); @@ -718,6 +728,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); + gPipeline.generateHighlight(*LLViewerCamera::getInstance()); } ////////////////////////////////////// @@ -742,6 +753,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) gImageList.updateImages(max_image_decode_time); + + //remove dead textures from GL KL is it req? + LLImageGL::deleteDeadTextures(); stop_glerror(); } llpushcallstacks ; @@ -896,7 +910,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) /// and then display it again with compositor effects. /// Using render to texture would be faster/better, but I don't have a /// grasp of their full display stack just yet. - // gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); + gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); // KL if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { @@ -912,6 +926,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) render_ui(); } + gPipeline.rebuildGroups(); + LLSpatialGroup::sNoDelete = FALSE; } @@ -998,6 +1014,15 @@ void render_hud_attachments() gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); gPipeline.stateSort(hud_cam, result); diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index 400fb2f1f..93c17a2b8 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp @@ -60,6 +60,8 @@ #include "pipeline.h" #include "llappviewer.h" #include "llface.h" +#include "lltextureatlas.h" +#include "lltextureatlasmanager.h" #include "llviewercamera.h" /////////////////////////////////////////////////////////////////////////////// @@ -102,7 +104,7 @@ void LLViewerImage::initClass() sNullImagep = new LLImageGL(1,1,3,TRUE); LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3); raw->clear(0x77, 0x77, 0x77, 0xFF); - sNullImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + sNullImagep->createGLTexture(0, raw); #if 1 LLPointer<LLViewerImage> imagep = new LLViewerImage(IMG_DEFAULT); @@ -131,7 +133,7 @@ void LLViewerImage::initClass() } } } - imagep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + imagep->createGLTexture(0, image_raw); image_raw = NULL; gImageList.addImage(imagep); imagep->dontDiscard(); @@ -141,48 +143,48 @@ void LLViewerImage::initClass() sSmokeImagep = gImageList.getImage(IMG_SMOKE, TRUE, TRUE); sSmokeImagep->setNoDelete() ; - if(gAuditTexture) +#if !LL_RELEASE_FOR_DOWNLOAD + sDefaultTexturep = new LLImageGL() ; + image_raw = new LLImageRaw(dim,dim,3); + data = image_raw->getData(); + for (S32 i = 0; i<dim; i++) { - sDefaultTexturep = new LLImageGL() ; - image_raw = new LLImageRaw(dim,dim,3); - data = image_raw->getData(); - for (S32 i = 0; i<dim; i++) + for (S32 j = 0; j<dim; j++) { - for (S32 j = 0; j<dim; j++) + const S32 border = 2; + if (i<border || j<border || i>=(dim-border) || j>=(dim-border)) { - const S32 border = 2; - if (i<border || j<border || i>=(dim-border) || j>=(dim-border)) - { - *data++ = 0xff; - *data++ = 0xff; - *data++ = 0xff; - } - else - { - *data++ = 0xff; - *data++ = 0xff; - *data++ = 0x00; - } + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0xff; + } + else + { + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0x00; } } - sDefaultTexturep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); - image_raw = NULL; - sDefaultTexturep->dontDiscard(); } + sDefaultTexturep->createGLTexture(0, image_raw); + image_raw = NULL; + sDefaultTexturep->dontDiscard(); +#endif } // static void LLViewerImage::cleanupClass() { stop_glerror(); - LLImageGL::cleanupClass() ; - sNullImagep = NULL; sDefaultImagep = NULL; sSmokeImagep = NULL; sMissingAssetImagep = NULL; - sWhiteImagep = NULL; - sDefaultTexturep = NULL ; + sWhiteImagep = NULL; + +#if !LL_RELEASE_FOR_DOWNLOAD + LLImageGL::sDefaultTexturep = NULL ; +#endif } // tuning params @@ -231,12 +233,7 @@ void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) } sDesiredDiscardBias = llclamp(sDesiredDiscardBias, sDesiredDiscardBiasMin, sDesiredDiscardBiasMax); - F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; - F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); - sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ; - - LLViewerImage::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && - (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; + LLImageGL::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ; } // static @@ -382,6 +379,7 @@ LLViewerImage::~LLViewerImage() void LLViewerImage::cleanup() { mFaceList.clear() ; + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); iter != mLoadedCallbackList.end(); ) { @@ -411,6 +409,192 @@ void LLViewerImage::reinit(BOOL usemipmaps /* = TRUE */) setSize(0,0,0); } +void LLViewerImage::resetFaceAtlas() +{ + //Nothing should be done here. +} + +//invalidate all atlas slots for this image. +void LLViewerImage::invalidateAtlas(BOOL rebuild_geom) +{ + for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) + { + if(*iter) + { + LLFace* facep = (LLFace*)*iter ; + facep->removeAtlas() ; + if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup()) + { + facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY); + } + } + } +} + +BOOL LLViewerImage::insertToAtlas() +{ + if(mFaceList.size() < 1) + { + return FALSE ; + } + if(!canAddToAtlas()) + { + return FALSE ; + } + if(getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= getDiscardLevelInAtlas()) + { + return FALSE ; + } + if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), getTexTarget())) + { + return FALSE ; + } + + BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image. + S32 raw_w = mRawImage->getWidth() ; + S32 raw_h = mRawImage->getHeight() ; + F32 xscale = 1.0f, yscale = 1.0f ; + LLPointer<LLTextureAtlasSlot> slot_infop; + LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer. + LLSpatialGroup* groupp ; + LLFace* facep; + + //if the atlas slot pointers for some faces are null, process them later. + ll_face_list_t waiting_list ; + + for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) + { + if(*iter) + { + facep = (LLFace*)*iter ; + + //face can not use atlas. + if(!facep->canUseAtlas()) + { + if(facep->getAtlasInfo()) + { + facep->removeAtlas() ; + } + ret = FALSE ; + continue ; + } + + //the atlas slot is updated + slot_infop = facep->getAtlasInfo() ; + groupp = facep->getDrawable()->getSpatialGroup() ; + + if(slot_infop) + { + if(slot_infop->getSpatialGroup() != groupp) + { + if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot + { + facep->setAtlasInfo(cur_slotp) ; + facep->setAtlasInUse(TRUE) ; + continue ; + } + else //do not forget to update slot_infop->getSpatialGroup(). + { + LLSpatialGroup* gp = slot_infop->getSpatialGroup() ; + gp->setCurUpdatingTime(gFrameCount) ; + gp->setCurUpdatingTexture(this) ; + gp->setCurUpdatingSlot(slot_infop) ; + } + } + else //same group + { + if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated + { + facep->setAtlasInUse(TRUE) ; + continue ; + } + } + } + else + { + //if the slot is null, wait to process them later. + waiting_list.push_back(facep) ; + continue ; + } + + //---------- + //insert to atlas + if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) + { + //the texture does not qualify to add to atlas, do not bother to try for other faces. + //invalidateAtlas(); + return FALSE ; + } + + //update texture scale + slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; + slot_infop->setTexCoordScale(xscale, yscale) ; + slot_infop->setValid() ; + slot_infop->setUpdatedTime(gFrameCount) ; + + //update spatial group atlas info + groupp->setCurUpdatingTime(gFrameCount) ; + groupp->setCurUpdatingTexture(this) ; + groupp->setCurUpdatingSlot(slot_infop) ; + + //make the face to switch to the atlas. + facep->setAtlasInUse(TRUE) ; + } + } + + //process the waiting_list + for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) + { + facep = (LLFace*)*iter ; + groupp = facep->getDrawable()->getSpatialGroup() ; + + //check if this texture already inserted to atlas for this group + if((cur_slotp = groupp->getCurUpdatingSlot(this))) + { + facep->setAtlasInfo(cur_slotp) ; + facep->setAtlasInUse(TRUE) ; + continue ; + } + + //need to reserve a slot from atlas + slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ; + + facep->setAtlasInfo(slot_infop) ; + + groupp->setCurUpdatingTime(gFrameCount) ; + groupp->setCurUpdatingTexture(this) ; + groupp->setCurUpdatingSlot(slot_infop) ; + + //slot allocation failed. + if(!slot_infop || !slot_infop->getAtlas()) + { + ret = FALSE ; + facep->setAtlasInUse(FALSE) ; + continue ; + } + + //insert to atlas + if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) + { + //the texture does not qualify to add to atlas, do not bother to try for other faces. + ret = FALSE ; + //invalidateAtlas(); + break ; + } + + //update texture scale + slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; + slot_infop->setTexCoordScale(xscale, yscale) ; + slot_infop->setValid() ; + slot_infop->setUpdatedTime(gFrameCount) ; + + //make the face to switch to the atlas. + facep->setAtlasInUse(TRUE) ; + } + + return ret ; +} + /////////////////////////////////////////////////////////////////////////////// // ONLY called from LLViewerImageList void LLViewerImage::destroyTexture() @@ -432,7 +616,7 @@ void LLViewerImage::addToCreateTexture() if(isForSculptOnly()) { //just update some variables, not to create a real GL texture. - createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE) ; + createGLTexture(mRawDiscardLevel, mRawImage, 0) ; mNeedsCreateTexture = FALSE ; destroyRawImage(); } @@ -495,7 +679,7 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) mNeedsCreateTexture = FALSE; if (mRawImage.isNull()) { - llerrs << "LLViewerImage trying to create texture with no Raw Image" << llendl; + llwarns << "LLViewerImage trying to create texture with no Raw Image" << llendl; } // llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", // mRawDiscardLevel, @@ -519,32 +703,25 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) mOrigHeight = mFullHeight; } - bool size_okay = true; - - U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel; - U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel; - if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE ) + if (LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) { - llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl; - size_okay = false; + if(!(res = insertToAtlas())) + { + res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); + resetFaceAtlas() ; + } } - if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) + else { // A non power-of-two image was uploaded (through a non standard client) - llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl; - size_okay = false; - } - - if( !size_okay ) - { - // An inappropriately-sized image was uploaded (through a non standard client) // We treat these images as missing assets which causes them to // be renderd as 'missing image' and to stop requesting data setIsMissingAsset(); destroyRawImage(); return FALSE; } + if (mRawImage->getComponents()>4) { LL_DEBUGS("Openjpeg")<<"broken raw image" << LL_ENDL; @@ -553,7 +730,6 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) return FALSE; } - res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); } // @@ -655,6 +831,7 @@ void LLViewerImage::processTextureStats() S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); mTexelsPerImage = (F32)fullwidth * fullheight; + F32 discard_level = 0.f; // If we know the output width and height, we can force the discard @@ -662,7 +839,8 @@ void LLViewerImage::processTextureStats() // data than we need to. if (mBoostLevel == LLViewerImageBoostLevel::BOOST_UI || mBoostLevel == LLViewerImageBoostLevel::BOOST_PREVIEW || - mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF) // JAMESDEBUG what about AVATAR_BAKED_SELF? + mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF || + mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_BAKED_SELF) { discard_level = 0; // full res } @@ -677,12 +855,6 @@ void LLViewerImage::processTextureStats() } else { - if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 1.0f) - { - //if is a big image and not being used recently, nor close to the view point, do not load hi-res data. - mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerImage::sMinLargeImageSize) ; - } - if ((mCalculatedDiscardLevel >= 0.f) && (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) { @@ -705,6 +877,7 @@ void LLViewerImage::processTextureStats() discard_level += sCameraMovingDiscardBias ; } discard_level = floorf(discard_level); +// discard_level -= (gImageList.mVideoMemorySetting>>1); // more video ram = higher detail F32 min_discard = 0.f; if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) @@ -726,15 +899,12 @@ void LLViewerImage::processTextureStats() if ((sDesiredDiscardBias > 0.0f) && (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) { - // Limit the amount of GL memory bound each frame - if ( (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && - (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) + if ( (sBoundTextureMemoryInBytes >> 20) > sMaxBoundTextureMemInMegaBytes*texmem_middle_bound_scale) { scaleDown() ; } // Only allow GL to have 2x the video card memory - else if ( (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale) && - (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) + else if (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel) { scaleDown() ; } @@ -756,7 +926,7 @@ void LLViewerImage::updateVirtualSize() if(facep->getDrawable()->isRecentlyVisible()) { addTextureStats(facep->getVirtualSize()) ; - setAdditionalDecodePriority(facep->getImportanceToCamera()) ; + //setAdditionalDecodePriority(facep->getImportanceToCamera()) ; } } } @@ -796,6 +966,7 @@ void LLViewerImage::switchToCachedImage() mNeedsCreateTexture = TRUE; } } + //============================================================================ F32 LLViewerImage::calcDecodePriority() @@ -817,13 +988,6 @@ F32 LLViewerImage::calcDecodePriority() } S32 cur_discard = getDiscardLevel(); - - //no need to update if the texture reaches its highest res and the memory is sufficient. - //if(LLViewerImage::sFreezeImageScalingDown && !cur_discard) - //{ - // return -5.0f ; - //} - bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); F32 pixel_priority = fsqrtf(mMaxVirtualSize); const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame @@ -842,14 +1006,6 @@ F32 LLViewerImage::calcDecodePriority() { priority = -1.0f ; } - else if (!isJustBound() && mCachedRawImageReady) - { - priority = -1.0f; - } - else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel) - { - priority = -1.0f; - } else if (mDesiredDiscardLevel > mMaxDiscardLevel) { // Don't decode anything we don't need @@ -910,7 +1066,6 @@ F32 LLViewerImage::calcDecodePriority() ddiscard-=2; } ddiscard = llclamp(ddiscard, 0, 4); - priority = ddiscard*100000.f; } if (priority > 0.0f) @@ -942,7 +1097,7 @@ F32 LLViewerImage::calcDecodePriority() //static F32 LLViewerImage::maxDecodePriority() { - return 6000000.f; + return 6000000.f; // KL 2000000 in render pipeline } void LLViewerImage::setDecodePriority(F32 priority) @@ -969,10 +1124,7 @@ void LLViewerImage::setBoostLevel(S32 level) { mBoostLevel = level; - if(gAuditTexture) - { - setCategory(mBoostLevel); - } + if(mBoostLevel != LLViewerImageBoostLevel::BOOST_NONE) { @@ -1022,11 +1174,15 @@ bool LLViewerImage::updateFetch() return false; // process any raw image data in callbacks before replacing } + mFetchState = 0; + mFetchPriority = 0; + mFetchDeltaTime = 999999.f; + mRequestDeltaTime = 999999.f; S32 current_discard = getDiscardLevel(); S32 desired_discard = getDesiredDiscardLevel(); F32 decode_priority = getDecodePriority(); decode_priority = llmax(decode_priority, 0.0f); - decode_priority = llmin(decode_priority, maxDecodePriority()); + //decode_priority = llmin(decode_priority, maxDecodePriority()); if (mIsFetching) { @@ -1059,7 +1215,6 @@ bool LLViewerImage::updateFetch() if (mRawImage.notNull()) { mRawDiscardLevel = fetch_discard; - if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) { @@ -1178,10 +1333,6 @@ bool LLViewerImage::updateFetch() { make_request = false; } - else if (!isJustBound() && mCachedRawImageReady) - { - make_request = false; - } else { if (mIsFetching) @@ -1216,14 +1367,13 @@ bool LLViewerImage::updateFetch() w, h, c, desired_discard, needsAux()); if (fetch_request_created) - { + { mHasFetcher = TRUE; mIsFetching = TRUE; mRequestedDiscardLevel = desired_discard; - mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, - mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); - } + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); + } // if createRequest() failed, we're finishing up a request for this UUID, // wait for it to complete @@ -1295,12 +1445,12 @@ BOOL LLViewerImage::forceFetch() w, h, c, desired_discard, needsAux()); if (fetch_request_created) - { + { mHasFetcher = TRUE; mIsFetching = TRUE; // Set the image's decode priority to maxDecodePriority() too, or updateFetch() will set // the request priority to 0 and terminate the fetch before we even started (SNOW-203). - gImageList.bumpToMaxDecodePriority(this); + // gImageList.bumpToMaxDecodePriority(this); // Kl force immediate update?? mRequestedDiscardLevel = desired_discard ; mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, @@ -1473,8 +1623,8 @@ bool LLViewerImage::doLoadedCallbacks() destroyRawImage(); readBackRawImage(gl_discard); - llassert_always(mRawImage.notNull()); - llassert_always(!mNeedsAux || mAuxRawImage.notNull()); + //llassert_always(mRawImage.notNull()); + //llassert_always(!mNeedsAux || mAuxRawImage.notNull()); } // @@ -1636,7 +1786,18 @@ bool LLViewerImage::bindDefaultImage(S32 stage) //virtual void LLViewerImage::forceImmediateUpdate() { - gImageList.bumpToMaxDecodePriority(this) ; + //only immediately update a deleted texture which is now being re-used. + if(!isDeleted()) + { + return ; + } + //if already called forceImmediateUpdate() + if(mInImageList && mDecodePriority == LLViewerImage::maxDecodePriority()) + { + return ; + } + + gImageList.forceImmediateUpdate(this) ; return ; } @@ -1647,7 +1808,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) llassert_always(mComponents > 0); if (mRawImage.notNull()) { - llerrs << "called with existing mRawImage" << llendl; + llwarns << "called with existing mRawImage" << llendl; mRawImage = NULL; } @@ -1665,7 +1826,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) sRawCount++; mIsRawImageValid = TRUE; - + return mRawImage; } diff --git a/linden/indra/newview/llviewerimage.h b/linden/indra/newview/llviewerimage.h index c82b68bae..7d646be36 100644 --- a/linden/indra/newview/llviewerimage.h +++ b/linden/indra/newview/llviewerimage.h @@ -41,11 +41,13 @@ #include <map> #include <list> -class LLFace; + #define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 #define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. class LLViewerImage; +class LLTextureAtlas ; +class LLFace ; typedef void (*loaded_callback_func)( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); @@ -261,8 +263,29 @@ class LLViewerImage : public LLImageGL void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } // Host we think might have this image, used for baked av textures. + void setTargetHost(LLHost host) { mTargetHost = host; } LLHost getTargetHost() const { return mTargetHost; } + enum + { + BOOST_NONE = 0, + BOOST_AVATAR_BAKED = 1, + BOOST_AVATAR = 2, + BOOST_CLOUDS = 3, + BOOST_SCULPTED = 4, + + BOOST_HIGH = 10, + BOOST_TERRAIN = 11, // has to be high priority for minimap / low detail + BOOST_SELECTED = 12, + BOOST_HUD = 13, + BOOST_AVATAR_BAKED_SELF = 14, + BOOST_UI = 15, + BOOST_PREVIEW = 16, + BOOST_MAP = 17, + BOOST_MAP_LAYER = 18, + BOOST_AVATAR_SELF = 19, // needed for baking avatar + BOOST_MAX_LEVEL + }; void setBoostLevel(S32 level); S32 getBoostLevel() { return mBoostLevel; } @@ -295,6 +318,10 @@ class LLViewerImage : public LLImageGL S32 getOriginalWidth() { return mOrigWidth; } S32 getOriginalHeight() { return mOrigHeight; } + BOOL insertToAtlas() ; + void resetFaceAtlas() ; + void invalidateAtlas(BOOL rebuild_geom = FALSE); + BOOL isForSculptOnly() const ; void setForSculpt(); @@ -313,6 +340,7 @@ class LLViewerImage : public LLImageGL void addFace(LLFace* facep) ; void removeFace(LLFace* facep) ; + BOOL isReferenced()const {return mFaceList.size() > 0 ; } friend class LocalBitmap; // tag: vaa emerald local_asset_browser @@ -418,6 +446,7 @@ class LLViewerImage : public LLImageGL typedef std::list<LLFace*> ll_face_list_t ; ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture + BOOL mInCreationList ; public: static const U32 sCurrentFileVersion; // Default textures diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp index 29c630b4a..f795de61f 100644 --- a/linden/indra/newview/llviewerimagelist.cpp +++ b/linden/indra/newview/llviewerimagelist.cpp @@ -199,7 +199,6 @@ static std::string get_texture_list_name() void LLViewerImageList::doPrefetchImages() { -#if 1 if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point @@ -227,7 +226,7 @@ void LLViewerImageList::doPrefetchImages() image->addTextureStats((F32)pixel_area); } } -#endif + } @@ -486,7 +485,7 @@ void LLViewerImageList::removeImageFromList(LLViewerImage *image) { llinfos << "Image is not in mUUIDMap!" << llendl ; } - llerrs << "LLViewerImageList::removeImageFromList - Image not in list" << llendl; + llwarns << "LLViewerImageList::removeImageFromList - Image not in list" << llendl; } llverify(mImageList.erase(image) == 1); image->mInImageList = FALSE; @@ -535,7 +534,8 @@ void LLViewerImageList::deleteImage(LLViewerImage *image) void LLViewerImageList::dirtyImage(LLViewerImage *image) { - mDirtyTextureList.insert(image); + //mDirtyTextureList.insert(image); + image->invalidateAtlas(TRUE) ; // KL } //////////////////////////////////////////////////////////////////////////// @@ -547,25 +547,21 @@ void LLViewerImageList::updateImages(F32 max_time) sNumImagesStat.addValue(sNumImages); sNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); - sGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); - sGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); - sRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); - sFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); - + sGLTexMemStat.addValue((F32)(LLImageGL::sGlobalTextureMemoryInBytes >> 20)); + sGLBoundMemStat.addValue((F32)(LLImageGL::sBoundTextureMemoryInBytes >> 20)); + sRawMemStat.addValue((F32)(LLImageRaw::sGlobalRawMemory >> 20)); + sFormattedMemStat.addValue((F32)(LLImageFormatted::sGlobalFormattedMemory >> 20)); + llpushcallstacks ; - updateImagesDecodePriorities(); - llpushcallstacks ; - F32 total_max_time = max_time; max_time -= updateImagesFetchTextures(max_time); - llpushcallstacks ; - max_time = llmax(max_time, total_max_time*.25f); // at least 25% of max_time + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); max_time -= updateImagesCreateTextures(max_time); - llpushcallstacks ; - + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); + llpushcallstacks ; if (!mDirtyTextureList.empty()) { LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY); @@ -739,7 +735,7 @@ F32 LLViewerImageList::updateImagesCreateTextures(F32 max_time) return create_timer.getElapsedTimeF32(); } -void LLViewerImageList::bumpToMaxDecodePriority(LLViewerImage* imagep) +void LLViewerImageList::forceImmediateUpdate(LLViewerImage* imagep) { if(!imagep) { @@ -747,11 +743,6 @@ void LLViewerImageList::bumpToMaxDecodePriority(LLViewerImage* imagep) } if(imagep->mInImageList) { - if (imagep->getDecodePriority() == LLViewerImage::maxDecodePriority()) - { - // Already at maximum. - return; - } removeImageFromList(imagep); } @@ -1028,13 +1019,16 @@ LLPointer<LLImageJ2C> LLViewerImageList::convertToUploadFile(LLPointer<LLImageRa return compressedImage; } + +const S32 MIN_VIDEO_RAM = 32; +const S32 MAX_VIDEO_RAM = 512; // 512MB max for performance reasons. // Returns min setting for TextureMemory (in MB) S32 LLViewerImageList::getMinVideoRamSetting() { - S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); + S32 system_ram = (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20); //min texture mem sets to 64M if total physical mem is more than 1.5GB - return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ; + return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM; } //static @@ -1061,14 +1055,14 @@ S32 LLViewerImageList::getMaxVideoRamSetting(bool get_recommended) llwarns << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << llendl; } - S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + S32 system_ram = (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20); // In MB //llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl; if (get_recommended) max_texmem = llmin(max_texmem, (S32)(system_ram/2)); else max_texmem = llmin(max_texmem, (S32)(system_ram)); - max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM); return max_texmem; } @@ -1113,9 +1107,9 @@ void LLViewerImageList::updateMaxResidentTexMem(S32 mem) mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2); } - if (mMaxTotalTextureMemInMegaBytes > (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()) - 128) + if (mMaxTotalTextureMemInMegaBytes > (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20) - 128) { - mMaxTotalTextureMemInMegaBytes = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()) - 128 ; + mMaxTotalTextureMemInMegaBytes = (gSysMemory.getPhysicalMemoryClamped() >> 20) - 128 ; } llinfos << "Total Video Memory set to: " << vb_mem << " MB" << llendl; diff --git a/linden/indra/newview/llviewerimagelist.h b/linden/indra/newview/llviewerimagelist.h index 561e8e5f4..f82d9f3eb 100644 --- a/linden/indra/newview/llviewerimagelist.h +++ b/linden/indra/newview/llviewerimagelist.h @@ -112,7 +112,7 @@ class LLViewerImageList LLGLenum primary_format = 0, const LLUUID& force_id = LLUUID::null ); - + // Request image from a specific host, used for baked avatar textures. // Implemented in header in case someone changes default params above. JC LLViewerImage* getImageFromHost(const LLUUID& image_id, LLHost host) @@ -129,7 +129,7 @@ class LLViewerImageList // Using image stats, determine what images are necessary, and perform image updates. void updateImages(F32 max_time); - void bumpToMaxDecodePriority(LLViewerImage* imagep) ; + void forceImmediateUpdate(LLViewerImage* imagep) ; // Decode and create textures for all images currently in list. void decodeAllImages(F32 max_decode_time); diff --git a/linden/indra/newview/llviewerjointmesh.cpp b/linden/indra/newview/llviewerjointmesh.cpp index b6f0dafae..dc08bcdc2 100644 --- a/linden/indra/newview/llviewerjointmesh.cpp +++ b/linden/indra/newview/llviewerjointmesh.cpp @@ -523,9 +523,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) //---------------------------------------------------------------- if (!gRenderForSelect) { - if (is_dummy) + /* if (is_dummy) glColor4fv(LLVOAvatar::getDummyColor().mV); - else + else */ glColor4fv(mColor.mV); } @@ -557,7 +557,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture()); + gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture(), TRUE); // KL SD } else { @@ -565,7 +565,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) // Ignore the warning if that's the case. if (!gSavedSettings.getBOOL("RenderUnloadedAvatar")) { - llwarns << "Layerset without composite" << llendl; + //llwarns << "Layerset without composite" << llendl; } gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT)); } @@ -574,7 +574,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if ( !is_dummy && mTexture.notNull() ) { old_mode = mTexture->getAddressMode(); - gGL.getTexUnit(0)->bind(mTexture.get()); + gGL.getTexUnit(0)->bind(mTexture.get(), TRUE); // KL SD gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } else diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 8c5cf6a14..8857170c1 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -938,9 +938,7 @@ void LLViewerMediaImpl::update() x_pos, y_pos, width, - height, - TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) - + height); } mMediaSource->resetDirty(); diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 7266dbce9..314fc94f7 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -1408,14 +1408,14 @@ void init_debug_avatar_menu(LLMenuGL* menu) //menu->append(new LLMenuItemToggleGL("Show Attachment Points", &LLVOAvatar::sShowAttachmentPoints)); //diabling collision plane due to DEV-14477 -brad //menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane)); - menu->append(new LLMenuItemCheckGL("Show Collision Skeleton", + /*menu->append(new LLMenuItemCheckGL("Show Collision Skeleton", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)); menu->append(new LLMenuItemCheckGL("Display Agent Target", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, - (void*)LLPipeline::RENDER_DEBUG_AGENT_TARGET)); + (void*)LLPipeline::RENDER_DEBUG_AGENT_TARGET));*/ menu->append(new LLMenuItemToggleGL( "Debug Rotation", &LLVOAvatar::sDebugAvatarRotation)); menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments)); menu->append(new LLMenuItemCallGL("Refresh Appearance", handle_rebake_textures, NULL, NULL, 'R', MASK_ALT | MASK_CONTROL )); @@ -10436,7 +10436,7 @@ class LLAdvancedCheckShowCollisionPlane : public view_listener_t // SHOW COLLISION SKELETON // ///////////////////////////// - +/* class LLAdvancedToggleShowCollisionSkeleton : public view_listener_t { bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) @@ -10457,13 +10457,13 @@ class LLAdvancedCheckShowCollisionSkeleton : public view_listener_t } }; - +*/ ////////////////////////// // DISPLAY AGENT TARGET // ////////////////////////// - +/* class LLAdvancedToggleDisplayAgentTarget : public view_listener_t { bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) @@ -10484,7 +10484,7 @@ class LLAdvancedCheckDisplayAgentTarget : public view_listener_t } }; - +*/ /////////////////////////// // DEBUG AVATAR ROTATION // @@ -11350,10 +11350,10 @@ void initialize_menus() addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis"); // addMenu(new LLAdvancedToggleShowCollisionPlane(), "Advanced.ToggleShowCollisionPlane"); // addMenu(new LLAdvancedCheckShowCollisionPlane(), "Advanced.CheckShowCollisionPlane"); - addMenu(new LLAdvancedToggleShowCollisionSkeleton(), "Advanced.ToggleShowCollisionSkeleton"); - addMenu(new LLAdvancedCheckShowCollisionSkeleton(), "Advanced.CheckShowCollisionSkeleton"); - addMenu(new LLAdvancedToggleDisplayAgentTarget(), "Advanced.ToggleDisplayAgentTarget"); - addMenu(new LLAdvancedCheckDisplayAgentTarget(), "Advanced.CheckDisplayAgentTarget"); +// addMenu(new LLAdvancedToggleShowCollisionSkeleton(), "Advanced.ToggleShowCollisionSkeleton"); +// addMenu(new LLAdvancedCheckShowCollisionSkeleton(), "Advanced.CheckShowCollisionSkeleton"); +// addMenu(new LLAdvancedToggleDisplayAgentTarget(), "Advanced.ToggleDisplayAgentTarget"); +// addMenu(new LLAdvancedCheckDisplayAgentTarget(), "Advanced.CheckDisplayAgentTarget"); addMenu(new LLAdvancedToggleDebugAvatarRotation(), "Advanced.ToggleDebugAvatarRotation"); addMenu(new LLAdvancedCheckDebugAvatarRotation(), "Advanced.CheckDebugAvatarRotation"); addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments"); diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index b40d4e03a..2a6fafaea 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp @@ -2785,6 +2785,11 @@ BOOL LLViewerObject::updateGeometry(LLDrawable *drawable) return TRUE; } +void LLViewerObject::updateGL() +{ + +} + void LLViewerObject::updateFaceSize(S32 idx) { @@ -2889,7 +2894,7 @@ F32 LLViewerObject::getMidScale() const } -void LLViewerObject::updateTextures() +void LLViewerObject::updateTextures(LLAgent &agent) { } @@ -3734,6 +3739,7 @@ S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color) else if (color != tep->getColor()) { retval = LLPrimitive::setTEColor(te, color); + //setChanged(TEXTURE); if (mDrawable.notNull() && retval) { // These should only happen on updates which are not the initial update. @@ -3972,7 +3978,7 @@ LLViewerImage *LLViewerObject::getTEImage(const U8 face) const } } - llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; + llwarns << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; return NULL; } @@ -4158,6 +4164,11 @@ void LLViewerObject::updateText() } } +LLVOAvatar* LLViewerObject::asAvatar() +{ + return NULL; +} + BOOL LLViewerObject::isParticleSource() const { return !mPartSourcep.isNull() && !mPartSourcep->isDead(); @@ -4372,7 +4383,14 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow gAudiop->cleanupAudioSource(mAudioSourcep); mAudioSourcep = NULL; } - +/* + if (mAudioSourcep && mAudioSourcep->isMuted() && + mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid) + { + //llinfos << "Already having this sound as muted sound, ignoring" << llendl; + return; + } +*/ getAudioSource(owner_id); if (mAudioSourcep) @@ -4466,7 +4484,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para new_block = new LLSculptParams(); break; } - + case LLNetworkData::PARAMS_LIGHT_IMAGE: + { + new_block = new LLLightImageParams(); + break; + } default: { llinfos << "Unknown param type." << llendl; @@ -4557,7 +4579,7 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_ bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin) { ExtraParameter* param = getExtraParameterEntryCreate(param_type); - if (param->in_use != in_use) + if (param && param->in_use != in_use) { param->in_use = in_use; parameterChanged(param_type, param->data, in_use, local_origin); @@ -4973,7 +4995,7 @@ U32 LLViewerObject::getPartitionType() const return LLViewerRegion::PARTITION_NONE; } -void LLViewerObject::dirtySpatialGroup() const +void LLViewerObject::dirtySpatialGroup(BOOL priority) const { if (mDrawable) { @@ -4981,6 +5003,7 @@ void LLViewerObject::dirtySpatialGroup() const if (group) { group->dirtyGeom(); + gPipeline.markRebuild(group, priority); } } } diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h index 7f8bd63f2..41c406aed 100644 --- a/linden/indra/newview/llviewerobject.h +++ b/linden/indra/newview/llviewerobject.h @@ -74,6 +74,7 @@ class LLViewerPartSourceScript; class LLViewerRegion; class LLViewerObjectMedia; class LLVOInventoryListener; +class LLVOAvatar; typedef enum e_object_update_type { @@ -116,7 +117,7 @@ struct LLMaterialExportInfo //============================================================================ -class LLViewerObject : public LLPrimitive, public LLRefCount +class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate { protected: ~LLViewerObject(); // use unref() @@ -143,6 +144,8 @@ class LLViewerObject : public LLPrimitive, public LLRefCount BOOL isOrphaned() const { return mOrphaned; } BOOL isParticleSource() const; + virtual LLVOAvatar* asAvatar(); + static void initVOClasses(); static void cleanupVOClasses(); @@ -189,11 +192,12 @@ class LLViewerObject : public LLPrimitive, public LLRefCount S32 getNumFaces() const { return mNumFaces; } // Graphical stuff for objects - maybe broken out into render class later? - virtual void updateTextures(); + virtual void updateTextures(LLAgent &agent); virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object virtual LLDrawable* createDrawable(LLPipeline *pipeline); virtual BOOL updateGeometry(LLDrawable *drawable); + virtual void updateGL(); virtual void updateFaceSize(S32 idx); virtual BOOL updateLOD(); virtual BOOL setDrawableParent(LLDrawable* parentp); @@ -218,6 +222,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } + virtual BOOL hasLightTexture() const { return FALSE; } // This method returns true if the object is over land owned by // the agent. @@ -468,7 +473,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount virtual S32 getLOD() const { return 3; } virtual U32 getPartitionType() const; - virtual void dirtySpatialGroup() const; + virtual void dirtySpatialGroup(BOOL priority = FALSE) const; virtual void dirtyMesh(); virtual LLNetworkData* getParameterEntry(U16 param_type) const; diff --git a/linden/indra/newview/llviewerobjectlist.cpp b/linden/indra/newview/llviewerobjectlist.cpp index bfb248b69..a289570a7 100644 --- a/linden/indra/newview/llviewerobjectlist.cpp +++ b/linden/indra/newview/llviewerobjectlist.cpp @@ -629,7 +629,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) // Update distance & gpw objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area - objectp->updateTextures(); // Update the image levels of textures for this object. + objectp->updateTextures(agent); // Update the image levels of textures for this object. } } diff --git a/linden/indra/newview/llviewerobjectlist.h b/linden/indra/newview/llviewerobjectlist.h index 07920cbaa..a77c33db0 100644 --- a/linden/indra/newview/llviewerobjectlist.h +++ b/linden/indra/newview/llviewerobjectlist.h @@ -44,7 +44,6 @@ // project includes #include "llviewerobject.h" -class LLCamera; class LLNetMap; class LLDebugBeacon; diff --git a/linden/indra/newview/llviewerparceloverlay.cpp b/linden/indra/newview/llviewerparceloverlay.cpp index 0bcd8f395..935e3e60a 100644 --- a/linden/indra/newview/llviewerparceloverlay.cpp +++ b/linden/indra/newview/llviewerparceloverlay.cpp @@ -71,7 +71,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges mTexture = new LLImageGL(FALSE); mImageRaw = new LLImageRaw(mParcelGridsPerEdge, mParcelGridsPerEdge, OVERLAY_IMG_COMPONENTS); - mTexture->createGLTexture(0, mImageRaw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + mTexture->createGLTexture(0, mImageRaw, 0); gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(mTexture); mTexture->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -593,7 +593,7 @@ void LLViewerParcelOverlay::addPropertyLine( break; default: - llerrs << "Invalid edge in addPropertyLine" << llendl; + llwarns << "Invalid edge in addPropertyLine" << llendl; return; } diff --git a/linden/indra/newview/llviewershadermgr.cpp b/linden/indra/newview/llviewershadermgr.cpp index 69f7bd8b1..8648271e7 100644 --- a/linden/indra/newview/llviewershadermgr.cpp +++ b/linden/indra/newview/llviewershadermgr.cpp @@ -113,6 +113,8 @@ LLGLSLShader gDeferredAvatarProgram; LLGLSLShader gDeferredAvatarAlphaProgram; LLGLSLShader gDeferredLightProgram; LLGLSLShader gDeferredMultiLightProgram; +LLGLSLShader gDeferredSpotLightProgram; +LLGLSLShader gDeferredMultiSpotLightProgram; LLGLSLShader gDeferredSunProgram; LLGLSLShader gDeferredBlurLightProgram; LLGLSLShader gDeferredSoftenProgram; @@ -120,6 +122,12 @@ LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAlphaProgram; LLGLSLShader gDeferredFullbrightProgram; +LLGLSLShader gDeferredGIProgram; +LLGLSLShader gDeferredPostGIProgram; +LLGLSLShader gDeferredPostProgram; + +LLGLSLShader gLuminanceGatherProgram; + //current avatar shader parameter pointer GLint gAvatarMatrixParam; @@ -151,6 +159,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredMultiLightProgram); mShaderList.push_back(&gDeferredAlphaProgram); mShaderList.push_back(&gDeferredFullbrightProgram); + mShaderList.push_back(&gDeferredPostGIProgram); + mShaderList.push_back(&gDeferredPostProgram); + mShaderList.push_back(&gDeferredGIProgram); mShaderList.push_back(&gDeferredWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); } @@ -220,13 +231,32 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) mReservedUniforms.push_back("shadowMap1"); mReservedUniforms.push_back("shadowMap2"); mReservedUniforms.push_back("shadowMap3"); + mReservedUniforms.push_back("shadowMap4"); + mReservedUniforms.push_back("shadowMap5"); + mReservedUniforms.push_back("normalMap"); mReservedUniforms.push_back("positionMap"); mReservedUniforms.push_back("diffuseRect"); mReservedUniforms.push_back("specularRect"); mReservedUniforms.push_back("noiseMap"); + mReservedUniforms.push_back("lightFunc"); mReservedUniforms.push_back("lightMap"); - + mReservedUniforms.push_back("luminanceMap"); + mReservedUniforms.push_back("giLightMap"); + mReservedUniforms.push_back("sunLightMap"); + mReservedUniforms.push_back("localLightMap"); + mReservedUniforms.push_back("projectionMap"); + mReservedUniforms.push_back("diffuseGIMap"); + mReservedUniforms.push_back("specularGIMap"); + mReservedUniforms.push_back("normalGIMap"); + mReservedUniforms.push_back("minpGIMap"); + mReservedUniforms.push_back("maxpGIMap"); + mReservedUniforms.push_back("depthGIMap"); + mReservedUniforms.push_back("lastDiffuseGIMap"); + mReservedUniforms.push_back("lastNormalGIMap"); + mReservedUniforms.push_back("lastMinpGIMap"); + mReservedUniforms.push_back("lastMaxpGIMap"); + mWLUniforms.push_back("camPosLocal"); mTerrainUniforms.reserve(5); @@ -754,9 +784,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects() } } -#if 0 - // disabling loading of postprocess shaders until we fix - // ATI sampler2DRect compatibility. + + // KL enabling loading of postprocess shaders until we fix + // ATI may still have issues //load Color Filter Shader if (success) @@ -797,7 +827,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gPostNightVisionProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms); } - #endif + return success; @@ -814,6 +844,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTerrainProgram.unload(); gDeferredLightProgram.unload(); gDeferredMultiLightProgram.unload(); + gDeferredSpotLightProgram.unload(); + gDeferredMultiSpotLightProgram.unload(); gDeferredSunProgram.unload(); gDeferredBlurLightProgram.unload(); gDeferredSoftenProgram.unload(); @@ -823,6 +855,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.unload(); gDeferredAlphaProgram.unload(); gDeferredFullbrightProgram.unload(); + gDeferredPostGIProgram.unload(); + gDeferredPostProgram.unload(); + gLuminanceGatherProgram.unload(); + gDeferredGIProgram.unload(); gDeferredWaterProgram.unload(); return FALSE; } @@ -891,6 +927,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredMultiLightProgram.createShader(NULL, NULL); } + if (success) + { + gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; + gDeferredSpotLightProgram.mShaderFiles.clear(); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSpotLightProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; + gDeferredMultiSpotLightProgram.mShaderFiles.clear(); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); + } + if (success) { gDeferredSunProgram.mName = "Deferred Sun Shader"; @@ -940,6 +996,36 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredFullbrightProgram.createShader(NULL, NULL); } + if (success) + { + gDeferredPostGIProgram.mName = "Deferred Post GI Shader"; + gDeferredPostGIProgram.mShaderFiles.clear(); + gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostGIProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredPostProgram.mName = "Deferred Post Shader"; + gDeferredPostProgram.mShaderFiles.clear(); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredGIProgram.mName = "Deferred GI Shader"; + gDeferredGIProgram.mShaderFiles.clear(); + gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredGIProgram.createShader(NULL, NULL); + } + if (success) { // load water shader @@ -1022,6 +1108,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms); } + if (success) + { + gLuminanceGatherProgram.mName = "Luminance Gather Shader"; + gLuminanceGatherProgram.mShaderFiles.clear(); + gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceV.glsl", GL_VERTEX_SHADER_ARB)); + gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER_ARB)); + gLuminanceGatherProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gLuminanceGatherProgram.createShader(NULL, NULL); + } + return success; } diff --git a/linden/indra/newview/llviewershadermgr.h b/linden/indra/newview/llviewershadermgr.h index a743966d9..bb5077906 100644 --- a/linden/indra/newview/llviewershadermgr.h +++ b/linden/indra/newview/llviewershadermgr.h @@ -116,12 +116,30 @@ class LLViewerShaderMgr: public LLShaderMgr DEFERRED_SHADOW1, DEFERRED_SHADOW2, DEFERRED_SHADOW3, + DEFERRED_SHADOW4, + DEFERRED_SHADOW5, DEFERRED_NORMAL, DEFERRED_POSITION, DEFERRED_DIFFUSE, DEFERRED_SPECULAR, DEFERRED_NOISE, + DEFERRED_LIGHTFUNC, DEFERRED_LIGHT, + DEFERRED_LUMINANCE, + DEFERRED_GI_LIGHT, + DEFERRED_SUN_LIGHT, + DEFERRED_LOCAL_LIGHT, + DEFERRED_PROJECTION, + DEFERRED_GI_DIFFUSE, + DEFERRED_GI_SPECULAR, + DEFERRED_GI_NORMAL, + DEFERRED_GI_MIN_POS, + DEFERRED_GI_MAX_POS, + DEFERRED_GI_DEPTH, + DEFERRED_GI_LAST_DIFFUSE, + DEFERRED_GI_LAST_NORMAL, + DEFERRED_GI_LAST_MIN_POS, + DEFERRED_GI_LAST_MAX_POS, END_RESERVED_UNIFORMS } eGLSLReservedUniforms; @@ -326,16 +344,23 @@ extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTreeProgram; extern LLGLSLShader gDeferredLightProgram; extern LLGLSLShader gDeferredMultiLightProgram; +extern LLGLSLShader gDeferredSpotLightProgram; +extern LLGLSLShader gDeferredMultiSpotLightProgram; extern LLGLSLShader gDeferredSunProgram; +extern LLGLSLShader gDeferredGIProgram; extern LLGLSLShader gDeferredBlurLightProgram; extern LLGLSLShader gDeferredAvatarProgram; extern LLGLSLShader gDeferredSoftenProgram; extern LLGLSLShader gDeferredShadowProgram; +extern LLGLSLShader gDeferredPostGIProgram; +extern LLGLSLShader gDeferredPostProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; extern LLGLSLShader gDeferredFullbrightProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; +extern LLGLSLShader gLuminanceGatherProgram; + //current avatar shader parameter pointer extern GLint gAvatarMatrixParam; diff --git a/linden/indra/newview/llviewerstats.h b/linden/indra/newview/llviewerstats.h index b176632d0..9107ad6ee 100644 --- a/linden/indra/newview/llviewerstats.h +++ b/linden/indra/newview/llviewerstats.h @@ -196,7 +196,7 @@ class LLViewerStats : public LLSingleton<LLViewerStats> F64 mLastTimeDiff; // used for time stat updates }; -static const F32 SEND_STATS_PERIOD = 300.0f; +static const F32 SEND_STATS_PERIOD = 3000.0f; // The following are from (older?) statistics code found in appviewer. void init_statistics(); diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index f7713c22c..6f1b54ca5 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -471,6 +471,27 @@ class LLDebugText ypos += y_inc; + { + std::ostringstream ostr; + ostr << "Shadow error: " << gPipeline.mShadowError; + addText(xpos, ypos, ostr.str()); + ypos += y_inc; + } + + { + std::ostringstream ostr; + ostr << "Shadow FOV: " << gPipeline.mShadowFOV; + addText(xpos, ypos, ostr.str()); + ypos += y_inc; + } + + { + std::ostringstream ostr; + ostr << "Shadow Splits: " << gPipeline.mSunClipPlanes; + addText(xpos, ypos, ostr.str()); + ypos += y_inc; + } + LLVertexBuffer::sBindCount = LLImageGL::sBindCount = LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; @@ -1321,7 +1342,6 @@ LLViewerWindow::LLViewerWindow( // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. - LLImageGL::initClass(LLViewerImageBoostLevel::MAX_GL_IMAGE_CATEGORY) ; gImageList.init(); LLViewerImage::initClass(); gBumpImageList.init(); @@ -1434,7 +1454,7 @@ void LLViewerWindow::initBase() llassert( !gConsole ); gConsole = new LLConsole( "console", - gSavedSettings.getS32("ConsoleBufferSize"), + //gSavedSettings.getS32("ConsoleBufferSize"), getChatConsoleRect(), gSavedSettings.getS32("ChatFontSize"), gSavedSettings.getF32("ChatPersistTime") ); @@ -2515,7 +2535,6 @@ BOOL LLViewerWindow::handlePerFrameHover() mMouseInWindow = TRUE; } - S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]); S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]); @@ -2538,7 +2557,7 @@ BOOL LLViewerWindow::handlePerFrameHover() mCurrentMouseDelta.set(dx, dy); mouse_vel.setVec((F32) dx, (F32) dy); } - + mMouseVelocityStat.addValue(mouse_vel.magVec()); if (gNoRender) @@ -2727,8 +2746,8 @@ BOOL LLViewerWindow::handlePerFrameHover() { mToolTip->setVisible( tooltip_vis ); } - } - + } + if (tool && tool != gToolNull && tool != LLToolCompInspect::getInstance() && tool != LLToolDragAndDrop::getInstance() && !gSavedSettings.getBOOL("FreezeTime")) { LLMouseHandler *captor = gFocusMgr.getMouseCapture(); @@ -2798,37 +2817,41 @@ BOOL LLViewerWindow::handlePerFrameHover() gFloaterView->setRect(floater_rect); } - // snap floaters to top of chat bar/button strip - LLView* chatbar_and_buttons = gOverlayBar->getChild<LLView>("chatbar_and_buttons", TRUE); - // find top of chatbar and state buttons, if either are visible - if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull()) { - // convert top/left corner of chatbar/buttons container to gFloaterView-relative coordinates + // snap floaters to top of chat bar/button strip + LLView* chatbar_and_buttons = gOverlayBar->getChild<LLView>("chatbar_and_buttons", TRUE); S32 top, left; - chatbar_and_buttons->localPointToOtherView( - chatbar_and_buttons->getLocalBoundingRect().mLeft, - chatbar_and_buttons->getLocalBoundingRect().mTop, - &left, - &top, - gFloaterView); - gFloaterView->setSnapOffsetBottom(top); - } - else if (gToolBar->getVisible()) - { - S32 top, left; - gToolBar->localPointToOtherView( - gToolBar->getLocalBoundingRect().mLeft, - gToolBar->getLocalBoundingRect().mTop, - &left, - &top, - gFloaterView); - gFloaterView->setSnapOffsetBottom(top); - } - else - { - gFloaterView->setSnapOffsetBottom(0); + S32 chatbar_and_buttons_x = chatbar_and_buttons->getLocalBoundingRect().mLeft; + S32 chatbar_and_buttons_y = chatbar_and_buttons->getLocalBoundingRect().mTop; + + // find top of chatbar and state buttons, if either are visible + if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull()) + { + // convert top/left corner of chatbar/buttons container to + // gFloaterView-relative coordinates + chatbar_and_buttons->localPointToOtherView( + chatbar_and_buttons_x, + chatbar_and_buttons_y, + &left, + &top, + gFloaterView); + gFloaterView->setSnapOffsetBottom(top); + } + else if (gToolBar->getVisible()) + { + gToolBar->localPointToOtherView( + chatbar_and_buttons_x, + chatbar_and_buttons_y, + &left, + &top, + gFloaterView); + gFloaterView->setSnapOffsetBottom(top); + } + else + { + gFloaterView->setSnapOffsetBottom(0); + } } - // Always update console LLRect console_rect = getChatConsoleRect(); console_rect.mBottom = gHUDView->getRect().mBottom + getChatConsoleBottomPad(); @@ -2836,8 +2859,8 @@ BOOL LLViewerWindow::handlePerFrameHover() gConsole->setRect(console_rect); } - mLastMousePoint = mCurrentMousePoint; + mLastMousePoint = mCurrentMousePoint; // last ditch force of edit menu to selection manager if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) { @@ -2900,7 +2923,6 @@ BOOL LLViewerWindow::handlePerFrameHover() &gDebugRaycastBinormal); } - // per frame picking - for tooltips and changing cursor over interactive objects static S32 previous_x = -1; static S32 previous_y = -1; @@ -2943,7 +2965,6 @@ BOOL LLViewerWindow::handlePerFrameHover() previous_x = x; previous_y = y; - return handled; } @@ -4041,7 +4062,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei { if(image_width > window_width || image_height > window_height) //need to enlarge the scene { - if (gGLManager.mHasFramebufferObject && !show_ui) + if (!LLPipeline::sRenderDeferred && gGLManager.mHasFramebufferObject && !show_ui) { GLint max_size = 0; glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size); @@ -4130,9 +4151,16 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei else { const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); - display(do_rebuild, scale_factor, subfield, TRUE); - // Required for showing the GUI in snapshots? See DEV-16350 for details. JC - render_ui(scale_factor, subfield); + if (LLPipeline::sRenderDeferred) + { + display(do_rebuild, scale_factor, subfield, FALSE); + } + else + { + display(do_rebuild, scale_factor, subfield, TRUE); + // Required for showing the GUI in snapshots? See DEV-16350 for details. JC + render_ui(scale_factor, subfield); + } } S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width); diff --git a/linden/indra/newview/llvlcomposition.cpp b/linden/indra/newview/llvlcomposition.cpp index 535c504ea..f96665b87 100644 --- a/linden/indra/newview/llvlcomposition.cpp +++ b/linden/indra/newview/llvlcomposition.cpp @@ -460,6 +460,10 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } } + if (!texturep->getHasGLTexture()) + { + texturep->createGLTexture(0, raw); + } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32(); LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin); diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 14b8d3e7a..3b62c63e5 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -704,6 +704,7 @@ BOOL LLVOAvatar::sDebugInvisible = FALSE; BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; BOOL LLVOAvatar::sShowAnimationDebug = FALSE; BOOL LLVOAvatar::sShowFootPlane = FALSE; +BOOL LLVOAvatar::sShowCollisionVolumes = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; BOOL LLVOAvatar::sUseImpostors = FALSE; @@ -740,6 +741,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mTyping(FALSE), mMeshValid(FALSE), mVisible(FALSE), + mMeshTexturesDirty(FALSE), mWindFreq(0.f), mRipplePhase( 0.f ), mBelowWater(FALSE), @@ -800,7 +802,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mBakedTextureData[i].mLastTextureIndex = IMG_DEFAULT_AVATAR; mBakedTextureData[i].mTexLayerSet = NULL; mBakedTextureData[i].mIsLoaded = false; - mBakedTextureData[i].mIsUsed = false; + //mBakedTextureData[i].mIsUsed = false; // KL SG mBakedTextureData[i].mMaskTexName = 0; mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i); } @@ -856,9 +858,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mRippleTimeLast = 0.f; mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c"); - gGL.getTexUnit(0)->bind(mShadowImagep.get()); - mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - + + // GL NOT ACTIVE HERE + //gGL.getTexUnit(0)->bind(mShadowImagep.get()); + //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); + mInAir = FALSE; mStepOnLand = TRUE; @@ -1295,7 +1299,7 @@ void LLVOAvatar::resetImpostors() // static void LLVOAvatar::deleteCachedImages(bool clearAll) { -if(gAuditTexture) +/* if(gAuditTexture) { S32 total_tex_size = sScratchTexBytes ; S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; @@ -1337,7 +1341,7 @@ if(gAuditTexture) total_tex_size -= 4 * tex_size ; } } - +*/ if (LLTexLayerSet::sHasCaches) { lldebugs << "Deleting layer set caches" << llendl; @@ -1862,6 +1866,11 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info) return TRUE; } +LLVOAvatar* LLVOAvatar::asAvatar() // KL SD +{ + return this; +} + //----------------------------------------------------------------------------- // LLVOAvatar::startDefaultMotions() //----------------------------------------------------------------------------- @@ -1924,7 +1933,7 @@ void LLVOAvatar::buildCharacter() LLTimer timer; BOOL status = loadAvatar(); - stop_glerror(); + // stop_glerror(); if (gNoRender) { @@ -2034,7 +2043,7 @@ void LLVOAvatar::buildCharacter() processAnimationStateChanges(); mIsBuilt = TRUE; - stop_glerror(); +// stop_glerror(); //------------------------------------------------------------------------- // build the attach and detach menus @@ -5022,7 +5031,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color) //------------------------------------------------------------------------ // LLVOAvatar::updateTextures() //------------------------------------------------------------------------ -void LLVOAvatar::updateTextures() +void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version { BOOL render_avatar = TRUE; @@ -5041,6 +5050,7 @@ void LLVOAvatar::updateTextures() } std::vector<bool> layer_baked; + // GL NOT ACTIVE HERE - *TODO for (U32 i = 0; i < mBakedTextureData.size(); i++) { layer_baked.push_back(isTextureDefined(mBakedTextureData[i].mTextureIndex)); @@ -5123,12 +5133,6 @@ void LLVOAvatar::updateTextures() if (texture_dict->mIsLocalTexture) { addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); - // SNOW-8 : temporary snowglobe1.0 fix for baked textures - if (render_avatar && !gGLManager.mIsDisabled ) - { - // bind the texture so that its boost level won't be slammed - gGL.getTexUnit(0)->bind(imagep); - } } else if (texture_dict->mIsBakedTexture) { @@ -5375,7 +5379,7 @@ void LLVOAvatar::processAnimationStateChanges() } } - stop_glerror(); + //stop_glerror(); } @@ -6360,6 +6364,15 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) } +void LLVOAvatar::updateGL() +{ + if (mMeshTexturesDirty) + { + updateMeshTextures(); + mMeshTexturesDirty = FALSE; + } +} + //----------------------------------------------------------------------------- // updateGeometry() //----------------------------------------------------------------------------- @@ -7396,12 +7409,20 @@ BOOL LLVOAvatar::bindScratchTexture( LLGLenum format ) if( *last_bind_time != LLImageGL::sLastFrameTime ) { *last_bind_time = LLImageGL::sLastFrameTime; - LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; +// #if !LL_RELEASE_FOR_DOWNLOAD +// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ; +// #else + LLImageGL::updateBoundTexMem(texture_bytes); +// #endif } } else { - LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; +// #if !LL_RELEASE_FOR_DOWNLOAD +// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ; +// #else + LLImageGL::updateBoundTexMem(texture_bytes); +// #endif LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) ); } @@ -7423,7 +7444,8 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) { case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; - case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; +// Support for GL_EXT_paletted_texture is deprecated +// case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; case GL_RGB: components = 3; internal_format = GL_RGB8; break; case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; @@ -7465,11 +7487,11 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) LLVOAvatar::sScratchTexBytes += *texture_bytes; LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes; - +/* if(gAuditTexture) { LLImageGL::incTextureCounterStatic(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; - } + }*/ return name; } @@ -7572,6 +7594,7 @@ void LLVOAvatar::updateMeshTextures() use_lkg_baked_layer[i] = (!is_layer_baked[i] && (mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) && mBakedTextureData[i].mTexLayerSet + && mBakedTextureData[i].mTexLayerSet->getComposite() // KL SD && !mBakedTextureData[i].mTexLayerSet->getComposite()->isInitialized()); if (use_lkg_baked_layer[i]) { @@ -7605,7 +7628,7 @@ void LLVOAvatar::updateMeshTextures() if (use_lkg_baked_layer[i] && !self_customizing ) { LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureData[i].mLastTextureIndex, target_host ); - mBakedTextureData[i].mIsUsed = TRUE; + //mBakedTextureData[i].mIsUsed = TRUE; for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) { mBakedTextureData[i].mMeshes[k]->setTexture( baked_img ); @@ -7635,7 +7658,7 @@ void LLVOAvatar::updateMeshTextures() { mBakedTextureData[i].mTexLayerSet->createComposite(); mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( TRUE ); - mBakedTextureData[i].mIsUsed = FALSE; + // mBakedTextureData[i].mIsUsed = FALSE; for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) { mBakedTextureData[i].mMeshes[k]->setLayerSet( mBakedTextureData[i].mTexLayerSet ); @@ -7656,9 +7679,13 @@ void LLVOAvatar::updateMeshTextures() mBakedTextureData[BAKED_HAIR].mMeshes[i]->setTexture( hair_img ); } mHasBakedHair = FALSE; - } - else + } + else { + for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++) + { + mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f ); + } mHasBakedHair = TRUE; } @@ -7790,7 +7817,7 @@ void LLVOAvatar::clearChat() S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index ) { // If the texture is not local, we don't care and treat it as fully loaded - if (!isIndexLocalTexture(index)) return 0; + if (!isIndexLocalTexture(index)) return FALSE; // KL SD version LocalTextureData &local_tex_data = mLocalTextureData[index]; if (index >= 0 @@ -7932,7 +7959,7 @@ bool LLVOAvatar::hasPendingBakedUploads() { for (U32 i = 0; i < mBakedTextureData.size(); i++) { - bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); + bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite() && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); if (upload_pending) { return true; @@ -8467,7 +8494,8 @@ void LLVOAvatar::onFirstTEMessageReceived() } } - updateMeshTextures(); + mMeshTexturesDirty = TRUE; // updateMeshTextures(); + gPipeline.markGLRebuild(this); } } @@ -8530,20 +8558,22 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // (isTextureDefined(TEX_SKIRT_BAKED) ? "SKIRT " : "skirt " ) << (getTEImage(TEX_SKIRT_BAKED)->getID()) << std::endl << // (isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl << // (isTextureDefined(TEX_EYES_BAKED) ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ; - + if( !mFirstTEMessageReceived ) { onFirstTEMessageReceived(); } setCompositeUpdatesEnabled( FALSE ); + mMeshTexturesDirty = TRUE; + gPipeline.markGLRebuild(this); // KL SD needing work in S19? if (!mIsSelf) { releaseUnnecessaryTextures(); } - - updateMeshTextures(); // enables updates for laysets without baked textures. + + //updateMeshTextures(); // enables updates for laysets without baked textures. // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); @@ -8829,7 +8859,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) if (id == image_baked->getID()) { mBakedTextureData[i].mIsLoaded = true; - mBakedTextureData[i].mIsUsed = true; + //mBakedTextureData[i].mIsUsed = true; mBakedTextureData[i].mLastTextureIndex = id; for (U32 k = 0; k < mBakedTextureData[i].mMeshes.size(); k++) { @@ -9738,9 +9768,9 @@ BOOL LLVOAvatar::updateLOD() LLFace* facep = mDrawable->getFace(0); if (facep->mVertexBuffer.isNull() || - LLVertexBuffer::sEnableVBOs && + (LLVertexBuffer::sEnableVBOs && ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) != - (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))) + (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))) { mDirtyMesh = TRUE; } diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index 0c32244e6..ff07d81e7 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h @@ -88,6 +88,8 @@ class LLVOAvatar : /*virtual*/ void markDead(); void startDefaultMotions(); + /*virtual*/ LLVOAvatar* asAvatar(); // KL SD + static void updateImpostors(); //-------------------------------------------------------------------- @@ -137,7 +139,7 @@ class LLVOAvatar : LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); // KL SD // If setting a baked texture, need to request it from a non-local sim. /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); /*virtual*/ void onShift(const LLVector3& shift_vector); @@ -155,6 +157,8 @@ class LLVOAvatar : /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); + /*virtual*/ void updateGL(); + /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); BOOL updateJointLODs(); @@ -474,6 +478,7 @@ class LLVOAvatar : LLFrameTimer mTypingTimer; //-------------------------------------------------------------------- + BOOL mMeshTexturesDirty; // wind rippling in clothes //-------------------------------------------------------------------- public: @@ -570,6 +575,7 @@ class LLVOAvatar : static BOOL sShowAnimationDebug; // show animation debug info static BOOL sUseImpostors; //use impostors for far away avatars static BOOL sShowFootPlane; // show foot collision plane reported by server + static BOOL sShowCollisionVolumes; // show skeletal collision volumes // KL SD static BOOL sVisibleInFirstPerson; static S32 sNumLODChangesThisFrame; static S32 sNumVisibleChatBubbles; @@ -771,7 +777,7 @@ class LLVOAvatar : LLUUID mLastTextureIndex; LLTexLayerSet* mTexLayerSet; bool mIsLoaded; - bool mIsUsed; + //bool mIsUsed; // KL SG LLVOAvatarDefines::ETextureIndex mTextureIndex; U32 mMaskTexName; // Stores pointers to the joint meshes that this baked texture deals with diff --git a/linden/indra/newview/llvoclouds.cpp b/linden/indra/newview/llvoclouds.cpp index a489f9177..019b6b4bc 100644 --- a/linden/indra/newview/llvoclouds.cpp +++ b/linden/indra/newview/llvoclouds.cpp @@ -101,7 +101,7 @@ void LLVOClouds::setPixelAreaAndAngle(LLAgent &agent) mPixelArea = 1500*100; } -void LLVOClouds::updateTextures() +void LLVOClouds::updateTextures(LLAgent &agent) { getTEImage(0)->addTextureStats(mPixelArea); } @@ -123,7 +123,10 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) return TRUE; } - dirtySpatialGroup(); + if (drawable->isVisible()) + { + dirtySpatialGroup(TRUE); + } LLFace *facep; diff --git a/linden/indra/newview/llvoclouds.h b/linden/indra/newview/llvoclouds.h index 52e5a681e..f70ea5b9e 100644 --- a/linden/indra/newview/llvoclouds.h +++ b/linden/indra/newview/llvoclouds.h @@ -65,7 +65,7 @@ class LLVOClouds : public LLAlphaObject /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. F32 getPartSize(S32 idx); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area void updateFaceSize(S32 idx) { } diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index 08f27170d..c56d676a7 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -331,7 +331,7 @@ void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent) // BUG could speed this up by caching the relative_position and range calculations -void LLVOGrass::updateTextures() +void LLVOGrass::updateTextures(LLAgent &agent) { if (getTEImage(0)) { diff --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index 682fbdbf5..c55c59b73 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -72,7 +72,7 @@ class LLVOGrass : public LLAlphaObject LLStrider<U16>& indicesp); void updateFaceSize(S32 idx) { } - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ BOOL updateLOD(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area diff --git a/linden/indra/newview/llvoground.cpp b/linden/indra/newview/llvoground.cpp index 0ef0196cc..fe19e1815 100644 --- a/linden/indra/newview/llvoground.cpp +++ b/linden/indra/newview/llvoground.cpp @@ -71,7 +71,7 @@ BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } -void LLVOGround::updateTextures() +void LLVOGround::updateTextures(LLAgent &agent) { } diff --git a/linden/indra/newview/llvoground.h b/linden/indra/newview/llvoground.h index b58ebae33..f485bd0aa 100644 --- a/linden/indra/newview/llvoground.h +++ b/linden/indra/newview/llvoground.h @@ -51,7 +51,7 @@ class LLVOGround : public LLStaticViewerObject // Graphical stuff for objects - maybe broken out into render class // later? - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvopartgroup.cpp b/linden/indra/newview/llvopartgroup.cpp index a0f80689e..b04036623 100644 --- a/linden/indra/newview/llvopartgroup.cpp +++ b/linden/indra/newview/llvopartgroup.cpp @@ -108,7 +108,7 @@ void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) } } -void LLVOPartGroup::updateTextures() +void LLVOPartGroup::updateTextures(LLAgent &agent) { // Texture stats for particles need to be updated in a different way... } @@ -154,6 +154,11 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) group = drawable->getSpatialGroup(); } + if (group && group->isVisible()) + { + dirtySpatialGroup(TRUE); + } + if (!num_parts) { if (group && drawable->getNumFaces()) @@ -186,13 +191,12 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) S32 count=0; mDepth = 0.f; S32 i = 0 ; - LLVector3 camera_agent = getCameraPosition(); for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++) { const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; LLVector3 part_pos_agent(part->mPosAgent); - LLVector3 at(part_pos_agent - camera_agent); + LLVector3 at(part_pos_agent - LLViewerCamera::getInstance()->getOrigin()); F32 camera_dist_squared = at.lengthSquared(); F32 inv_camera_dist_squared; @@ -315,7 +319,7 @@ void LLVOPartGroup::getGeometry(S32 idx, up *= 0.5f*part.mScale.mV[1]; - LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); + const LLVector3& normal = -LLViewerCamera::getInstance()->getXAxis(); *verticesp++ = part_pos_agent + up - right; *verticesp++ = part_pos_agent - up - right; @@ -352,12 +356,12 @@ U32 LLVOPartGroup::getPartitionType() const } LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; mPartitionType = LLViewerRegion::PARTITION_PARTICLE; - mBufferUsage = GL_DYNAMIC_DRAW_ARB; + // mBufferUsage = GL_DYNAMIC_DRAW_ARB; // KL SD hybrid code mSlopRatio = 0.f; mLODPeriod = 1; } @@ -481,7 +485,9 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) U32 end = start + facep->getGeomCount()-1; U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); - LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), buffer, fullbright); + LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), + facep->getTexture(), + buffer, fullbright); info->mExtents[0] = group->mObjectExtents[0]; info->mExtents[1] = group->mObjectExtents[1]; info->mVSize = vsize; diff --git a/linden/indra/newview/llvopartgroup.h b/linden/indra/newview/llvopartgroup.h index 18583b4be..3dc329299 100644 --- a/linden/indra/newview/llvopartgroup.h +++ b/linden/indra/newview/llvopartgroup.h @@ -61,7 +61,7 @@ class LLVOPartGroup : public LLAlphaObject virtual U32 getPartitionType() const; /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvosky.cpp b/linden/indra/newview/llvosky.cpp index d15a2dc35..2200c0281 100644 --- a/linden/indra/newview/llvosky.cpp +++ b/linden/indra/newview/llvosky.cpp @@ -289,7 +289,7 @@ void LLSkyTex::create(const F32 brightness) void LLSkyTex::createGLImage(S32 which) { - mImageGL[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerImageBoostLevel::OTHER); + mImageGL[which]->createGLTexture(0, mImageRaw[which]); mImageGL[which]->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -1095,10 +1095,10 @@ BOOL LLVOSky::updateSky() mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]); if ( mForceUpdate - || ((dot_lighting < LIGHT_DIRECTION_THRESHOLD) + || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD) || (delta_color.length() > COLOR_CHANGE_THRESHOLD) || !mInitialized) - && !direction.isExactlyZero()) + && !direction.isExactlyZero())) { mLastLightingDirection = direction; mLastTotalAmbient = mTotalAmbient; @@ -1180,7 +1180,7 @@ BOOL LLVOSky::updateSky() return TRUE; } -void LLVOSky::updateTextures() +void LLVOSky::updateTextures(LLAgent &agent) { if (mSunTexturep) { diff --git a/linden/indra/newview/llvosky.h b/linden/indra/newview/llvosky.h index dabf5b18b..5e2306515 100644 --- a/linden/indra/newview/llvosky.h +++ b/linden/indra/newview/llvosky.h @@ -147,7 +147,7 @@ class LLSkyTex static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } - static S32 stepCurrent() { sCurrent++; sCurrent&=1; return sCurrent; } + static S32 stepCurrent() { return (sCurrent = ++sCurrent % 2); } static S32 getNext() { return ((sCurrent+1) % 2); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } @@ -492,7 +492,7 @@ class LLVOSky : public LLStaticViewerObject // Graphical stuff for objects - maybe broken out into render class // later? - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvosurfacepatch.cpp b/linden/indra/newview/llvosurfacepatch.cpp index d86f7585a..a6fc1256f 100644 --- a/linden/indra/newview/llvosurfacepatch.cpp +++ b/linden/indra/newview/llvosurfacepatch.cpp @@ -134,7 +134,7 @@ void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent) } -void LLVOSurfacePatch::updateTextures() +void LLVOSurfacePatch::updateTextures(LLAgent &agent) { } @@ -177,11 +177,19 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) } +void LLVOSurfacePatch::updateGL() +{ + if (mPatchp) + { + mPatchp->updateGL(); + } +} + BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN); - dirtySpatialGroup(); + dirtySpatialGroup(TRUE); S32 min_comp, max_comp, range; min_comp = lltrunc(mPatchp->getMinComposition()); @@ -1013,12 +1021,12 @@ U32 LLVOSurfacePatch::getPartitionType() const } LLTerrainPartition::LLTerrainPartition() -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB) { mOcclusionEnabled = FALSE; - mRenderByGroup = FALSE; + //mRenderByGroup = FALSE; // KL not for SD hybrid code mInfiniteFarClip = TRUE; - mBufferUsage = GL_DYNAMIC_DRAW_ARB; + //mBufferUsage = GL_DYNAMIC_DRAW_ARB; // and here too! mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN; mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } diff --git a/linden/indra/newview/llvosurfacepatch.h b/linden/indra/newview/llvosurfacepatch.h index d3b144774..aaf4d41fa 100644 --- a/linden/indra/newview/llvosurfacepatch.h +++ b/linden/indra/newview/llvosurfacepatch.h @@ -64,6 +64,7 @@ class LLVOSurfacePatch : public LLStaticViewerObject virtual U32 getPartitionType() const; /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); + /*virtual*/ void updateGL(); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); /*virtual*/ void updateFaceSize(S32 idx); @@ -74,7 +75,7 @@ class LLVOSurfacePatch : public LLStaticViewerObject LLStrider<LLVector2> &texCoords1p, LLStrider<U16> &indicesp); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); diff --git a/linden/indra/newview/llvotextbubble.cpp b/linden/indra/newview/llvotextbubble.cpp index 5943f9be9..de69aac03 100644 --- a/linden/indra/newview/llvotextbubble.cpp +++ b/linden/indra/newview/llvotextbubble.cpp @@ -116,7 +116,7 @@ BOOL LLVOTextBubble::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } -void LLVOTextBubble::updateTextures() +void LLVOTextBubble::updateTextures(LLAgent &agent) { // Update the image levels of all textures... diff --git a/linden/indra/newview/llvotextbubble.h b/linden/indra/newview/llvotextbubble.h index 7f84dbf63..45d4df2a7 100644 --- a/linden/indra/newview/llvotextbubble.h +++ b/linden/indra/newview/llvotextbubble.h @@ -44,7 +44,7 @@ class LLVOTextBubble : public LLAlphaObject /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index 208086fca..89d649121 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -480,7 +480,7 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) #endif } -void LLVOTree::updateTextures() +void LLVOTree::updateTextures(LLAgent &agent) { if (mTreeImagep) { @@ -1316,9 +1316,9 @@ U32 LLVOTree::getPartitionType() const } LLTreePartition::LLTreePartition() -: LLSpatialPartition(0) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; + // mRenderByGroup = FALSE; // SD hybrid mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; mSlopRatio = 0.f; diff --git a/linden/indra/newview/llvotree.h b/linden/indra/newview/llvotree.h index 855c612b8..7804ab3f9 100644 --- a/linden/indra/newview/llvotree.h +++ b/linden/indra/newview/llvotree.h @@ -69,7 +69,7 @@ class LLVOTree : public LLViewerObject // Graphical stuff for objects - maybe broken out into render class later? /*virtual*/ void render(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvotreenew.h b/linden/indra/newview/llvotreenew.h index 4960d909c..02f6d3a05 100644 --- a/linden/indra/newview/llvotreenew.h +++ b/linden/indra/newview/llvotreenew.h @@ -156,7 +156,7 @@ class LLVOTreeNew : public LLViewerObject /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ void render(LLAgent &agent); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index 385dbe0c4..d4c4020f0 100644 --- a/linden/indra/newview/llvovolume.cpp +++ b/linden/indra/newview/llvovolume.cpp @@ -54,6 +54,7 @@ #include "llspatialpartition.h" #include "llhudmanager.h" #include "llflexibleobject.h" + #include "llsky.h" #include "lltexturefetch.h" #include "llviewercamera.h" @@ -67,6 +68,9 @@ const S32 MIN_QUIET_FRAMES_COALESCE = 30; const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; +const F32 MAX_LOD_DISTANCE = 24.f; +const S32 MAX_SCULPT_REZ = 128; + BOOL gAnimateTextures = TRUE; extern BOOL gHideSelectedObjects; @@ -91,6 +95,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mNumFaces = 0; mLODChanged = FALSE; mSculptChanged = FALSE; + mSpotLightPriority = 0.f; } LLVOVolume::~LLVOVolume() @@ -214,7 +219,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, std::string mask; mask = gDirUtilp->getDirDelimiter() + "*.slc"; gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), mask); -// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl; +// llwarns << "Bogus TE data in " << getID() << ", crashing!" << llendl; llwarns << "Bogus TE data in " << getID() << llendl; } else if (res2 & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR)) @@ -314,11 +319,6 @@ void LLVOVolume::animateTextures() te->getScale(&scale_s, &scale_t); } - LLVector3 scale(scale_s, scale_t, 1.f); - LLVector3 trans(off_s+0.5f, off_t+0.5f, 0.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); - if (!facep->mTextureMatrix) { facep->mTextureMatrix = new LLMatrix4(); @@ -326,7 +326,43 @@ void LLVOVolume::animateTextures() LLMatrix4& tex_mat = *facep->mTextureMatrix; tex_mat.setIdentity(); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + LLVector3 trans ; + + if(facep->isAtlasInUse()) + { + // + //if use atlas for animated texture + //apply the following transform to the animation matrix. + // + + F32 tcoord_xoffset = 0.f ; + F32 tcoord_yoffset = 0.f ; + F32 tcoord_xscale = 1.f ; + F32 tcoord_yscale = 1.f ; + if(facep->isAtlasInUse()) + { + const LLVector2* tmp = facep->getTexCoordOffset() ; + tcoord_xoffset = tmp->mV[0] ; + tcoord_yoffset = tmp->mV[1] ; + + tmp = facep->getTexCoordScale() ; + tcoord_xscale = tmp->mV[0] ; + tcoord_yscale = tmp->mV[1] ; + } + trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); + + tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); + } + else //non atlas + { + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + } + + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); + tex_mat.rotate(quat); LLMatrix4 mat; @@ -403,30 +439,28 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) return TRUE; } -void LLVOVolume::updateTextures() +void LLVOVolume::updateTextures(LLAgent &agent) // KL sd { const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds - if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) + if (mDrawable.notNull() && mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) { - updateTextureVirtualSize(); + if (mDrawable->isVisible()) + { + updateTextures(); + } } } -void LLVOVolume::updateTextureVirtualSize() +void LLVOVolume::updateTextures() { // Update the pixel area of all faces - if(mDrawable.isNull() || !mDrawable->isVisible()) - { - return ; - } - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) { return; } - if (LLViewerImage::sDontLoadVolumeTextures || LLAppViewer::getTextureFetch()->mDebugPause) + if (LLViewerImage::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible()) { return; } @@ -443,15 +477,14 @@ void LLVOVolume::updateTextureVirtualSize() LLFace* face = mDrawable->getFace(i); const LLTextureEntry *te = face->getTextureEntry(); LLViewerImage *imagep = face->getTexture(); - if (!imagep || !te || + if (!imagep || !te || face->mExtents[0] == face->mExtents[1]) { continue; } F32 vsize; - F32 old_size = face->getVirtualSize(); - + if (isHUDAttachment()) { F32 area = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); @@ -461,21 +494,24 @@ void LLVOVolume::updateTextureVirtualSize() } else { - vsize = face->getTextureVirtualSize(); + vsize = getTextureVirtualSize(face); } - mPixelArea = llmax(mPixelArea, face->getPixelArea()); + mPixelArea = llmax(mPixelArea, face->getPixelArea()); + + F32 old_size = face->getVirtualSize(); if (face->mTextureMatrix != NULL) { - if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || - (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) + if (vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE || + vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE); } } face->setVirtualSize(vsize); + // imagep->addTextureStats(vsize); if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { if (vsize < min_vsize) min_vsize = vsize; @@ -503,46 +539,46 @@ void LLVOVolume::updateTextureVirtualSize() mSculptTexture = gImageList.getImage(id); if (mSculptTexture.notNull()) { + S32 lod = llmin(mLOD, 3); + F32 lodf = ((F32)(lod + 1.0f)/4.f); + F32 tex_size = lodf * MAX_SCULPT_REZ; + mSculptTexture->addTextureStats(2.f * tex_size * tex_size); mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), (S32)LLViewerImageBoostLevel::BOOST_SCULPTED)); - mSculptTexture->setForSculpt() ; - - if(!mSculptTexture->isCachedRawImageReady()) - { - S32 lod = llmin(mLOD, 3); - F32 lodf = ((F32)(lod + 1.0f)/4.f); - F32 tex_size = lodf * LLViewerImage::sMaxSculptRez ; - mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); - - //if the sculpty very close to the view point, load first - { - LLVector3 lookAt = getPositionAgent() - LLViewerCamera::getInstance()->getOrigin(); - F32 dist = lookAt.normVec() ; - F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; - mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ; - } - } - - S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture - S32 current_discard = mSculptLevel; + } - if (texture_discard >= 0 && //texture has some data available - (texture_discard < current_discard || //texture has more data than last rebuild - current_discard < 0)) //no previous rebuild - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); - mSculptChanged = TRUE; - } + S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture + S32 current_discard = mSculptLevel; - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) + if (texture_discard >= 0 && //texture has some data available + (texture_discard < current_discard || //texture has more data than last rebuild + current_discard < 0)) //no previous rebuild + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); + mSculptChanged = TRUE; + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) { setDebugText(llformat("T%d C%d V%d\n%dx%d", - texture_discard, current_discard, getVolume()->getSculptLevel(), - mSculptTexture->getHeight(), mSculptTexture->getWidth())); + texture_discard, current_discard, getVolume()->getSculptLevel(), + mSculptTexture->getHeight(), mSculptTexture->getWidth())); } - } } + if (getLightTextureID().notNull()) + { + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + LLUUID id = params->getLightTexture(); + mLightTexture = gImageList.getImage(id); + if (mLightTexture.notNull()) + { + F32 rad = getLightRadius(); + mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), + LLVector3(rad,rad,rad), + *LLViewerCamera::getInstance())); + } + } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { @@ -563,6 +599,36 @@ void LLVOVolume::updateTextureVirtualSize() } } +F32 LLVOVolume::getTextureVirtualSize(LLFace* face) +{ + //get area of circle around face + LLVector3 center = face->getPositionAgent(); + LLVector3 size = (face->mExtents[1] - face->mExtents[0]) * 0.5f; + + F32 face_area = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + + face->setPixelArea(face_area); + + if (face_area <= 0) + { + return 0.f; + } + + //get area of circle in texture space + LLVector2 tdim = face->mTexExtents[1] - face->mTexExtents[0]; + F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; + if (texel_area <= 0) + { + // Probably animated, use default + texel_area = 1.f; + } + + //apply texel area to face area to get accurate ratio + face_area /= llclamp(texel_area, 1.f/64.f, 16.f); + + return face_area; +} + BOOL LLVOVolume::isActive() const { return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()); @@ -699,21 +765,31 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() -{ +{ + U16 sculpt_height = 0; + U16 sculpt_width = 0; + S8 sculpt_components = 0; + const U8* sculpt_data = NULL; + if (mSculptTexture.notNull()) - { - U16 sculpt_height = 0; - U16 sculpt_width = 0; - S8 sculpt_components = 0; - const U8* sculpt_data = NULL; - - S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; - LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; + { + S32 discard_level; + S32 desired_discard = 0; // lower discard levels have MUCH less resolution + + discard_level = desired_discard; S32 max_discard = mSculptTexture->getMaxDiscardLevel(); if (discard_level > max_discard) discard_level = max_discard; // clamp to the best we can do + S32 best_discard = mSculptTexture->getDiscardLevel(); + if (discard_level < best_discard) + discard_level = best_discard; // clamp to what we have + + if (best_discard == -1) + discard_level = -1; // and if we have nothing, set to nothing + + S32 current_discard = getVolume()->getSculptLevel(); if(current_discard < -2) { @@ -735,17 +811,28 @@ void LLVOVolume::sculpt() if (current_discard == discard_level) // no work to do here return; - if(!raw_image) + LLPointer<LLImageRaw> raw_image = new LLImageRaw(); + BOOL is_valid = mSculptTexture->readBackRaw(discard_level, raw_image, FALSE); + + sculpt_height = raw_image->getHeight(); + sculpt_width = raw_image->getWidth(); + sculpt_components = raw_image->getComponents(); + + if(is_valid) + { + is_valid = mSculptTexture->isValidForSculpt(discard_level, sculpt_width, sculpt_height, sculpt_components) ; + } + if(!is_valid) { sculpt_width = 0; sculpt_height = 0; sculpt_data = NULL ; } else - { - sculpt_height = raw_image->getHeight(); - sculpt_width = raw_image->getWidth(); - sculpt_components = raw_image->getComponents(); + { + if (raw_image->getDataSize() < sculpt_height * sculpt_width * sculpt_components) + llwarns << "Sculpt: image data size = " << raw_image->getDataSize() + << " < " << sculpt_height << " x " << sculpt_width << " x " <<sculpt_components << llendl; sculpt_data = raw_image->getData(); } @@ -777,7 +864,7 @@ BOOL LLVOVolume::calcLOD() } //update face texture sizes on lod calculation - updateTextureVirtualSize(); + // updateTextureVirtualSize(); S32 cur_detail = 0; @@ -1231,28 +1318,15 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color) S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) + S32 res = LLViewerObject::setTEColor(te, color); + if (res && mDrawable.notNull()) { - llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; + //gPipeline.markTextured(mDrawable); + mDrawable->setState(LLDrawable::REBUILD_COLOR); + dirtyMesh(); + //mFaceMappingChanged = TRUE; } - else if (color != tep->getColor()) - { - if (color.mV[3] != tep->getColor().mV[3]) - { - gPipeline.markTextured(mDrawable); - } - retval = LLPrimitive::setTEColor(te, color); - if (mDrawable.notNull() && retval) - { - // These should only happen on updates which are not the initial update. - mDrawable->setState(LLDrawable::REBUILD_COLOR); - dirtyMesh(); - } - } - - return retval; + return res; } S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap) @@ -1318,7 +1392,7 @@ S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump) gPipeline.markTextured(mDrawable); mFaceMappingChanged = TRUE; } - return res; + return res; } S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) @@ -1387,6 +1461,40 @@ void LLVOVolume::updateTEData() //---------------------------------------------------------------------------- +void LLVOVolume::setLightTextureID(LLUUID id) +{ + if (id.notNull()) + { + if (!hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); + } + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getLightTexture() != id) + { + param_block->setLightTexture(id); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } + } + else + { + if (hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); + } + } +} + +void LLVOVolume::setSpotLightParams(LLVector3 params) +{ + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getParams() != params) + { + param_block->setParams(params); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } +} + void LLVOVolume::setIsLight(BOOL is_light) { if (is_light != getIsLight()) @@ -1513,6 +1621,77 @@ LLColor3 LLVOVolume::getLightColor() const } } +LLUUID LLVOVolume::getLightTextureID() const +{ + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getLightTexture(); + } + + return LLUUID::null; +} + + +LLVector3 LLVOVolume::getSpotLightParams() const +{ + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getParams(); + } + + return LLVector3(); +} + +F32 LLVOVolume::getSpotLightPriority() const +{ + return mSpotLightPriority; +} + +void LLVOVolume::updateSpotLightPriority() +{ + LLVector3 pos = mDrawable->getPositionAgent(); + LLVector3 at(0,0,-1); + at *= getRenderRotation(); + + F32 r = getLightRadius()*0.5f; + + pos += at * r; + + at = LLViewerCamera::getInstance()->getAtAxis(); + + pos -= at * r; + + mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); + // KL needed for S19? + if (mLightTexture.notNull()) + { + mLightTexture->addTextureStats(mSpotLightPriority); + mLightTexture->setBoostLevel(LLViewerImageBoostLevel::BOOST_CLOUDS); + } +} + + +LLViewerImage* LLVOVolume::getLightTexture() +{ + LLUUID id = getLightTextureID(); + + if (id.notNull()) + { + if (mLightTexture.isNull() || id != mLightTexture->getID()) + { + mLightTexture = gImageList.getImage(id); + } + } + else + { + mLightTexture = NULL; + } + + return mLightTexture; +} + F32 LLVOVolume::getLightIntensity() const { const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); @@ -1604,6 +1783,16 @@ BOOL LLVOVolume::isSculpted() const return FALSE; } +BOOL LLVOVolume::hasLightTexture() const +{ + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + return TRUE; + } + + return FALSE; +} + BOOL LLVOVolume::isVolumeGlobal() const { if (mVolumeImpl) @@ -2056,9 +2245,9 @@ U32 LLVOVolume::getPartitionType() const } LLVolumePartition::LLVolumePartition() -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, FALSE) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) // KL { - mLODPeriod = 16; + mLODPeriod = 32; // KL 32 in SD mDepthMask = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_VOLUME; @@ -2067,10 +2256,10 @@ LLVolumePartition::LLVolumePartition() } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) -: LLSpatialBridge(drawablep, LLVOVolume::VERTEX_DATA_MASK) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK) // KL SD { mDepthMask = FALSE; - mLODPeriod = 16; + mLODPeriod = 32; // KL 32 in SD mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; @@ -2125,7 +2314,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); - LLViewerImage* tex = facep->getTexture(); + LLImageGL* tex = facep->getGLTexture(); // LLViewerImage* tex = facep->getTexture(); // KL SD U8 glow = 0; @@ -2136,7 +2325,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (facep->mVertexBuffer.isNull()) { - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } if (idx >= 0 && @@ -2167,6 +2356,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset,tex, + (LLImageGL*)facep->getTexture() == tex ? facep->getTexture() : NULL, facep->mVertexBuffer, fullbright, bump); draw_info->mGroup = group; draw_info->mVSize = facep->getVirtualSize(); @@ -2254,9 +2444,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); llassert_always(vobj); - vobj->updateTextureVirtualSize(); + vobj->updateTextures(); vobj->preRebuild(); + drawablep->clearState(LLDrawable::HAS_ALPHA); // KL SD + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -2325,6 +2517,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { + drawablep->setState(LLDrawable::HAS_ALPHA); // KL SD alpha_faces.push_back(facep); } } @@ -2348,7 +2541,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); + //facep->setState(LLFace::FULLBRIGHT); fullbright_faces.push_back(facep); } } @@ -2358,14 +2551,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //needs normal + binormal bump_faces.push_back(facep); } - else if ((te->getShiny() && LLPipeline::sRenderBump) || + else if (te->getShiny() && LLPipeline::sRenderBump || !te->getFullbright()) { //needs normal simple_faces.push_back(facep); } else { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); + // facep->setState(LLFace::FULLBRIGHT); fullbright_faces.push_back(facep); } } @@ -2413,7 +2606,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (LLPipeline::sDelayVBUpdate) { - group->setState(LLSpatialGroup::MESH_DIRTY); + group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); // KL SD } mFaceList.clear(); @@ -2421,7 +2614,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::MESH_DIRTY)) + if (group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) // KL SD { S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ; @@ -2499,7 +2692,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } } - group->clearState(LLSpatialGroup::MESH_DIRTY); + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); // KL SD } } @@ -2524,7 +2717,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: LLSpatialGroup::buffer_map_t buffer_map; - LLViewerImage* last_tex = NULL; + LLImageGL* last_tex = NULL;// LLViewerImage* last_tex = NULL; // KL SD S32 buffer_index = 0; if (distance_sort) @@ -2536,7 +2729,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //pull off next face LLFace* facep = *face_iter; - LLViewerImage* tex = facep->getTexture(); + LLImageGL* tex = facep->getGLTexture(); // LLViewerImage* tex = facep->getTexture(); // KL SD if (distance_sort) { @@ -2561,7 +2754,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: ++i; while (i != faces.end() && - (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) + (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getGLTexture() == tex))) // KL SD getTexture { facep = *i; @@ -2644,6 +2837,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); + if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) // KL SD + { //paranoia check to make sure GL doesn't try to read non-existant normals + fullbright = TRUE; + } + const LLTextureEntry* te = facep->getTextureEntry(); BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; @@ -2695,7 +2893,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - llassert(mask & LLVertexBuffer::MAP_NORMAL); + // llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } @@ -2726,7 +2924,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - llassert(mask & LLVertexBuffer::MAP_NORMAL); + // llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } @@ -2739,8 +2937,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!is_alpha && !LLPipeline::sRenderDeferred) { - llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); - facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); + // llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); + facep->setPoolType(LLDrawPool::POOL_SIMPLE); // facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); if (!force_simple && te->getBumpmap()) { @@ -2819,7 +3017,7 @@ LLHUDPartition::LLHUDPartition() mPartitionType = LLViewerRegion::PARTITION_HUD; mDrawableType = LLPipeline::RENDER_TYPE_HUD; mSlopRatio = 0.f; - mLODPeriod = 1; + mLODPeriod = 32; // KL 32 in SD } void LLHUDPartition::shift(const LLVector3 &offset) diff --git a/linden/indra/newview/llvovolume.h b/linden/indra/newview/llvovolume.h index a78aa37ff..4c6ad9af2 100644 --- a/linden/indra/newview/llvovolume.h +++ b/linden/indra/newview/llvovolume.h @@ -130,7 +130,7 @@ class LLVOVolume : public LLViewerObject BOOL getVolumeChanged() const { return mVolumeChanged; } - + F32 getTextureVirtualSize(LLFace* face); /*virtual*/ F32 getRadius() const { return mVObjRadius; }; const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; @@ -158,14 +158,14 @@ class LLVOVolume : public LLViewerObject /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump); /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny); /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright); - /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); + /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); // KL S19? /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s); /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t); /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen); - /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media); + /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media); // KL S19 /*virtual*/ BOOL setMaterial(const U8 material); void setTexture(const S32 face); @@ -177,8 +177,8 @@ class LLVOVolume : public LLViewerObject /*virtual*/ void updateFaceSize(S32 idx); /*virtual*/ BOOL updateLOD(); void updateRadius(); - /*virtual*/ void updateTextures(); - void updateTextureVirtualSize(); + /*virtual*/ void updateTextures(LLAgent &agent); + void updateTextures(); void updateFaceFlags(); void regenFaces(); @@ -196,9 +196,18 @@ class LLVOVolume : public LLViewerObject void setLightRadius(F32 radius); void setLightFalloff(F32 falloff); void setLightCutoff(F32 cutoff); + void setLightTextureID(LLUUID id); + void setSpotLightParams(LLVector3 params); + BOOL getIsLight() const; LLColor3 getLightBaseColor() const; // not scaled by intensity LLColor3 getLightColor() const; // scaled by intensity + LLUUID getLightTextureID() const; + LLVector3 getSpotLightParams() const; + void updateSpotLightPriority(); + F32 getSpotLightPriority() const; + + LLViewerImage* getLightTexture(); F32 getLightIntensity() const; F32 getLightRadius() const; F32 getLightFalloff() const; @@ -208,6 +217,8 @@ class LLVOVolume : public LLViewerObject U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; virtual BOOL isSculpted() const; + virtual BOOL hasLightTexture() const; + BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); @@ -233,12 +244,14 @@ class LLVOVolume : public LLViewerObject BOOL mLODChanged; S32 mSculptLevel; BOOL mSculptChanged; + F32 mSpotLightPriority; LLMatrix4 mRelativeXform; LLMatrix3 mRelativeXformInvTrans; BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; LLPointer<LLViewerImage> mSculptTexture; + LLPointer<LLViewerImage> mLightTexture; // statics public: diff --git a/linden/indra/newview/llvowater.cpp b/linden/indra/newview/llvowater.cpp index 5b6a9497d..25960dece 100644 --- a/linden/indra/newview/llvowater.cpp +++ b/linden/indra/newview/llvowater.cpp @@ -101,7 +101,7 @@ void LLVOWater::setPixelAreaAndAngle(LLAgent &agent) // virtual -void LLVOWater::updateTextures() +void LLVOWater::updateTextures(LLAgent &agent) { } @@ -276,9 +276,9 @@ U32 LLVOWater::getPartitionType() const } LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; + // mRenderByGroup = FALSE; // KL specified const SG branch not req here mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; mPartitionType = LLViewerRegion::PARTITION_WATER; diff --git a/linden/indra/newview/llvowater.h b/linden/indra/newview/llvowater.h index 9c33e743e..cdda48f6f 100644 --- a/linden/indra/newview/llvowater.h +++ b/linden/indra/newview/llvowater.h @@ -68,7 +68,7 @@ class LLVOWater : public LLStaticViewerObject /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area virtual U32 getPartitionType() const; diff --git a/linden/indra/newview/llwaterparammanager.cpp b/linden/indra/newview/llwaterparammanager.cpp index e01506e94..8ef11bea2 100644 --- a/linden/indra/newview/llwaterparammanager.cpp +++ b/linden/indra/newview/llwaterparammanager.cpp @@ -407,8 +407,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam) LLFloaterWater::instance()->syncMenu(); } - stop_glerror(); - + //stop_glerror(); // only do this if we're dealing with shaders if(gPipeline.canUseVertexShaders()) { diff --git a/linden/indra/newview/llwlparammanager.cpp b/linden/indra/newview/llwlparammanager.cpp index 31471d77c..09f7d017e 100644 --- a/linden/indra/newview/llwlparammanager.cpp +++ b/linden/indra/newview/llwlparammanager.cpp @@ -539,8 +539,7 @@ void LLWLParamManager::update(LLViewerCamera * cam) F32 camYaw = cam->getYaw(); - stop_glerror(); - + //stop_glerror(); // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h index 46aefd91d..9abb56588 100644 --- a/linden/indra/newview/llworld.h +++ b/linden/indra/newview/llworld.h @@ -2,7 +2,7 @@ * @file llworld.h * @brief Collection of viewer regions in the vacinity of the user. * - * Represents the whole world, so far as 3D functionality is conserned. + * Represents the whole world, so far as 3D functionality is concerned. * Always contains the region that the user's avatar is in along with * neighboring regions. As the user crosses region boundaries, new * regions are added to the world and distant ones are rolled up. @@ -151,7 +151,8 @@ class LLWorld : public LLSingleton<LLWorld> public: typedef std::list<LLViewerRegion*> region_list_t; - const region_list_t& getRegionList() const { return mActiveRegionList; } + region_list_t mActiveRegionList; // KL SD branch public not private + region_list_t& getRegionList() { return mActiveRegionList; } // Returns lists of avatar IDs and their world-space positions within a given distance of a point. // All arguments are optional. Given containers will be emptied and then filled. @@ -162,7 +163,6 @@ class LLWorld : public LLSingleton<LLWorld> const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX) const; private: - region_list_t mActiveRegionList; region_list_t mRegionList; region_list_t mVisibleRegionList; region_list_t mCulledRegionList; diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 72da3c631..4bf53af73 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -159,6 +159,8 @@ std::string gPoolNames[] = "POOL_ALPHA", }; +void drawBox(const LLVector3& c, const LLVector3& r); + U32 nhpo2(U32 v) { U32 r = 1; @@ -267,11 +269,11 @@ static const U32 gl_cube_face[] = void validate_framebuffer_object(); + void addDeferredAttachments(LLRenderTarget& target) { - target.addColorAttachment(GL_RGBA16F_ARB); //specular - target.addColorAttachment(GL_RGBA16F_ARB); //normal+z - target.addColorAttachment(GL_RGBA16F_ARB); //position + target.addColorAttachment(GL_RGBA); //specular //target.addColorAttachment(GL_RGBA16F_ARB); //specular // KL + target.addColorAttachment(GL_RGBA); //normal+z //target.addColorAttachment(GL_RGBA16F_ARB); //normal+z } LLPipeline::LLPipeline() : @@ -313,6 +315,8 @@ LLPipeline::LLPipeline() : mLightingDetail(0) { mNoiseMap = 0; + //mTrueNoiseMap = 0; // KL SD + mLightFunc = 0; // KL SD } void LLPipeline::init() @@ -362,6 +366,11 @@ void LLPipeline::init() LLViewerShaderMgr::instance()->setShaders(); stop_glerror(); + + for (U32 i = 0; i < 2; ++i) + { + mSpotLightFade[i] = 1.f; + } } LLPipeline::~LLPipeline() @@ -373,6 +382,9 @@ void LLPipeline::cleanup() { assertInitialized(); + mGroupQ1.clear() ; + mGroupQ2.clear() ; + for(pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ) { @@ -469,33 +481,69 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWindowDisplayWidth(); GLuint resY = gViewerWindow->getWindowDisplayHeight(); - U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); - if (res_mod > 1 && res_mod < resX && res_mod < resY) - { - resX /= res_mod; - resY /= res_mod; - } - allocateScreenBuffer(resX,resY); - - llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; } } void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { + U32 samples = gSavedSettings.getU32("RenderFSAASamples"); + U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); + + if (res_mod > 1 && res_mod < resX && res_mod < resY) + { + resX /= res_mod; + resY /= res_mod; + } + + if (gSavedSettings.getBOOL("RenderUIBuffer")) + { + //mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + } + if (LLPipeline::sRenderDeferred) { //allocate deferred rendering color buffers - mDeferredScreen.allocate(resX, resY, GL_RGBA16F_ARB, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); addDeferredAttachments(mDeferredScreen); - mScreen.allocate(resX, resY, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - + + // always set viewport to desired size, since allocate resets the viewport + + mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + + for (U32 i = 0; i < 3; i++) + { + mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + for (U32 i = 0; i < 2; i++) { - mDeferredLight[i].allocate(resX, resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + + F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); + + for (U32 i = 0; i < 4; i++) + { + mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); } + + + U32 width = nhpo2(U32(resX*scale))/2; + U32 height = width; + + for (U32 i = 4; i < 6; i++) + { + mShadow[i].allocate(width, height, 0, TRUE, FALSE); + } + + + + width = nhpo2(resX)/2; + height = nhpo2(resY)/2; + mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); } else { @@ -505,25 +553,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (gGLManager.mHasFramebufferMultisample && samples > 1) { + mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); if (LLPipeline::sRenderDeferred) { - mSampleBuffer.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); addDeferredAttachments(mSampleBuffer); mDeferredScreen.setSampleBuffer(&mSampleBuffer); } - else - { - mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); - } mScreen.setSampleBuffer(&mSampleBuffer); + stop_glerror(); } - else if (LLPipeline::sRenderDeferred) + + if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); - for (U32 i = 0; i < 2; i++) - { + for (U32 i = 0; i < 3; i++) + { //share stencil buffer with screen space lightmap to stencil out sky mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); } } @@ -556,17 +602,40 @@ void LLPipeline::releaseGLBuffers() mNoiseMap = 0; } +/* if (mTrueNoiseMap) + { + LLImageGL::deleteTextures(1, &mTrueNoiseMap); + mTrueNoiseMap = 0; + } +*/ + if (mLightFunc) + { + LLImageGL::deleteTextures(1, &mLightFunc); + mLightFunc = 0; + } + mWaterRef.release(); mWaterDis.release(); mScreen.release(); mSampleBuffer.releaseSampleBuffer(); mDeferredScreen.release(); + mDeferredDepth.release(); + for (U32 i = 0; i < 3; i++) + { + mDeferredLight[i].release(); + } + + mGIMap.release(); + mGIMapPost[0].release(); + mGIMapPost[1].release(); + mHighlight.release(); +// mLuminanceMap.release(); - - for (U32 i = 0; i < 4; i++) + for (U32 i = 0; i < 6; i++) // KL 6 in SD { - mSunShadow[i].release(); + mShadow[i].release(); } + for (U32 i = 0; i < 3; i++) { mGlow[i].release(); @@ -589,9 +658,13 @@ void LLPipeline::createGLBuffers() mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE); } + mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); stop_glerror(); + GLuint resX = gViewerWindow->getWindowDisplayWidth(); + GLuint resY = gViewerWindow->getWindowDisplayHeight(); + if (LLPipeline::sRenderGlow) { //screen space glow buffers const U32 glow_res = llmax(1, @@ -601,20 +674,13 @@ void LLPipeline::createGLBuffers() { mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); } - } - GLuint resX = gViewerWindow->getWindowDisplayWidth(); - GLuint resY = gViewerWindow->getWindowDisplayHeight(); - - allocateScreenBuffer(resX,resY); + allocateScreenBuffer(resX,resY); + } + if (sRenderDeferred) { - mSunShadow[0].allocate(1024,1024, 0, TRUE, FALSE); - mSunShadow[1].allocate(1024,1024, 0, TRUE, FALSE); - mSunShadow[2].allocate(1024,1024, 0, TRUE, FALSE); - mSunShadow[3].allocate(1024,1024, 0, TRUE, FALSE); - if (!mNoiseMap) { const U32 noiseRes = 128; @@ -634,7 +700,83 @@ void LLPipeline::createGLBuffers() LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - } + +/* if (!mTrueNoiseMap) + { + const U32 noiseRes = 128; + F32 noise[noiseRes*noiseRes*3]; + for (U32 i = 0; i < noiseRes*noiseRes*3; i++) + { + noise[i] = ll_frand()*2.0-1.0; + } + + LLImageGL::generateTextures(1, &mTrueNoiseMap); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } +*/ + if (!mLightFunc) + { + U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); + U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); + U8* lg = new U8[lightResX*lightResY]; + + for (U32 y = 0; y < lightResY; ++y) + { + for (U32 x = 0; x < lightResX; ++x) + { + //spec func + F32 sa = (F32) x/(lightResX-1); + F32 spec = (F32) y/(lightResY-1); + //lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255); + + //F32 sp = acosf(sa)/(1.f-spec); + + sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent")); + F32 a = acosf(sa*0.25f+0.75f); + F32 m = llmax(0.5f-spec*0.5f, 0.001f); + F32 t2 = tanf(a)/m; + t2 *= t2; + + F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f; + F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2); + + lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255); + } + } + + LLImageGL::generateTextures(1, &mLightFunc); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_ALPHA, lightResX, lightResY, GL_ALPHA, GL_UNSIGNED_BYTE, lg); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + + delete [] lg; +/* } + + if (gSavedSettings.getBOOL("RenderDeferredGI")) + { */ + mGIMap.allocate(1024,1024,GL_RGBA, TRUE, FALSE); + addDeferredAttachments(mGIMap); + + { + LLGLDepthTest depth(GL_TRUE); + gGL.setColorMask(true, true); + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].allocate(128,128,GL_RGB16F_ARB, FALSE, FALSE); + mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); + mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); + mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); + + mGIMapPost[i].bindTarget(); + mGIMapPost[i].clear(); + mGIMapPost[i].flush(); + } + } + } + } //mLuminanceMap.allocate(128,128, GL_RGBA, FALSE, FALSE); } void LLPipeline::restoreGL() @@ -646,7 +788,7 @@ void LLPipeline::restoreGL() LLViewerShaderMgr::instance()->setShaders(); } - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -700,7 +842,7 @@ void LLPipeline::unloadShaders() void LLPipeline::assertInitializedDoError() { - llerrs << "LLPipeline used when uninitialized." << llendl; + llwarns << "LLPipeline used when uninitialized." << llendl; } //============================================================================ @@ -763,7 +905,7 @@ class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable> for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { LLDrawInfo* params = *j; - if (mTextures.find(params->mTexture) != mTextures.end()) + if (mTextures.find(params->mViewerTexture) != mTextures.end()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } @@ -797,7 +939,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& texture } LLOctreeDirtyTexture dirty(textures); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -876,7 +1018,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) default: llassert(0); - llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; + llwarns << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; break; } @@ -991,7 +1133,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) #ifdef LL_RELEASE_FOR_DOWNLOAD llwarns << "Couldn't remove object from spatial group!" << llendl; #else - llerrs << "Couldn't remove object from spatial group!" << llendl; + llwarns << "Couldn't remove object from spatial group!" << llendl; #endif } } @@ -1006,6 +1148,31 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) break; } } + + { + HighlightItem item(drawablep); + mHighlightSet.erase(item); + + if (mHighlightObject == drawablep) + { + mHighlightObject = NULL; + } + } + + for (U32 i = 0; i < 2; ++i) + { + if (mShadowSpotLight[i] == drawablep) + { + mShadowSpotLight[i] = NULL; + } + + if (mTargetShadowSpotLight[i] == drawablep) + { + mTargetShadowSpotLight[i] = NULL; + } + } + + } U32 LLPipeline::addObject(LLViewerObject *vobj) @@ -1062,7 +1229,7 @@ void LLPipeline::createObject(LLViewerObject* vobj) } else { - llerrs << "Redundant drawable creation!" << llendl; + llwarns << "Redundant drawable creation!" << llendl; } llassert(drawablep); @@ -1123,7 +1290,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) } if (!drawablep) { - llerrs << "updateMove called with NULL drawablep" << llendl; + llwarns << "updateMove called with NULL drawablep" << llendl; return; } if (drawablep->isState(LLDrawable::EARLY_MOVE)) @@ -1153,7 +1320,8 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) } if (!drawablep) { - llerrs << "updateMove called with NULL drawablep" << llendl; + llwarns << "updateMove called with NULL drawablep" << llendl; + return; } if (drawablep->isState(LLDrawable::EARLY_MOVE)) { @@ -1245,7 +1413,7 @@ void LLPipeline::updateMove() { LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1272,7 +1440,6 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera F32 dist = lookAt.length(); //ramp down distance for nearby objects - //shrink dist by dist/16. if (dist < 16.f) { dist /= 16.f; @@ -1293,7 +1460,7 @@ void LLPipeline::grabReferences(LLCullResult& result) BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1325,7 +1492,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& BOOL res = TRUE; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1388,7 +1555,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1465,7 +1632,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) group->setVisible(); - if (!sSkipUpdate) + if (!sSkipUpdate) // && !sShadowRender) KL? { group->updateDistance(camera); } @@ -1556,6 +1723,78 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) return update_complete; } +void LLPipeline::updateGL() // KL SD +{ + while (!LLGLUpdate::sGLQ.empty()) + { + LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); + glu->updateGL(); + glu->mInQ = FALSE; + LLGLUpdate::sGLQ.pop_front(); + } +} // KL updateGL SD + +void LLPipeline::rebuildPriorityGroups() +{ + LLTimer update_timer; + LLMemType mt(LLMemType::MTYPE_PIPELINE); + + assertInitialized(); + + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + group->rebuildGeom(); + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + + mGroupQ1.clear(); +} + +void LLPipeline::rebuildGroups() +{ + // Iterate through some drawables on the non-priority build queue + S32 size = (S32) mGroupQ2.size(); + S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); + + S32 count = 0; + + std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); // KL + + LLSpatialGroup::sg_vector_t::iterator iter; + for (iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + if (group->isDead()) + { + continue; + } + + group->rebuildGeom(); + + if (group->mSpatialPartition->mRenderByGroup) + { + count++; + } + + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + + if (count > min_count) + { + ++iter; + break; + } + } + + mGroupQ2.erase(mGroupQ2.begin(), iter); + + updateMovedList(mMovedBridge); +} + void LLPipeline::updateGeom(F32 max_dtime) { LLTimer update_timer; @@ -1670,6 +1909,16 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) if (drawablep->isSpatialBridge()) { + LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; + + if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment()) + { + LLVOAvatar* av = root->getParent()->getVObj()->asAvatar(); + if (av->isImpostor()) + { + return; + } + } sCull->pushBridge((LLSpatialBridge*) drawablep); } else @@ -1686,7 +1935,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) if (!drawablep) { - //llerrs << "Sending null drawable to moved list!" << llendl; + //llwarns << "Sending null drawable to moved list!" << llendl; return; } @@ -1771,7 +2020,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) } mShiftList.resize(0); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1799,6 +2048,54 @@ void LLPipeline::markTextured(LLDrawable *drawablep) } } +void LLPipeline::markGLRebuild(LLGLUpdate* glu) +{ + if (glu && !glu->mInQ) + { + LLGLUpdate::sGLQ.push_back(glu); + glu->mInQ = TRUE; + } +} + +void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) +{ + LLMemType mt(LLMemType::MTYPE_PIPELINE); + //assert_main_thread(); + + if (group && !group->isDead() && group->mSpatialPartition) + { + if (priority) + { + if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) + { + mGroupQ1.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q1); + + if (group->isState(LLSpatialGroup::IN_BUILD_Q2)) + { + LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); + if (iter != mGroupQ2.end()) + { + mGroupQ2.erase(iter); + } + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + } + else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) + { + //llwarns << "Non-priority updates not yet supported!" << llendl; + if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) + { + llwarns << "WTF?" << llendl; + } + mGroupQ2.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q2); + + } + } +} + void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -1853,12 +2150,13 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) grabReferences(result); + //if (!LLPipeline::sShadowRender) { for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); - if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) + if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED)) { markOccluder(group); } @@ -1871,12 +2169,15 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } + } + if (!LLPipeline::sShadowRender) + { for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); - if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) + if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED)) { markOccluder(group); } @@ -1888,6 +2189,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } + if (!LLPipeline::sShadowRender) { for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { @@ -1939,7 +2241,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) + if (!sSkipUpdate && !sShadowRender && bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2001,41 +2303,46 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (!group || group->changeLOD()) + if (!sShadowRender) { - if (drawablep->isVisible() && !sSkipUpdate) + LLSpatialGroup* group = drawablep->getSpatialGroup(); + if (!group || group->changeLOD()) { - if (!drawablep->isActive()) + if (drawablep->isVisible() && !sSkipUpdate) { - bool force_update = false; - drawablep->updateDistance(camera, force_update); + if (!drawablep->isActive()) + { + drawablep->updateDistance(camera, TRUE); + } + else if (drawablep->isAvatar()) + { + drawablep->updateDistance(camera, TRUE); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() + } } - else if (drawablep->isAvatar()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() - } } } - for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); - iter != drawablep->mFaces.end(); iter++) + if (!drawablep->getVOVolume()) { - LLFace* facep = *iter; - - if (facep->hasGeometry()) + for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); + iter != drawablep->mFaces.end(); iter++) { - if (facep->getPool()) - { - facep->getPool()->enqueue(facep); - } - else + LLFace* facep = *iter; + + if (facep->hasGeometry()) { - break; + if (facep->getPool()) + { + facep->getPool()->enqueue(facep); + } + else + { + break; + } } } } + mNumVisibleFaces += drawablep->getNumFaces(); } @@ -2201,7 +2508,7 @@ void LLPipeline::postSort(LLCamera& camera) //rebuild groups sCull->assertDrawMapsEmpty(); - LLSpatialGroup::sNoDelete = FALSE; + /*LLSpatialGroup::sNoDelete = FALSE; for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; @@ -2213,8 +2520,10 @@ void LLPipeline::postSort(LLCamera& camera) group->rebuildGeom(); } - LLSpatialGroup::sNoDelete = TRUE; + LLSpatialGroup::sNoDelete = TRUE;*/ + + rebuildPriorityGroups(); const S32 bin_count = 1024*8; @@ -2240,39 +2549,51 @@ void LLPipeline::postSort(LLCamera& camera) { continue; } - + + if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY)) + { //no way this group is going to be drawable without a rebuild + group->rebuildGeom(); + } + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) { LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - + if (!hasRenderType(j->first)) + { + continue; + } + for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) { sCull->pushDrawInfo(j->first, *k); } } - LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); - - if (alpha != group->mDrawMap.end()) - { //store alpha groups for sorting - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); - if (!sSkipUpdate) - { - if (bridge) + if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) + { + LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); + + if (alpha != group->mDrawMap.end()) + { //store alpha groups for sorting + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + if (!sSkipUpdate) { - LLCamera trans_camera = bridge->transformCamera(camera); - group->updateDistance(trans_camera); + if (bridge) + { + LLCamera trans_camera = bridge->transformCamera(camera); + group->updateDistance(trans_camera); + } + else + { + group->updateDistance(camera); + } } - else + + if (hasRenderType(LLDrawPool::POOL_ALPHA)) { - group->updateDistance(camera); + sCull->pushAlphaGroup(group); } } - - if (hasRenderType(LLDrawPool::POOL_ALPHA)) - { - sCull->pushAlphaGroup(group); - } } } @@ -2370,7 +2691,7 @@ void LLPipeline::postSort(LLCamera& camera) } } - LLSpatialGroup::sNoDelete = FALSE; + //LLSpatialGroup::sNoDelete = FALSE; } @@ -2431,21 +2752,118 @@ void LLPipeline::renderHighlights() LLGLEnable color_mat(GL_COLOR_MATERIAL); disableLights(); - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightProgram.bind(); - gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,1,1,0.5f); - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) - { - // Make sure the selection image gets downloaded and decoded - if (!mFaceSelectImagep) + if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && !mHighlightSet.empty()) + { //draw blurry highlight image over screen + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + LLGLDisable test(GL_ALPHA_TEST); + + LLGLEnable stencil(GL_STENCIL_TEST); + gGL.flush(); + glStencilMask(0xFFFFFFFF); + glClearStencil(1); + glClear(GL_STENCIL_BUFFER_BIT); + + glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + + gGL.setColorMask(false, false); + for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter) { - // Load the select texture texture from file -- MC - mFaceSelectImagep = gImageList.getImageFromFile(IMG_FACE_SELECT.asString()+".j2c", TRUE, TRUE); /*gImageList.getImage(IMG_FACE_SELECT);*/ + renderHighlight(iter->mItem->getVObj(), 1.f); } - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + gGL.setColorMask(true, false); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); + + //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + + gGL.pushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + gGL.pushMatrix(); + glLoadIdentity(); + + gGL.getTexUnit(0)->bind(&mHighlight); + + LLVector2 tc1; + LLVector2 tc2; + + tc1.setVec(0,0); + tc2.setVec(2,2); + + gGL.begin(LLRender::TRIANGLES); + + F32 scale = gSavedSettings.getF32("RenderHighlightBrightness"); + LLColor4 color = gSavedSettings.getColor4("RenderHighlightColor"); + F32 thickness = gSavedSettings.getF32("RenderHighlightThickness"); + + for (S32 pass = 0; pass < 2; ++pass) + { + if (pass == 0) + { + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + } + else + { + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + + for (S32 i = 0; i < 8; ++i) + { + for (S32 j = 0; j < 8; ++j) + { + LLVector2 tc(i-4+0.5f, j-4+0.5f); + + F32 dist = 1.f-(tc.length()/sqrtf(32.f)); + dist *= scale/64.f; + + tc *= thickness; + tc.mV[0] = (tc.mV[0])/mHighlight.getWidth(); + tc.mV[1] = (tc.mV[1])/mHighlight.getHeight(); + + gGL.color4f(color.mV[0], + color.mV[1], + color.mV[2], + color.mV[3]*dist); + + gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc.mV[0]+tc2.mV[0], tc.mV[1]+tc1.mV[1]); + gGL.vertex2f(3,-1); + } + } + } + + gGL.end(); + + gGL.popMatrix(); + glMatrixMode(GL_MODELVIEW); + gGL.popMatrix(); + + //gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightProgram.bind(); + gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,1,1,0.5f); + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) + { + // Make sure the selection image gets downloaded and decoded + if (!mFaceSelectImagep) + { + // Load the select texture texture from file -- MC + mFaceSelectImagep = gImageList.getImageFromFile(IMG_FACE_SELECT.asString()+".j2c", TRUE, TRUE); /*gImageList.getImage(IMG_FACE_SELECT);*/ + } + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); U32 count = mSelectedFaces.size(); for (U32 i = 0; i < count; i++) @@ -2453,7 +2871,7 @@ void LLPipeline::renderHighlights() LLFace *facep = mSelectedFaces[i]; if (!facep || facep->getDrawable()->isDead()) { - llerrs << "Bad face on selection" << llendl; + llwarns << "Bad face on selection" << llendl; return; } @@ -2526,7 +2944,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { if (!verify()) { - llerrs << "Pipeline verification failed!" << llendl; + llwarns << "Pipeline verification failed!" << llendl; } } @@ -2575,6 +2993,9 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) stop_glerror(); LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDeferred"); + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { LLDrawPool *poolp = *iter; @@ -2586,7 +3007,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect()); } else @@ -2650,7 +3070,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); if (depth > 3) { - llerrs << "GL matrix stack corrupted!" << llendl; + + llwarns << "GL matrix stack corrupted!" << llendl; } std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); LLGLState::checkStates(msg); @@ -2721,20 +3142,12 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLVertexBuffer::unbind(); - if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) + if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - LLHUDObject::renderAll(); - gObjectList.resetObjectBeacons(); - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + LLHUDObject::renderAll(); + gObjectList.resetObjectBeacons(); } LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); @@ -2758,7 +3171,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) void LLPipeline::renderGeomDeferred(LLCamera& camera) { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); LLFastTimer t2(LLFastTimer::FTM_POOLS); @@ -2825,15 +3237,18 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) poolp->endDeferredPass(i); LLVertexBuffer::unbind(); - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) + if (gDebugGL || gDebugPipeline) { - llerrs << "GL matrix stack corrupted!" << llendl; + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth > 3) + { + llwarns << "GL matrix stack corrupted!" << llendl; + } + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); } - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } } else @@ -2915,15 +3330,18 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) poolp->endPostDeferredPass(i); LLVertexBuffer::unbind(); - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) + if (gDebugGL || gDebugPipeline) { - llerrs << "GL matrix stack corrupted!" << llendl; + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth > 3) + { + llwarns << "GL matrix stack corrupted!" << llendl; + } + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); } - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } } else @@ -2959,11 +3377,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLHUDObject::renderAll(); gObjectList.resetObjectBeacons(); } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } if (occlude) { @@ -3067,7 +3480,7 @@ void LLPipeline::renderDebug() gGL.setColorMask(true, false); // Debug stuff. - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -3084,7 +3497,7 @@ void LLPipeline::renderDebug() } } - for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) @@ -3098,93 +3511,88 @@ void LLPipeline::renderDebug() if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + LLGLEnable blend(GL_BLEND); // kl sd + LLGLDepthTest depth(TRUE, FALSE); + LLGLDisable cull(GL_CULL_FACE); // kl + gGL.color4f(1,1,1,1); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + F32 a = 0.1f; + F32 col[] = { - 1,1,0, - 0,1,1, - 1,0,1, - 1,1,1, - 1,0,0, - 0,1,0, - 0,0,1, - 0,0,0 + 1,0,0,a, + 0,1,0,a, + 0,0,1,a, + 1,0,1,a, + + 1,1,0,a, + 0,1,1,a, + 1,1,1,a, + 1,0,1,a, }; for (U32 i = 0; i < 8; i++) { - gGL.color3fv(col+i*3); - - gGL.begin(LLRender::LINES); - - LLVector3* frust = mShadowCamera[i].mAgentFrustum; - - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); - - gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); - - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + if (i > 3) + { + gGL.color4fv(col+(i-4)*4); + LLVector3* frust = mShadowCamera[i].mAgentFrustum; + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.end(); + + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); + gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[2].mV); + gGL.end(); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[6].mV); + gGL.end(); + } + + if (i < 4) { - LLVector3* ext = mShadowExtents[i]; + gGL.begin(LLRender::LINES); - LLVector3 box[] = + F32* c = col+i*4; + for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) { - LLVector3(ext[0][0], ext[0][1], ext[0][2]), - LLVector3(ext[1][0], ext[0][1], ext[0][2]), - LLVector3(ext[1][0], ext[1][1], ext[0][2]), - LLVector3(ext[0][0], ext[1][1], ext[0][2]), - LLVector3(ext[0][0], ext[0][1], ext[1][2]), - LLVector3(ext[1][0], ext[0][1], ext[1][2]), - LLVector3(ext[1][0], ext[1][1], ext[1][2]), - LLVector3(ext[0][0], ext[1][1], ext[1][2]), - }; - gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[1].mV); - gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[2].mV); - gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[3].mV); - gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[0].mV); - - gGL.vertex3fv(box[4].mV); gGL.vertex3fv(box[5].mV); - gGL.vertex3fv(box[5].mV); gGL.vertex3fv(box[6].mV); - gGL.vertex3fv(box[6].mV); gGL.vertex3fv(box[7].mV); - gGL.vertex3fv(box[7].mV); gGL.vertex3fv(box[4].mV); - - gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[4].mV); - gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[5].mV); - gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[6].mV); - gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[7].mV); - } + gGL.color3fv(c); - gGL.end(); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) - { - LLSpatialPartition* part = region->getSpatialPartition(j); - if (part) + for (U32 k = 0; k < mShadowFrustPoints[i].size(); ++k) { - if (hasRenderType(part->mDrawableType)) + if (j != k) { - part->renderIntersectingBBoxes(&mShadowCamera[i]); + gGL.vertex3fv(mShadowFrustPoints[i][j].mV); + gGL.vertex3fv(mShadowFrustPoints[i][k].mV); } } + + if (!mShadowFrustOrigin[i].isExactlyZero()) + { + gGL.vertex3fv(mShadowFrustPoints[i][j].mV); + gGL.color4f(1,1,1,1); + gGL.vertex3fv(mShadowFrustOrigin[i].mV); + } } + gGL.end(); } } } @@ -3222,6 +3630,55 @@ void LLPipeline::renderDebug() } } + if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) + { + U32 count = 0; + U32 size = mBuildQ2.size(); + LLColor4 col; + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep); + + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + if (group->isDead()) + { + continue; + } + + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + + if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead())) + { + continue; + } + + if (bridge) + { + gGL.pushMatrix(); + glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + } + + F32 alpha = (F32) (size-count)/size; + + + LLVector2 c(1.f-alpha, alpha); + c.normVec(); + + + ++count; + col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f); + group->drawObjectBox(col); + + if (bridge) + { + gGL.popMatrix(); + } + } + } + gGL.flush(); } @@ -4650,7 +5107,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4707,7 +5164,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, //check against avatars sPickAvatar = TRUE; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4784,7 +5241,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co { LLDrawable* drawable = NULL; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4847,7 +5304,7 @@ void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4958,18 +5415,18 @@ void validate_framebuffer_object() break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: // frame buffer not OK: probably means unsupported depth buffer format - llerrs << "Framebuffer Incomplete Dimensions." << llendl; + llwarns << "Framebuffer Incomplete Dimensions." << llendl; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: // frame buffer not OK: probably means unsupported depth buffer format - llerrs << "Framebuffer Incomplete Attachment." << llendl; + llwarns << "Framebuffer Incomplete Attachment." << llendl; break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: /* choose different formats */ - llerrs << "Framebuffer unsupported." << llendl; + llwarns << "Framebuffer unsupported." << llendl; break; default: - llerrs << "Unknown framebuffer status." << llendl; + llwarns << "Unknown framebuffer status." << llendl; break; } } @@ -5287,46 +5744,202 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post) //, U32 noise_map) { +/* if (noise_map == 0xFFFFFFFF) + { + noise_map = mNoiseMap; + } +*/ + LLFastTimer ftm(LLFastTimer::FTM_TEMP3); + LLGLState::checkTextureChannels(); + shader.bind(); S32 channel = 0; channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(0,channel); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) + if (gi_source) { - mDeferredScreen.bindTexture(3, channel); + BOOL has_gi = FALSE; + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(3, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(3, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); + if (channel > -1) + { + has_gi = TRUE; + gGL.getTexUnit(channel)->bind(gi_source, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + stop_glerror(); + + glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); + + stop_glerror(); + } + + if (has_gi) + { + U32 gi_samples = llclamp(gSavedSettings.getU32("RenderGISamples"), (U32) 1, (U32) 8); + + F32 range_x = llmin(mGIRange.mV[0], 1.f); + F32 range_y = llmin(mGIRange.mV[1], 1.f); + + LLVector2 scale(range_x,range_y); + + LLVector2 kern[25]; + + for (S32 i = 0; i < 5; ++i) + { + for (S32 j = 0; j < 5; ++j) + { + S32 idx = i*5+j; + kern[idx].mV[0] = (i-2)*0.5f; + kern[idx].mV[1] = (j-2)*0.5f; + kern[idx].scaleVec(scale); + } + } + + F32 gi_radius = mGILightRadius; //gSavedSettings.getF32("RenderGILightRadius"); + + shader.uniform2f("gi_scale", scale.mV[0], scale.mV[1]); + shader.uniform2fv("gi_kern", 25, (F32*) kern); + shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m); + shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m); + shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m); + shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m); + shader.uniform1f("gi_radius", gi_radius); + shader.uniform1i("gi_samples", (GLint) gSavedSettings.getU32("RenderGISamples")); + shader.uniform1f("gi_intensity", gSavedSettings.getF32("RenderGIIntensity")/(gi_samples*gi_samples)); + shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV); + shader.uniform3fv("gi_spec", 1, gSavedSettings.getVector3("RenderGISpecularCurve").mV); + shader.uniform1f("gi_direction_weight", gSavedSettings.getF32("RenderGIDirectionWeight")); + shader.uniform1f("gi_light_offset", gSavedSettings.getF32("RenderGILightOffset")); + shader.uniform1f("gi_blend", gFrameIntervalSeconds); + } } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { - gGL.getTexUnit(channel)->bind(&mDeferredScreen, TRUE); + gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + stop_glerror(); + + glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); + + stop_glerror(); + + glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f inv_proj = projection.inverse(); + + shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m); + shader.uniform4f("viewport", (F32) gGLViewport[0], + (F32) gGLViewport[1], + (F32) gGLViewport[2], + (F32) gGLViewport[3]); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE); if (channel > -1) { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); // was noise_map KL + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); } stop_glerror(); @@ -5335,19 +5948,68 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) if (channel > -1) { mDeferredLight[light_index].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + gi_source->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mDeferredLight[1].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mDeferredLight[2].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } + stop_glerror(); for (U32 i = 0; i < 4; i++) + { + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); + stop_glerror(); + if (channel > -1) + { + stop_glerror(); + gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + stop_glerror(); + } + } + + for (U32 i = 4; i < 6; i++) { channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i); stop_glerror(); if (channel > -1) { stop_glerror(); - gGL.getTexUnit(channel)->bind(&mSunShadow[i], TRUE); + gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); @@ -5358,17 +6020,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) stop_glerror(); - F32 mat[64]; + F32 mat[16*6]; for (U32 i = 0; i < 16; i++) { mat[i] = mSunShadowMatrix[0].m[i]; mat[i+16] = mSunShadowMatrix[1].m[i]; mat[i+32] = mSunShadowMatrix[2].m[i]; mat[i+48] = mSunShadowMatrix[3].m[i]; + mat[i+64] = mSunShadowMatrix[4].m[i]; + mat[i+80] = mSunShadowMatrix[5].m[i]; } - shader.uniformMatrix4fv("shadow_matrix[0]", 4, FALSE, mat); - shader.uniformMatrix4fv("shadow_matrix", 4, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat); stop_glerror(); @@ -5417,8 +6081,23 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften")); + shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")); + shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")); +/* shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV); + shader.uniform3fv("lum_quad", 1, gSavedSettings.getVector3("RenderLuminanceColorCurve").mV); + shader.uniform3fv("gi_lum_quad", 1, gSavedSettings.getVector3("RenderGILuminanceColorCurve").mV); + shader.uniform3fv("sun_lum_quad", 1, gSavedSettings.getVector3("RenderSunLuminanceColorCurve").mV); + shader.uniform1f("lum_lod", gSavedSettings.getF32("RenderLuminanceDetail")); + shader.uniform1f("gi_range", gSavedSettings.getF32("RenderGIRange")); + + if (shader.getUniformLocation("norm_mat") >= 0) + { + glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); + shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m); + } */ } +// KL The Deffered Pipeline begins here! void LLPipeline::renderDeferredLighting() { if (!sCull) @@ -5426,6 +6105,12 @@ void LLPipeline::renderDeferredLighting() return; } + { + LLGLDepthTest depth(GL_TRUE); + mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), + 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } + LLGLEnable multisample(GL_MULTISAMPLE_ARB); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -5439,16 +6124,10 @@ void LLPipeline::renderDeferredLighting() glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); gGL.setColorMask(true, true); - - mDeferredLight[0].bindTarget(); - - //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); //draw a cube around every light LLVertexBuffer::unbind(); - glBlendFunc(GL_ONE, GL_ONE); LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); @@ -5460,126 +6139,271 @@ void LLPipeline::renderDeferredLighting() -1,-3, 3,1, }; - - bindDeferredShader(gDeferredSunProgram); - - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); - - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); + //Set mSunDir KL This makes sense to have it here. Still calculated EVEN if Deferred Sun is FALSE! { - for (U32 j = 0; j < 8; j++) - { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); - v.normalize(); - inv_trans.mult_matrix_vec(v); - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; - } + setupHWLights(NULL); //to set mSunDir; + LLVector4 dir(mSunDir, 0.f); + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); } - gDeferredSunProgram.uniform3fv("offset", slice, offset); - gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); - - setupHWLights(NULL); //to set mSunDir; - - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + if (gSavedSettings.getBOOL("RenderDeferredShadow")) + { + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); - LLVector4 dir(mSunDir, 0.f); + mDeferredLight[0].bindTarget(); +// KL Bind to 0 next section Deferred Sun ! + if (gSavedSettings.getBOOL("RenderDeferredSun")) + { //paint shadow/SSAO light map (direct lighting lightmap) + bindDeferredShader(gDeferredSunProgram, 0); - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); - glColor3f(1,1,1); + glClearColor(1,1,1,1); + mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); - glVertexPointer(2, GL_FLOAT, 0, vert); + glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + + const U32 slice = 32; + F32 offset[slice*3]; + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 8; j++) + { + glh::vec3f v; + v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); + v.normalize(); + inv_trans.mult_matrix_vec(v); + v.normalize(); + offset[(i*8+j)*3+0] = v.v[0]; + offset[(i*8+j)*3+1] = v.v[2]; + offset[(i*8+j)*3+2] = v.v[1]; + } + } + + gDeferredSunProgram.uniform3fv("offset", slice, offset); + gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + unbindDeferredShader(gDeferredSunProgram); + } + else { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); + mDeferredLight[0].clear(); } - - unbindDeferredShader(gDeferredSunProgram); - mDeferredLight[0].flush(); + mDeferredLight[0].flush(); + mDeferredLight[1].bindTarget(); + } +// KL Bind to 1 next section GI +/* if (gSavedSettings.getBOOL("RenderDeferredGI")) + { + { //get luminance map from previous frame's light map + LLGLEnable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); - //blur lightmap - mDeferredLight[1].bindTarget(); + //static F32 fade = 1.f; - //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - - bindDeferredShader(gDeferredBlurLightProgram); + F32 fade = gSavedSettings.getF32("RenderLuminanceFade"); + { + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gLuminanceGatherProgram.bind(); + gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + gLuminanceGatherProgram.uniform1f("fade", llclamp(fade, 0.f, 1.f)); + mLuminanceMap.bindTarget(); + gGL.getTexUnit(0)->bind(&mDeferredLight[0]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + gLuminanceGatherProgram.unbind(); + mLuminanceMap.flush(); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + glGenerateMipmapEXT(GL_TEXTURE_2D); + } - LLVector3 gauss[32]; // xweight, yweight, offset + } - LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); - U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; - F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + { //paint noisy GI map (bounce lighting lightmap) + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable test(GL_ALPHA_TEST); - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = -(kern_length/2.0f) + 0.5f; + mGIMapPost[0].bindTarget(); - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } - /* swap the x=0 position to the start of gauss[] so we can - treat it specially as an optimization. */ - LLVector3 swap; - swap = gauss[kern_length/2]; - gauss[kern_length/2] = gauss[0]; - gauss[0] = swap; - llassert(gauss[0].mV[2] == 0.0f); + bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0);//, mTrueNoiseMap); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + unbindDeferredShader(gDeferredGIProgram); + mGIMapPost[0].flush(); - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + } - bindDeferredShader(gDeferredBlurLightProgram, 1); - mDeferredLight[0].bindTarget(); + U32 pass_count = 0; + if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) + { + pass_count = llclamp(gSavedSettings.getU32("RenderGIBlurPasses"), (U32) 1, (U32) 128); + } - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + for (U32 i = 0; i < pass_count; ++i) + { //gather/soften indirect lighting map + bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL); //, mTrueNoiseMap); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - stop_glerror(); - } + LLVector2 gauss[32]; // xweight, yweight, offset + + F32 sc = 1.f; + + F32 go = gSavedSettings.getF32("RenderGIGaussian"); + U32 kern_length = llclamp(gSavedSettings.getU32("RenderGIBlurSamples"), (U32) 1, (U32) 16)*2 - 1; + F32 blur_size = gSavedSettings.getF32("RenderGIBlurSize")*sc; + F32 dist_factor = gSavedSettings.getF32("RenderGIBlurDistFactor"); + + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = -(kern_length/2.0f) + 0.5f; + + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go); + gauss[i].mV[1] = x; + x += 1.f; + } + // swap the x=0 position to the start of gauss[] so we can + // treat it specially as an optimization. + LLVector2 swap; + swap = gauss[kern_length/2]; + gauss[kern_length/2] = gauss[0]; + gauss[0] = swap; + llassert(gauss[0].mV[2] == 0.0f); + + gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f); + gDeferredPostGIProgram.uniform1f("dist_factor", dist_factor); + gDeferredPostGIProgram.uniform2fv("kern[0]", kern_length, gauss[0].mV); + gDeferredPostGIProgram.uniform2fv("kern", kern_length, gauss[0].mV); + gDeferredPostGIProgram.uniform1i("kern_length", kern_length); + gDeferredPostGIProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + gDeferredPostGIProgram.uniform3fv("blur_quad", 1, gSavedSettings.getVector3("RenderGIBlurColorCurve").mV); + + mGIMapPost[1].bindTarget(); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mGIMapPost[1].flush(); + unbindDeferredShader(gDeferredPostGIProgram); + + bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL);//, mTrueNoiseMap); + mGIMapPost[0].bindTarget(); + + gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f); + gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); + gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + stop_glerror(); + } + mGIMapPost[0].flush(); + unbindDeferredShader(gDeferredPostGIProgram); + } + } */ + + if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) + { //soften direct lighting lightmap + //blur lightmap + mDeferredLight[1].bindTarget(); + + glClearColor(1,1,1,1); + mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); + + bindDeferredShader(gDeferredBlurLightProgram); + + LLVector3 gauss[32]; // xweight, yweight, offset + + LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); + U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; + F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); + + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = -(kern_length/2.0f) + 0.5f; + + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } + /* swap the x=0 position to the start of gauss[] so we can + treat it specially as an optimization. */ + LLVector3 swap; + swap = gauss[kern_length/2]; + gauss[kern_length/2] = gauss[0]; + gauss[0] = swap; + llassert(gauss[0].mV[2] == 0.0f); + + gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); + gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); + gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mDeferredLight[1].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + + bindDeferredShader(gDeferredBlurLightProgram, 1); + mDeferredLight[0].bindTarget(); + + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); + gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); + gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); // KL 4? + stop_glerror(); + } mDeferredLight[0].flush(); unbindDeferredShader(gDeferredBlurLightProgram); + } stop_glerror(); glPopMatrix(); @@ -5588,15 +6412,26 @@ void LLPipeline::renderDeferredLighting() stop_glerror(); glPopMatrix(); stop_glerror(); +// } //copy depth and stencil from deferred screen //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - mScreen.bindTarget(); - mScreen.clear(GL_COLOR_BUFFER_BIT); - - bindDeferredShader(gDeferredSoftenProgram); +/* if (gSavedSettings.getBOOL("RenderDeferredGI")) + { + mDeferredLight[1].bindTarget(); + mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + } + else + { */ + mScreen.bindTarget(); + mScreen.clear(GL_COLOR_BUFFER_BIT); +// } + + if (gSavedSettings.getBOOL("RenderDeferredAtmospheric")) + { //apply sunlight contribution + bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]); // may not be using GI but still need this KL { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -5619,130 +6454,330 @@ void LLPipeline::renderDeferredLighting() } unbindDeferredShader(gDeferredSoftenProgram); + } +// KL this code is a tad buggered atm it obliterates local lights...... +/* { //render sky/water/hair/skirts + LLGLDisable blend(GL_BLEND); + LLGLDisable stencil(GL_STENCIL_TEST); + gGL.setSceneBlendType(LLRender::BT_ALPHA); - bindDeferredShader(gDeferredLightProgram); - - std::list<LLVector4> fullscreen_lights; - std::list<LLVector4> light_colors; + U32 render_mask = mRenderTypeMask; + mRenderTypeMask = mRenderTypeMask & + ((1 << LLPipeline::RENDER_TYPE_SKY) | + (1 << LLPipeline::RENDER_TYPE_CLOUDS) | + (1 << LLPipeline::RENDER_TYPE_WL_SKY) | + (1 << LLPipeline::RENDER_TYPE_AVATAR) | + (1 << LLPipeline::RENDER_TYPE_WATER)); + + renderGeomPostDeferred(*LLViewerCamera::getInstance()); + mRenderTypeMask = render_mask; + } */ - F32 v[24]; - glVertexPointer(3, GL_FLOAT, 0, v); + BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); + BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights"); + +/* + if (gSavedSettings.getBOOL("RenderDeferredGI")) { - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) + mDeferredLight[1].flush(); + mDeferredLight[2].bindTarget(); + mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT); + } +*/ + if (render_local || render_fullscreen) + { + gGL.setSceneBlendType(LLRender::BT_ADD); + std::list<LLVector4> fullscreen_lights; + LLDrawable::drawable_list_t spot_lights; + LLDrawable::drawable_list_t fullscreen_spot_lights; + + for (U32 i = 0; i < 2; i++) { - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); - if (!volume) + mTargetShadowSpotLight[i] = NULL; + } + + std::list<LLVector4> light_colors; + + F32 v[24]; + glVertexPointer(3, GL_FLOAT, 0, v); + BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); + + { + bindDeferredShader(gDeferredLightProgram); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { - continue; + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + if (!volume) + { + continue; + } + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + if (col.magVecSquared() < 0.001f) + { + continue; + } + + if (s <= 0.001f) + { + continue; + } + + if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + { + continue; + } + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 + v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 + v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 + v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + + v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 + v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 + v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 + v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 + + if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) + { //draw box if camera is outside box + if (render_local) + { + if (volume->getLightTexture()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + spot_lights.push_back(drawablep); + continue; + } + + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); + } + } + else if (render_fullscreen) + { + if (volume->getLightTexture()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + fullscreen_spot_lights.push_back(drawablep); + continue; + } + + fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); + light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); + } } + unbindDeferredShader(gDeferredLightProgram); + } - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; - F32 s = volume->getLightRadius()*1.5f; + if (!spot_lights.empty()) + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + bindDeferredShader(gDeferredSpotLightProgram); - if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) { - continue; - } + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + setupSpotLight(gDeferredSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 + v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 + v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 + v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + + v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 + v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 + v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 + v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - sVisibleLightCount++; - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - - //vertex positions are encoded so the 3 bits of their vertex index - //correspond to their axis facing, with bit position 3,2,1 matching - //axis facing x,y,z, bit set meaning positive facing, bit clear - //meaning negative facing - v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 - v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 - v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 - v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 - - v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 - v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 - v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 - v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - - if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) - { //draw box if camera is outside box glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); - } - else - { - fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); - light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); + GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); } + gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredSpotLightProgram); } - } - unbindDeferredShader(gDeferredLightProgram); + { + bindDeferredShader(gDeferredMultiLightProgram); + + LLGLDepthTest depth(GL_FALSE); - if (!fullscreen_lights.empty()) - { - bindDeferredShader(gDeferredMultiLightProgram); - LLGLDepthTest depth(GL_FALSE); + //full screen blit + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); - //full screen blit - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + U32 count = 0; - U32 count = 0; + const U32 max_count = 8; // KL poss 16? + LLVector4 light[max_count]; + LLVector4 col[max_count]; - LLVector4 light[16]; - LLVector4 col[16]; + glVertexPointer(2, GL_FLOAT, 0, vert); - glVertexPointer(2, GL_FLOAT, 0, vert); + F32 far_z = 0.f; - while (!fullscreen_lights.empty()) - { - light[count] = fullscreen_lights.front(); - fullscreen_lights.pop_front(); - col[count] = light_colors.front(); - light_colors.pop_front(); + while (!fullscreen_lights.empty()) + { + light[count] = fullscreen_lights.front(); + fullscreen_lights.pop_front(); + col[count] = light_colors.front(); + light_colors.pop_front(); - count++; - if (count == 16 || fullscreen_lights.empty()) + far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z); + + count++; + if (count == max_count || fullscreen_lights.empty()) + { + gDeferredMultiLightProgram.uniform1i("light_count", count); + gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); + gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); + gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); + gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); + gDeferredMultiLightProgram.uniform1f("far_z", far_z); + far_z = 0.f; + count = 0; + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + } + } + + unbindDeferredShader(gDeferredMultiLightProgram); + + bindDeferredShader(gDeferredMultiSpotLightProgram); + + gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) { - gDeferredMultiLightProgram.uniform1i("light_count", count); - gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); - gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); - count = 0; + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); } - } - - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - unbindDeferredShader(gDeferredMultiLightProgram); + gDeferredMultiSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredMultiSpotLightProgram); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } } + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.setColorMask(true, true); +/* + if (gSavedSettings.getBOOL("RenderDeferredGI")) + { + mDeferredLight[2].flush(); + mScreen.bindTarget(); + mScreen.clear(GL_COLOR_BUFFER_BIT); + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + { //mix various light maps (local, sun, gi) + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); + + gViewerWindow->setupViewport(); + + bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]); + + gDeferredPostProgram.bind(); + + LLVertexBuffer::unbind(); + + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); - { //render non-deferred geometry + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + unbindDeferredShader(gDeferredPostProgram); + } + } +*/ + { //render non-deferred geometry (alpha, fullbright, glow) KL issues with render pipeline merge needs work.. here LLGLDisable blend(GL_BLEND); LLGLDisable stencil(GL_STENCIL_TEST); - + gGL.setSceneBlendType(LLRender::BT_ALPHA); U32 render_mask = mRenderTypeMask; mRenderTypeMask = mRenderTypeMask & ((1 << LLPipeline::RENDER_TYPE_SKY) | @@ -5754,18 +6789,161 @@ void LLPipeline::renderDeferredLighting() (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | (1 << LLPipeline::RENDER_TYPE_VOLUME) | (1 << LLPipeline::RENDER_TYPE_GLOW) | - (1 << LLPipeline::RENDER_TYPE_BUMP)); + (1 << LLPipeline::RENDER_TYPE_BUMP) | + (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | + (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | + (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) | + (1 << LLPipeline::RENDER_TYPE_PASS_GLOW) | + (1 << LLPipeline::RENDER_TYPE_PASS_GRASS) | + (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | + (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY)); renderGeomPostDeferred(*LLViewerCamera::getInstance()); mRenderTypeMask = render_mask; } - mScreen.flush(); + mScreen.flush(); // We are FLUSHED alright ! end of deferred render YAY! } +void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) +{ + //construct frustum + LLVOVolume* volume = drawablep->getVOVolume(); + LLVector3 params = volume->getSpotLightParams(); + + F32 fov = params.mV[0]; + F32 focus = params.mV[1]; + + LLVector3 pos = drawablep->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); + LLVector3 scale = volume->getScale(); + + //get near clip plane + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; + + LLVector3 np = pos+at_axis; + at_axis.normVec(); + + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + + LLVector3 origin = np - at_axis*dist; + + //matrix from volume space to agent space + LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); + + glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); + glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent; + + glh::matrix4f screen_to_light = light_to_screen.inverse(); + + F32 s = volume->getLightRadius()*1.5f; + F32 near_clip = dist; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = s+dist-scale.mV[VZ]; + + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); + + glh::vec3f p1(0, 0, -(near_clip+0.01f)); + glh::vec3f p2(0, 0, -(near_clip+1.f)); + + glh::vec3f screen_origin(0, 0, 0); + + light_to_screen.mult_matrix_vec(p1); + light_to_screen.mult_matrix_vec(p2); + light_to_screen.mult_matrix_vec(screen_origin); + + glh::vec3f n = p2-p1; + n.normalize(); + + F32 proj_range = far_clip - near_clip; + glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); + screen_to_light = trans * light_proj * screen_to_light; + shader.uniformMatrix4fv("proj_mat", 1, FALSE, screen_to_light.m); + shader.uniform1f("proj_near", near_clip); + shader.uniform3fv("proj_p", 1, p1.v); + shader.uniform3fv("proj_n", 1, n.v); + shader.uniform3fv("proj_origin", 1, screen_origin.v); + shader.uniform1f("proj_range", proj_range); + shader.uniform1f("proj_ambiance", params.mV[2]); + S32 s_idx = -1; + + for (U32 i = 0; i < 2; i++) + { + if (mShadowSpotLight[i] == drawablep) + { + s_idx = i; + } + } + + shader.uniform1i("proj_shadow_idx", s_idx); + + if (s_idx >= 0) + { + shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]); + } + else + { + shader.uniform1f("shadow_fade", 1.f); + } + + { + LLDrawable* potential = drawablep; + //determine if this is a good light for casting shadows + F32 m_pri = volume->getSpotLightPriority(); + + for (U32 i = 0; i < 2; i++) + { + F32 pri = 0.f; + + if (mTargetShadowSpotLight[i].notNull()) + { + pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority(); + } + + if (m_pri > pri) + { + LLDrawable* temp = mTargetShadowSpotLight[i]; + mTargetShadowSpotLight[i] = potential; + potential = temp; + m_pri = pri; + } + } + } + + LLViewerImage* img = volume->getLightTexture(); + + S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + if (channel > -1 && img) + { + gGL.getTexUnit(channel)->bind(img); + + F32 lod_range = logf(img->getWidth())/logf(2.f); + + shader.uniform1f("proj_focus", focus); + shader.uniform1f("proj_lod", lod_range); + shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + } +} + void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { + LLFastTimer ftm(LLFastTimer::FTM_TEMP4); stop_glerror(); shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); @@ -5773,14 +6951,40 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); + shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); + for (U32 i = 0; i < 4; i++) + { + if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) + { + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + } + } + + for (U32 i = 4; i < 6; i++) { if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } } + shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); if (channel > -1) @@ -5794,6 +6998,8 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->activate(); shader.unbind(); + + LLGLState::checkTextureChannels(); } inline float sgn(float a) @@ -5932,15 +7138,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } } - LLSpatialPartition::sFreezeState = TRUE; - LLPipeline::sSkipUpdate = TRUE; + //LLSpatialPartition::sFreezeState = TRUE; + //LLPipeline::sSkipUpdate = TRUE; LLGLUserClipPlane clip_plane(plane, mat, projection); static LLCullResult result; updateCull(camera, result, 1); stateSort(camera, result); renderGeom(camera); - LLSpatialPartition::sFreezeState = FALSE; - LLPipeline::sSkipUpdate = FALSE; + //LLSpatialPartition::sFreezeState = FALSE; + //LLPipeline::sSkipUpdate = FALSE; } } glCullFace(GL_BACK); @@ -6039,7 +7245,6 @@ glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) dirN = dir; dirN.normVec(); - ret.m[ 0] = lftN[0]; ret.m[ 1] = upN[0]; @@ -6087,17 +7292,468 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) ret.m[11] = 0; ret.m[15] = 1; - return ret; -} + return ret; +} + +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, BOOL use_shader) +{ + LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); + + //clip out geometry on the same side of water as the camera + static LLCullResult result; + S32 occlude = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 1; + LLPipeline::sShadowRender = TRUE; + + updateCull(shadow_cam, result); + stateSort(shadow_cam, result); + + U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; + LLGLEnable cull(GL_CULL_FACE); + + //generate shadow map + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(proj.m); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(view.m); + + stop_glerror(); + gGLLastMatrix = NULL; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + glColor4f(1,1,1,1); + + stop_glerror(); + + gGL.setColorMask(false, false); + + if (use_shader) + { + gDeferredShadowProgram.bind(); + } + + //glCullFace(GL_FRONT); + + { + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->disable(); + for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) + { + renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + } + + if (use_shader) + { + gDeferredShadowProgram.unbind(); + renderGeomShadow(shadow_cam); + gDeferredShadowProgram.bind(); + } + else + { + renderGeomShadow(shadow_cam); + } + + { + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); + LLGLEnable test(GL_ALPHA_TEST); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); + renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); + glColor4f(1,1,1,1); + renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + } + + //glCullFace(GL_BACK); + + if (use_shader) + { + gDeferredShadowProgram.unbind(); + } + + gGL.setColorMask(true, true); + + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gGLLastMatrix = NULL; + + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = FALSE; +} + + +BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) +{ + LLFastTimer ftm(LLFastTimer::FTM_TEMP2); + //get point cloud of intersection of frust and min, max + + //get set of planes + std::vector<LLPlane> ps; + + if (getVisibleExtents(camera, min, max)) + { + return FALSE; + } + + ps.push_back(LLPlane(min, LLVector3(-1,0,0))); + ps.push_back(LLPlane(min, LLVector3(0,-1,0))); + ps.push_back(LLPlane(min, LLVector3(0,0,-1))); + ps.push_back(LLPlane(max, LLVector3(1,0,0))); + ps.push_back(LLPlane(max, LLVector3(0,1,0))); + ps.push_back(LLPlane(max, LLVector3(0,0,1))); + + if (!light_dir.isExactlyZero()) + { + LLPlane ucp; + LLPlane mcp; + + F32 maxd = -1.f; + F32 mind = 1.f; + + for (U32 i = 0; i < ps.size(); ++i) + { //pick the plane most aligned to lightDir for user clip plane + LLVector3 n(ps[i].mV); + F32 da = n*light_dir; + if (da > maxd) + { + maxd = da; + ucp = ps[i]; + } + + if (da < mind) + { + mind = da; + mcp = ps[i]; + } + } + + camera.setUserClipPlane(ucp); + + ps.clear(); + ps.push_back(ucp); + ps.push_back(mcp); + } + + for (U32 i = 0; i < 6; i++) + { + ps.push_back(camera.getAgentPlane(i)); + } + + //get set of points where planes intersect and points are not above any plane + fp.clear(); + + for (U32 i = 0; i < ps.size(); ++i) + { + for (U32 j = 0; j < ps.size(); ++j) + { + for (U32 k = 0; k < ps.size(); ++k) + { + if (i == j || + i == k || + k == j) + { + continue; + } + + LLVector3 n1,n2,n3; + F32 d1,d2,d3; + + n1.setVec(ps[i].mV); + n2.setVec(ps[j].mV); + n3.setVec(ps[k].mV); + + d1 = ps[i].mV[3]; + d2 = ps[j].mV[3]; + d3 = ps[k].mV[3]; + + //get point of intersection of 3 planes "p" + LLVector3 p = (-d1*(n2%n3)-d2*(n3%n1)-d3*(n1%n2))/(n1*(n2%n3)); + + if (llround(p*n1+d1, 0.0001f) == 0.f && + llround(p*n2+d2, 0.0001f) == 0.f && + llround(p*n3+d3, 0.0001f) == 0.f) + { //point is on all three planes + BOOL found = TRUE; + for (U32 l = 0; l < ps.size() && found; ++l) + { + if (llround(ps[l].dist(p), 0.0001f) > 0.0f) + { //point is above some plane, not contained + found = FALSE; + } + } + + if (found) + { + fp.push_back(p); + } + } + } + } + } + + if (fp.empty()) + { + return FALSE; + } + + return TRUE; +} + +void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc) +{ +/* if (!gSavedSettings.getBOOL("RenderDeferredGI")) + { + return; + } */ + + LLVector3 up; + + if (lightDir.mV[2] > 0.5f) + { + up = LLVector3(1,0,0); + } + else + { + up = LLVector3(0, 0, 1); + } + + + F32 lrad = gSavedSettings.getF32("RenderGILightRadius"); + + F32 samples = (F32) gSavedSettings.getU32("RenderGISamples"); + + F32 gi_range = gSavedSettings.getF32("RenderGIRange"); + + U32 res = 1024; + + lrad = samples*gi_range/(res-samples)*0.5f; + + F32 lrange = lrad+gi_range*0.5f; + + LLVector3 pad(lrange,lrange,lrange); + + glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up); + + LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f); + + glh::vec3f scp(cp.mV); + view.mult_matrix_vec(scp); + cp.setVec(scp.v); + + F32 pix_width = lrange/(res*0.5f); + + //lrad = llround(lrad, pix_width); + + //move cp to the nearest pix_width + for (U32 i = 0; i < 3; i++) + { + cp.mV[i] = llround(cp.mV[i], pix_width); + } + + LLVector3 min = cp-pad; + LLVector3 max = cp+pad; + + //set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point + mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res; + mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res; + mGILightRadius = lrad; + + glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + + LLCamera sun_cam = camera; + + glh::matrix4f eye_view = glh_get_current_modelview(); + + //get eye space to camera space matrix + mGIMatrix = view*eye_view.inverse(); + mGINormalMatrix = mGIMatrix.inverse().transpose(); + mGIInvProj = proj.inverse(); + mGIMatrixProj = proj*mGIMatrix; + + //translate and scale to [0,1] + glh::matrix4f trans(.5f, 0.f, 0.f, .5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); + + mGIMatrixProj = trans*mGIMatrixProj; + + glh_set_current_modelview(view); + glh_set_current_projection(proj); + + LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE); + + sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + static LLCullResult result; + + U32 type_mask = mRenderTypeMask; + + mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | + (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | + (1<<LLPipeline::RENDER_TYPE_BUMP) | + (1<<LLPipeline::RENDER_TYPE_VOLUME) | + (1<<LLPipeline::RENDER_TYPE_TREE) | + (1<<LLPipeline::RENDER_TYPE_TERRAIN) | + (1<<LLPipeline::RENDER_TYPE_WATER) | + (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | + (1<<LLPipeline::RENDER_TYPE_AVATAR) | + (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | + (1 << LLPipeline::RENDER_TYPE_PASS_SHINY)); + + + + S32 occlude = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; + LLPipeline::sShadowRender = TRUE; + + updateCull(sun_cam, result); + stateSort(sun_cam, result); + + LLGLEnable cull(GL_CULL_FACE); + + //generate GI map + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(proj.m); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(view.m); + + stop_glerror(); + gGLLastMatrix = NULL; + + mGIMap.clear(); + + { + LLGLEnable enable(GL_DEPTH_CLAMP_NV); + renderGeomDeferred(camera); + } + + mGIMap.flush(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gGLLastMatrix = NULL; + + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = FALSE; + + + mRenderTypeMask = type_mask; + +} + +void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) +{ + if (!gSavedSettings.getBOOL("renderhighlights")) // KL need this to make the mouseover Highlights toggle ^^ + { + return; + } + + if (obj && obj->getVolume()) + { + for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter) + { + renderHighlight(*iter, fade); + } + + LLDrawable* drawable = obj->mDrawable; + if (drawable) + { + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + if (face) + { + face->renderSelected(LLViewerImage::sNullImagep, LLColor4(1,1,1,fade)); + } + } + } + } +} + +void LLPipeline::generateHighlight(LLCamera& camera) +{ + if (!gSavedSettings.getBOOL("renderhighlights")) // KL need this to make the mouseover Highlights toggle ^^ + { + return; + } + //render highlighted object as white into offscreen render target + + if (mHighlightObject.notNull()) + { + mHighlightSet.insert(HighlightItem(mHighlightObject)); + } + + if (!mHighlightSet.empty()) + { + F32 transition = gFrameIntervalSeconds/gSavedSettings.getF32("RenderHighlightFadeTime"); + + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + mHighlight.bindTarget(); + disableLights(); + gGL.setColorMask(true, true); + mHighlight.clear(); + + gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep); + for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ) + { + std::set<HighlightItem>::iterator cur_iter = iter++; + + if (cur_iter->mItem.isNull()) + { + mHighlightSet.erase(cur_iter); + continue; + } + + if (cur_iter->mItem == mHighlightObject) + { + cur_iter->incrFade(transition); + } + else + { + cur_iter->incrFade(-transition); + if (cur_iter->mFade <= 0.f) + { + mHighlightSet.erase(cur_iter); + continue; + } + } + + renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade); + } + + mHighlight.flush(); + gGL.setColorMask(true, false); + gViewerWindow->setupViewport(); + } +} + void LLPipeline::generateSunShadow(LLCamera& camera) { - if (!sRenderDeferred) { return; } + LLFastTimer ftm(LLFastTimer::FTM_TEMP1); + //temporary hack to disable shadows but keep local lights static BOOL clear = TRUE; BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); @@ -6106,98 +7762,162 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (clear) { clear = FALSE; - for (U32 i = 0; i < 4; i++) + for (U32 i = 0; i < 6; i++) { - mSunShadow[i].bindTarget(); - mSunShadow[i].clear(); - mSunShadow[i].flush(); + mShadow[i].bindTarget(); + mShadow[i].clear(); + mShadow[i].flush(); } } return; } clear = TRUE; + U32 type_mask = mRenderTypeMask; + mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | + (1<<LLPipeline::RENDER_TYPE_ALPHA) | + (1<<LLPipeline::RENDER_TYPE_GRASS) | + (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | + (1<<LLPipeline::RENDER_TYPE_BUMP) | + (1<<LLPipeline::RENDER_TYPE_VOLUME) | + (1<<LLPipeline::RENDER_TYPE_AVATAR) | + (1<<LLPipeline::RENDER_TYPE_TREE) | + (1<<LLPipeline::RENDER_TYPE_TERRAIN) | + (1<<LLPipeline::RENDER_TYPE_WATER) | + (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | + (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | + (1 << LLPipeline::RENDER_TYPE_PASS_SHINY)); + gGL.setColorMask(false, false); //get sun view matrix - F32 range = 128.f; - //store current projection/modelview matrix glh::matrix4f saved_proj = glh_get_current_projection(); glh::matrix4f saved_view = glh_get_current_modelview(); glh::matrix4f inv_view = saved_view.inverse(); - glh::matrix4f view[4]; - glh::matrix4f proj[4]; - LLVector3 up; - + glh::matrix4f view[6]; + glh::matrix4f proj[6]; + //clip contains parallel split distances for 3 splits LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes"); + //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold"); + //far clip on last split is minimum of camera view distance and 128 mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); - const LLPickInfo& pick_info = gViewerWindow->getLastPick(); - - if (!pick_info.mPosGlobal.isExactlyZero()) - { //squish nearest frustum based on alt-zoom (tighten up nearest frustum when focusing on tiny object - F32 focus_dist = (F32) (pick_info.mPosGlobal + LLVector3d(pick_info.mObjectOffset) - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec(); - mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]); - } - - // convenience array of 4 near clip plane distances - F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; + clip = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); + mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); //currently used for amount to extrude frusta corners for constructing shadow frusta LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); - F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; - for (S32 j = 0; j < 4; j++) - { - //restore render matrices - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + LLVector3 lightDir = -mSunDir; + lightDir.normVec(); - //get center of far clip plane (for point of interest later) - LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range; + glh::vec3f light_dir(lightDir.mV); - LLVector3 eye = camera.getOrigin(); + //create light space camera matrix + + LLVector3 at = lightDir; - //camera used for shadow cull/render - LLCamera shadow_cam; - - // perspective shadow map - glh::vec3f p[16]; //point cloud to be contained by shadow projection (light camera space) - glh::vec3f wp[16]; //point cloud to be contained by shadow projection (world space) - - LLVector3 lightDir = -mSunDir; - glh::vec3f light_dir(lightDir.mV); + LLVector3 up = camera.getAtAxis(); + + if (fabsf(up*lightDir) > 0.75f) + { + up = camera.getUpAxis(); + } - //create light space camera matrix - LLVector3 at; - F32 dl = camera.getLeftAxis() * lightDir; - F32 du = camera.getUpAxis() * lightDir; + /*LLVector3 left = up%at; + up = at%left;*/ - //choose an at axis such that up will be most aligned with lightDir - if (dl*dl < du*du) + up.normVec(); + at.normVec(); + + + F32 near_clip = 0.f; + { + //get visible point cloud + std::vector<LLVector3> fp; + + LLVector3 min,max; + getVisiblePointCloud(camera,min,max,fp); + + if (fp.empty()) { - at = lightDir%camera.getLeftAxis(); + mRenderTypeMask = type_mask; + return; } - else + + generateGI(camera, lightDir, fp); + + //get good split distances for frustum + for (U32 i = 0; i < fp.size(); ++i) { - at = lightDir%camera.getUpAxis(); + glh::vec3f v(fp[i].mV); + saved_view.mult_matrix_vec(v); + fp[i].setVec(v.v); } - if (at * camera.getAtAxis() < 0) + min = fp[0]; + max = fp[0]; + + //get camera space bounding box + for (U32 i = 1; i < fp.size(); ++i) { - at = -at; + update_min_max(min, max, fp[i]); } + + near_clip = -max.mV[2]; + F32 far_clip = -min.mV[2]*2.f; + + far_clip = llmin(far_clip, 128.f); + far_clip = llmin(far_clip, camera.getFar()); + + F32 range = far_clip-near_clip; + + LLVector3 split_exp = gSavedSettings.getVector3("RenderShadowSplitExponent"); + + F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); - LLVector3 left = lightDir%at; - up = left%lightDir; - up.normVec(); + da = powf(da, split_exp.mV[2]); + + + F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; + + + for (U32 i = 0; i < 4; ++i) + { + F32 x = (F32)(i+1)/4.f; + x = powf(x, sxp); + mSunClipPlanes.mV[i] = near_clip+range*x; + } + } + + // convenience array of 4 near clip plane distances + F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; + + for (S32 j = 0; j < 4; j++) + { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustPoints[j].clear(); + } + + //restore render matrices + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); + + LLVector3 eye = camera.getOrigin(); + //camera used for shadow cull/render + LLCamera shadow_cam; + //create world space camera frustum for this split shadow_cam = camera; shadow_cam.setFar(16.f); @@ -6208,8 +7928,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 pn = shadow_cam.getAtAxis(); - LLVector3 frust_center; - LLVector3 min, max; //construct 8 corners of split frustum section @@ -6220,21 +7938,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera) F32 dp = delta*pn; frust[i] = eye + (delta*dist[j])/dp; frust[i+4] = eye + (delta*dist[j+1])/dp; - frust_center += frust[i] + frust[i+4]; } - - //get frustum center - frust_center /= 8.f; shadow_cam.calcAgentFrustumPlanes(frust); - + shadow_cam.mFrustumCornerDist = 0.f; if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { mShadowCamera[j] = shadow_cam; } - if (gPipeline.getVisibleExtents(shadow_cam, min, max)) + std::vector<LLVector3> fp; + + if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) { //no possible shadow receivers if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) @@ -6244,6 +7960,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowCamera[j+4] = shadow_cam; } + mShadow[j].bindTarget(); + { + LLGLDepthTest depth(GL_TRUE); + mShadow[j].clear(); + } + mShadow[j].flush(); + + mShadowError.mV[j] = 0.f; + mShadowFOV.mV[j] = 0.f; + continue; } @@ -6251,42 +7977,252 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { mShadowExtents[j][0] = min; mShadowExtents[j][1] = max; + mShadowFrustPoints[j] = fp; } - view[j] = look(frust_center-lightDir*nearDist[j], lightDir, up); - F32 shadow_dist = nearDist[j]; - for (U32 i = 0; i < 8; i++) + //find a good origin for shadow projection + LLVector3 origin; + + //get a temporary view projection + view[j] = look(camera.getOrigin(), lightDir, -up); + + std::vector<LLVector3> wpf; + + for (U32 i = 0; i < fp.size(); i++) { - //points in worldspace (wp) and light camera space (p) - //that must be included in shadow generation - wp[i] = glh::vec3f(frust[i].mV); - wp[i+8] = wp[i] - light_dir*shadow_dist; - view[j].mult_matrix_vec(wp[i], p[i]); - view[j].mult_matrix_vec(wp[i+8], p[i+8]); + glh::vec3f p = glh::vec3f(fp[i].mV); + view[j].mult_matrix_vec(p); + wpf.push_back(LLVector3(p.v)); } - - min = LLVector3(p[0].v); - max = LLVector3(p[0].v); - LLVector3 fmin = min; - LLVector3 fmax = max; + min = wpf[0]; + max = wpf[0]; - for (U32 i = 1; i < 16; i++) - { //find camera space AABB of frustum in light camera space - update_min_max(min, max, LLVector3(p[i].v)); - if (i < 8) - { - update_min_max(fmin, fmax, LLVector3(p[i].v)); + for (U32 i = 0; i < fp.size(); ++i) + { //get AABB in camera space + update_min_max(min, max, wpf[i]); + } + + // Construct a perspective transform with perspective along y-axis that contains + // points in wpf + //Known: + // - far clip plane + // - near clip plane + // - points in frustum + //Find: + // - origin + + //get some "interesting" points of reference + LLVector3 center = (min+max)*0.5f; + LLVector3 size = (max-min)*0.5f; + LLVector3 near_center = center; + near_center.mV[1] += size.mV[1]*2.f; + + + //put all points in wpf in quadrant 0, reletive to center of min/max + //get the best fit line using least squares + F32 bfm = 0.f; + F32 bfb = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + wpf[i] -= center; + wpf[i].mV[0] = fabsf(wpf[i].mV[0]); + wpf[i].mV[2] = fabsf(wpf[i].mV[2]); + } + + if (!wpf.empty()) + { + F32 sx = 0.f; + F32 sx2 = 0.f; + F32 sy = 0.f; + F32 sxy = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + sx += wpf[i].mV[0]; + sx2 += wpf[i].mV[0]*wpf[i].mV[0]; + sy += wpf[i].mV[1]; + sxy += wpf[i].mV[0]*wpf[i].mV[1]; } + + bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); + bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); } + + { + // best fit line is y=bfm*x+bfb + + //find point that is furthest to the right of line + F32 off_x = -1.f; + LLVector3 lp; + + for (U32 i = 0; i < wpf.size(); ++i) + { + //y = bfm*x+bfb + //x = (y-bfb)/bfm + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + + lx = wpf[i].mV[0]-lx; + + if (off_x < lx) + { + off_x = lx; + lp = wpf[i]; + } + } + + //get line with slope bfm through lp + // bfb = y-bfm*x + bfb = lp.mV[1]-bfm*lp.mV[0]; + + //calculate error + mShadowError.mV[j] = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); + } + + mShadowError.mV[j] /= wpf.size(); + mShadowError.mV[j] /= size.mV[0]; + + if (mShadowError.mV[j] > gSavedSettings.getF32("RenderShadowErrorCutoff")) + { //just use ortho projection + mShadowFOV.mV[j] = -1.f; + origin.clearVec(); + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //origin is where line x = 0; + origin.setVec(0,bfb,0); + + F32 fovz = 1.f; + F32 fovx = 1.f; + + LLVector3 zp; + LLVector3 xp; + + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + if (fovz > -atz.mV[1]) + { + zp = wpf[i]; + fovz = -atz.mV[1]; + } + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + if (fovx > -atx.mV[1]) + { + fovx = -atx.mV[1]; + xp = wpf[i]; + } + } + + fovx = acos(fovx); + fovz = acos(fovz); + + F32 cutoff = llmin(gSavedSettings.getF32("RenderShadowFOVCutoff"), 1.4f); + + mShadowFOV.mV[j] = fovx; + + if (fovx < cutoff && fovz > cutoff) + { + //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff + F32 d = zp.mV[2]/tan(cutoff); + F32 ny = zp.mV[1] + fabsf(d); + + origin.mV[1] = ny; + + fovz = 1.f; + fovx = 1.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + fovz = llmin(fovz, -atz.mV[1]); + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + fovx = llmin(fovx, -atx.mV[1]); + } - //generate perspective matrix that contains frustum - //proj[j] = matrix_perspective(min, max); - proj[j] = gl_ortho(min.mV[0], max.mV[0], + fovx = acos(fovx); + fovz = acos(fovz); + + if (fovx > cutoff || llround(fovz, 0.01f) > cutoff) + { + // llwarns << "WTF?" << llendl; + } + + mShadowFOV.mV[j] = cutoff; + } + + + origin += center; + + F32 ynear = -(max.mV[1]-origin.mV[1]); + F32 yfar = -(min.mV[1]-origin.mV[1]); + + if (ynear < 0.1f) //keep a sensible near clip plane + { + F32 diff = 0.1f-ynear; + origin.mV[1] += diff; + ynear += diff; + yfar += diff; + } + + if (fovx > cutoff) + { //just use ortho projection + origin.clearVec(); + mShadowError.mV[j] = -1.f; + proj[j] = gl_ortho(min.mV[0], max.mV[0], min.mV[1], max.mV[1], -max.mV[2], -min.mV[2]); - + } + else + { + //get perspective projection + view[j] = view[j].inverse(); + + glh::vec3f origin_agent(origin.mV); + + //translate view to origin + view[j].mult_matrix_vec(origin_agent); + + eye = LLVector3(origin_agent.v); + + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustOrigin[j] = eye; + } + + view[j] = look(LLVector3(origin_agent.v), lightDir, -up); + + F32 fx = 1.f/tanf(fovx); + F32 fz = 1.f/tanf(fovz); + + proj[j] = glh::matrix4f(-fx, 0, 0, 0, + 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), + 0, 0, -fz, 0, + 0, -1.f, 0, 0); + } + } + } + shadow_cam.setFar(128.f); shadow_cam.setOriginAndLookAt(eye, up, center); @@ -6295,9 +8231,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - proj[j] = gl_ortho(fmin.mV[0], fmax.mV[0], - fmin.mV[1], fmax.mV[1], - -fmax.mV[2], -fmin.mV[2]); + shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); //translate and scale to from [-1, 1] to [0, 1] glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, @@ -6310,111 +8244,155 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; - U32 type_mask = mRenderTypeMask; - mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | - (1<<LLPipeline::RENDER_TYPE_ALPHA) | - (1<<LLPipeline::RENDER_TYPE_GRASS) | - (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1<<LLPipeline::RENDER_TYPE_BUMP) | - (1<<LLPipeline::RENDER_TYPE_VOLUME) | - (1<<LLPipeline::RENDER_TYPE_AVATAR) | - (1<<LLPipeline::RENDER_TYPE_TREE) | - (1<<LLPipeline::RENDER_TYPE_TERRAIN) | - 0); - - //clip out geometry on the same side of water as the camera - static LLCullResult result; - S32 occlude = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 1; - LLPipeline::sShadowRender = TRUE; //hack to prevent LOD updates from using sun camera origin shadow_cam.setOrigin(camera.getOrigin()); - updateCull(shadow_cam, result); - stateSort(shadow_cam, result); - - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - mShadowCamera[j+4] = shadow_cam; - } - - LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); stop_glerror(); - mSunShadow[j].bindTarget(); - mSunShadow[j].getViewport(gGLViewport); + mShadow[j].bindTarget(); + mShadow[j].getViewport(gGLViewport); { LLGLDepthTest depth(GL_TRUE); - mSunShadow[j].clear(); + mShadow[j].clear(); } - U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; - LLGLEnable cull(GL_CULL_FACE); + { + LLGLEnable enable(GL_DEPTH_CLAMP_NV); + renderShadow(view[j], proj[j], shadow_cam, FALSE); + } - //generate sun shadow map - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(proj[j].m); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(view[j].m); + mShadow[j].flush(); + + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + mShadowCamera[j+4] = shadow_cam; + } + } - stop_glerror(); - gGLLastMatrix = NULL; + //llinfos << "Shadow error: " << error << " Slope: " << best_fit_slope << llendl; + - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - glColor4f(1,1,1,1); - - glCullFace(GL_FRONT); + F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); - stop_glerror(); + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); + } + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); + + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + } + } + } + } - gGL.setColorMask(false, false); + for (S32 i = 0; i < 2; i++) + { + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); - gDeferredShadowProgram.bind(); + if (mShadowSpotLight[i].isNull()) { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->disable(); - for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) - { - renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); - } - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + continue; } - + + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + + if (!volume) { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); - LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); - renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); - glColor4f(1,1,1,1); - renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + mShadowSpotLight[i] = NULL; + continue; } + + LLDrawable* drawable = mShadowSpotLight[i]; + + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; + + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); + + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; + + LLVector3 np = center+at_axis; + at_axis.normVec(); + + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + + LLVector3 origin = np - at_axis*dist; + + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + + view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + + view[i+4] = view[i+4].inverse(); + + //get perspective matrix + F32 near_clip = dist+0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist+volume->getLightRadius()*1.5f; + + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; - gDeferredShadowProgram.unbind(); + proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - renderGeomShadow(shadow_cam); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - gGL.setColorMask(true, true); + glh_set_current_modelview(view[i+4]); + glh_set_current_projection(proj[i+4]); - glCullFace(GL_BACK); - LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = FALSE; - mRenderTypeMask = type_mask; + mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gGLLastMatrix = NULL; + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); - mSunShadow[j].flush(); - } + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + + shadow_cam.setOrigin(camera.getOrigin()); + + stop_glerror(); + + mShadow[i+4].bindTarget(); + mShadow[i+4].getViewport(gGLViewport); + + { + LLGLDepthTest depth(GL_TRUE); + mShadow[i+4].clear(); + } + + renderShadow(view[i+4], proj[i+4], shadow_cam, FALSE); + + mShadow[i+4].flush(); + } if (!gSavedSettings.getBOOL("CameraOffset")) { @@ -6431,6 +8409,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glMatrixMode(GL_MODELVIEW); } gGL.setColorMask(true, false); + + mRenderTypeMask = type_mask; } void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) @@ -6470,7 +8450,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (muted) { - mask = 1 << LLPipeline::RENDER_TYPE_AVATAR; + mask = 1 << LLPipeline::RENDER_TYPE_INVISIBLE; // Peachy ;) } else { @@ -6481,7 +8461,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) (1<<LLPipeline::RENDER_TYPE_SIMPLE) | (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | (1<<LLPipeline::RENDER_TYPE_ALPHA) | - (1<<LLPipeline::RENDER_TYPE_INVISIBLE); + (1<<LLPipeline::RENDER_TYPE_INVISIBLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | + (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) | + (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | + (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); } mask = mask & gPipeline.getRenderTypeMask(); @@ -6491,6 +8480,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) S32 occlusion = sUseOcclusion; sUseOcclusion = 0; sReflectionRender = sRenderDeferred ? FALSE : TRUE; + sShadowRender = TRUE; sImpostorRender = TRUE; markVisible(avatar->mDrawable, *LLViewerCamera::getInstance()); @@ -6570,7 +8560,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (LLPipeline::sRenderDeferred) { avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE); - addDeferredAttachments(avatar->mImpostor); + //addDeferredAttachments(avatar->mImpostor); } else { @@ -6649,6 +8639,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sUseOcclusion = occlusion; sReflectionRender = FALSE; sImpostorRender = FALSE; + sShadowRender = FALSE; gPipeline.mRenderTypeMask = saved_mask; glMatrixMode(GL_PROJECTION); diff --git a/linden/indra/newview/pipeline.h b/linden/indra/newview/pipeline.h index 1a32b3083..a85877d1c 100644 --- a/linden/indra/newview/pipeline.h +++ b/linden/indra/newview/pipeline.h @@ -129,6 +129,8 @@ class LLPipeline void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE); void markShift(LLDrawable *drawablep); void markTextured(LLDrawable *drawablep); + void markGLRebuild(LLGLUpdate* glu); + void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); //get the object between start and end that's closest to start. @@ -179,10 +181,14 @@ class LLPipeline void updateMove(); BOOL visibleObjectsInFrustum(LLCamera& camera); BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); + BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0)); void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void updateGeom(F32 max_dtime); + void updateGL(); + void rebuildPriorityGroups(); + void rebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -203,12 +209,21 @@ class LLPipeline void renderGeomDeferred(LLCamera& camera); void renderGeomPostDeferred(LLCamera& camera); void renderGeomShadow(LLCamera& camera); - void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0); + void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, LLRenderTarget* gi_source = NULL, LLRenderTarget* last_gi_post = NULL); + void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep); + void unbindDeferredShader(LLGLSLShader& shader); void renderDeferredLighting(); void generateWaterReflection(LLCamera& camera); void generateSunShadow(LLCamera& camera); + void generateHighlight(LLCamera& camera); + void renderHighlight(const LLViewerObject* obj, F32 fade); + void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } + + + void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, BOOL use_shader = TRUE); + void generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc); // KL sd void renderHighlights(); void renderDebug(); @@ -303,27 +318,39 @@ class LLPipeline enum LLRenderTypeMask { // Following are pool types (some are also object types) - RENDER_TYPE_SKY = LLDrawPool::POOL_SKY, - RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY, - RENDER_TYPE_GROUND = LLDrawPool::POOL_GROUND, - RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN, - RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE, - RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS, - RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT, - RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP, - RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, - RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, - RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE, - RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, - RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, - RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, - + RENDER_TYPE_SKY = LLDrawPool::POOL_SKY, + RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY, + RENDER_TYPE_GROUND = LLDrawPool::POOL_GROUND, + RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN, + RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE, + RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS, + RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT, + RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP, + RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, + RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, + RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE, + RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, + RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, + RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, + RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE, + RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, + RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, + RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, + RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, + RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY, + RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY, + RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP, + RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW, + RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA, + RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK, + RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, + RENDER_TYPE_PASS_ALPHA_SHADOW = LLRenderPass::PASS_ALPHA_SHADOW, // Following are object types (only used in drawable mRenderType) - RENDER_TYPE_HUD = LLDrawPool::NUM_POOL_TYPES, + RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES, RENDER_TYPE_VOLUME, RENDER_TYPE_PARTICLES, RENDER_TYPE_CLOUDS, - RENDER_TYPE_HUD_PARTICLES + RENDER_TYPE_HUD_PARTICLES // KL S19? }; enum LLRenderDebugFeatureMask @@ -361,8 +388,7 @@ class LLPipeline RENDER_DEBUG_SHAME = 0x0020000, RENDER_DEBUG_SHADOW_FRUSTA = 0x0040000, RENDER_DEBUG_SCULPTED = 0x0080000, - RENDER_DEBUG_AVATAR_VOLUME = 0x0100000, - RENDER_DEBUG_AGENT_TARGET = 0x0200000, + RENDER_DEBUG_BUILD_QUEUE = 0x0100000, }; public: @@ -421,15 +447,36 @@ class LLPipeline //screen texture LLRenderTarget mScreen; LLRenderTarget mDeferredScreen; - LLRenderTarget mDeferredLight[2]; + LLRenderTarget mDeferredDepth; + LLRenderTarget mDeferredLight[3]; LLMultisampleBuffer mSampleBuffer; + LLRenderTarget mGIMap; + LLRenderTarget mGIMapPost[2]; + LLRenderTarget mLuminanceMap; + LLRenderTarget mHighlight; //sun shadow map - LLRenderTarget mSunShadow[4]; + LLRenderTarget mShadow[6]; + std::vector<LLVector3> mShadowFrustPoints[4]; + LLVector4 mShadowError; + LLVector4 mShadowFOV; + LLVector3 mShadowFrustOrigin[4]; LLCamera mShadowCamera[8]; LLVector3 mShadowExtents[4][2]; - glh::matrix4f mSunShadowMatrix[4]; + glh::matrix4f mSunShadowMatrix[6]; + glh::matrix4f mGIMatrix; + glh::matrix4f mGIMatrixProj; + glh::matrix4f mGINormalMatrix; + glh::matrix4f mGIInvProj; + LLVector2 mGIRange; + F32 mGILightRadius; + + LLPointer<LLDrawable> mShadowSpotLight[2]; + F32 mSpotLightFade[2]; + LLPointer<LLDrawable> mTargetShadowSpotLight[2]; + LLVector4 mSunClipPlanes; + LLVector4 mSunOrthoClipPlanes; LLVector2 mScreenScale; @@ -444,6 +491,8 @@ class LLPipeline //noise map U32 mNoiseMap; + U32 mTrueNoiseMap; + U32 mLightFunc; LLColor4 mSunDiffuse; LLVector3 mSunDir; @@ -504,12 +553,45 @@ class LLPipeline // LLDrawable::drawable_list_t mBuildQ1; // priority LLDrawable::drawable_list_t mBuildQ2; // non-priority + LLSpatialGroup::sg_list_t mGroupQ1; //priority + LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + LLViewerObject::vobj_list_t mCreateQ; LLDrawable::drawable_set_t mActiveQ; LLDrawable::drawable_set_t mRetexturedList; + class HighlightItem + { + public: + const LLPointer<LLDrawable> mItem; + mutable F32 mFade; + + HighlightItem(LLDrawable* item) + : mItem(item), mFade(0) + { + } + + bool operator<(const HighlightItem& rhs) const + { + return mItem < rhs.mItem; + } + + bool operator==(const HighlightItem& rhs) const + { + return mItem == rhs.mItem; + } + + void incrFade(F32 val) const + { + mFade = llclamp(mFade+val, 0.f, 1.f); + } + }; + + std::set<HighlightItem> mHighlightSet; + LLPointer<LLDrawable> mHighlightObject; + ////////////////////////////////////////////////// // // Draw pools are responsible for storing all rendered data, diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml b/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml index 24a895bff..e85eaa8ff 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml @@ -64,7 +64,35 @@ tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled." width="315" /> - <slider bottom_delta="-21" can_edit_text="false" control_name="TextureMemory" + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="12" + left="10" mouse_opaque="true" name="Enable FBO:" v_pad="0" + width="128"> + Enable FBO: + </text> + <check_box bottom_delta="-5" control_name="RenderUseFBO" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="true" + label="Enable OpenGL Framebuffer Objects" left="148" + mouse_opaque="true" name="fbo" radio_style="false" + tool_tip="Enabling this will use OpenGL Framebuffer objects for some dynamic textures. Prerequisite for deferred rendering." + width="315" /> + + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="12" + left="10" mouse_opaque="true" name="Deferred Rendering:" v_pad="0" + width="128"> + Deferred Rendering: + </text> + <check_box bottom_delta="-5" control_name="RenderDeferred" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="true" + label="Enable per-pixel lighting and shadows" left="148" + mouse_opaque="true" name="deferred" radio_style="false" + tool_tip="Enabling this will perform lighting calculations in screen space, enabling per pixel lighting for all lights and shadows from the sun/moon. Requires a fast graphics card. Might not be compatible with FSAA." + width="315" /> + + <slider bottom_delta="-21" can_edit_text="false" control_name="TextureMemory" decimal_digits="0" enabled="true" follows="left|top" height="16" increment="16" initial_val="32" label="Texture Memory (MB):" label_width="135" left="10" diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index 0cb4a592a..1be2e58ff 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -1036,25 +1036,47 @@ <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom_delta="-21" drop_shadow_visible="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left_delta="0" - mouse_opaque="true" name="label color" v_pad="0" width="58"> + mouse_opaque="true" name="label color" v_pad="0" width="57"> Color: </text> <color_swatch border_color="0.45098, 0.517647, 0.607843, 1" bottom_delta="-28" can_apply_immediately="true" color="0.5, 0.5, 0.5, 1" follows="left|top" - height="48" label="" left_delta="67" mouse_opaque="true" name="colorswatch" + height="48" label="" left_delta="57" mouse_opaque="true" name="colorswatch" tool_tip="Click to open Color Picker" width="32" /> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="28" drop_shadow_visible="true" follows="left|top" + font="SansSerifSmall" h_pad="0" height="10" left="144" + mouse_opaque="true" name="label texture" v_pad="0" width="58"> + Texture + </text> + <texture_picker allow_no_texture="true" bottom_delta="-28" can_apply_immediately="true" + default_image_name="Default" follows="left|top" height="48" label="" + left_delta="57" mouse_opaque="true" name="light texture control" + tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)" width="32" /> <spinner bottom_delta="-4" decimal_digits="3" follows="left|top" height="16" - increment="0.1" initial_val="0.5" label="Intensity:" label_width="65" - left="10" max_val="1" min_val="0" mouse_opaque="true" - name="Light Intensity" width="128" /> + increment="0.1" initial_val="0.5" label="Intensity:" label_width="55" + left="10" max_val="1" min_val="0" mouse_opaque="true" + name="Light Intensity" width="120" /> + <spinner bottom_delta="0" decimal_digits="3" follows="left|top" height="16" + increment="0.1" initial_val="0.5" label="FOV" label_width="55" + left="144" max_val="3" min_val="0" mouse_opaque="true" + name="Light FOV" width="120" /> <spinner bottom_delta="-20" decimal_digits="3" follows="left|top" height="16" - increment="0.1" initial_val="5" label="Radius:" label_width="65" - left_delta="0" max_val="20" min_val="0" mouse_opaque="true" - name="Light Radius" width="128" /> + increment="0.1" initial_val="5" label="Radius" label_width="55" + left="10" max_val="20" min_val="0" mouse_opaque="true" + name="Light Radius" width="120" /> + <spinner bottom_delta="0" decimal_digits="3" follows="left|top" height="16" + increment="0.5" initial_val="0.5" label="Focus" label_width="55" + left="144" max_val="20" min_val="-20" mouse_opaque="true" + name="Light Focus" width="120" /> <spinner bottom_delta="-20" decimal_digits="3" follows="left|top" height="16" - increment="0.25" initial_val="1" label="Falloff:" label_width="65" - left_delta="0" max_val="2" min_val="0" mouse_opaque="true" - name="Light Falloff" width="128" /> + increment="0.25" initial_val="1" label="Falloff" label_width="55" + left="10" max_val="2" min_val="0" mouse_opaque="true" + name="Light Falloff" width="120" /> + <spinner bottom_delta="0" decimal_digits="3" follows="left|top" height="16" + increment="0.05" initial_val="1" label="Ambiance" label_width="55" + left="144" max_val="1" min_val="0" mouse_opaque="true" + name="Light Ambiance" width="120" /> </panel> <!-- Texture sub-tab --> From a96260616070518acc70572dce4e74890ee8c529 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Tue, 7 Sep 2010 14:19:02 +0200 Subject: [PATCH 025/239] fix "about land" (actually llpanellandmedia) crashes --- linden/indra/newview/llpanellandmedia.cpp | 301 ++++++++++------------ linden/indra/newview/llpanellandmedia.h | 20 +- 2 files changed, 132 insertions(+), 189 deletions(-) diff --git a/linden/indra/newview/llpanellandmedia.cpp b/linden/indra/newview/llpanellandmedia.cpp index db68c4279..11f491c3d 100644 --- a/linden/indra/newview/llpanellandmedia.cpp +++ b/linden/indra/newview/llpanellandmedia.cpp @@ -39,8 +39,6 @@ #include "llmimetypes.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" -#include "llviewermedia.h" -#include "llviewerparcelmedia.h" #include "lluictrlfactory.h" // library includes @@ -56,7 +54,6 @@ #include "llsdutil.h" #include "lltexturectrl.h" #include "roles_constants.h" -#include "llscrolllistctrl.h" #include "hippoGridManager.h" @@ -65,8 +62,15 @@ //--------------------------------------------------------------------------- LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) -: LLPanel(), +: LLPanel(std::string("land_media_panel")), + mParcel(parcel), + mCheckSoundLocal(NULL), + mSoundHelpButton(NULL), + mCheckEnableVoiceChat(NULL), + mCheckEnableVoiceChatIsEstateDisabled(NULL), + mCheckEnableVoiceChatParcel(NULL), + mMusicURLEdit(NULL), mMediaURLEdit(NULL), mMediaDescEdit(NULL), mMediaTypeCombo(NULL), @@ -77,7 +81,8 @@ LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) mMediaTextureCtrl(NULL), mMediaAutoScaleCheck(NULL), mMediaLoopCheck(NULL), - mMediaUrlCheck(NULL) + mMediaUrlCheck(NULL), + mMusicUrlCheck(NULL) { } @@ -85,10 +90,34 @@ LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) // virtual LLPanelLandMedia::~LLPanelLandMedia() { + // close LLFloaterURLEntry? +} + + +// static +void LLPanelLandMedia::onClickSoundHelp(void*) +{ + LLNotifications::instance().add("ClickSoundHelpLand"); } + BOOL LLPanelLandMedia::postBuild() { + mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check sound local"); + childSetCommitCallback("check sound local", onCommitAny, this); + + mSoundHelpButton = getChild<LLButton>("?"); + mSoundHelpButton->setClickedCallback(onClickSoundHelp, this); + + mCheckEnableVoiceChat = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel"); + childSetCommitCallback("parcel_enable_voice_channel", onCommitAny, this); + mCheckEnableVoiceChatIsEstateDisabled = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_is_estate_disabled"); + childSetCommitCallback("parcel_enable_voice_channel_is_estate_disabled", onCommitAny, this); + mCheckEnableVoiceChatParcel = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_parcel"); + childSetCommitCallback("parcel_enable_voice_channel_parcel", onCommitAny, this); + + mMusicURLEdit = getChild<LLLineEditor>("music_url"); + childSetCommitCallback("music_url", onCommitAny, this); mMediaTextureCtrl = getChild<LLTextureCtrl>("media texture"); mMediaTextureCtrl->setCommitCallback( onCommitAny ); @@ -101,13 +130,16 @@ BOOL LLPanelLandMedia::postBuild() childSetCommitCallback("media_auto_scale", onCommitAny, this); mMediaLoopCheck = getChild<LLCheckBoxCtrl>("media_loop"); - childSetCommitCallback("media_loop", onCommitAny, this ); + childSetCommitCallback("media_loop", onCommitAny, this); mMediaUrlCheck = getChild<LLCheckBoxCtrl>("hide_media_url"); - childSetCommitCallback("hide_media_url", onCommitAny, this ); + childSetCommitCallback("hide_media_url", onCommitAny, this); + + mMusicUrlCheck = getChild<LLCheckBoxCtrl>("hide_music_url"); + childSetCommitCallback("hide_music_url", onCommitAny, this); mMediaURLEdit = getChild<LLLineEditor>("media_url"); - childSetCommitCallback("media_url", onCommitAny, this ); + childSetCommitCallback("media_url", onCommitAny, this); mMediaDescEdit = getChild<LLLineEditor>("url_description"); childSetCommitCallback("url_description", onCommitAny, this); @@ -116,41 +148,15 @@ BOOL LLPanelLandMedia::postBuild() childSetCommitCallback("media type", onCommitType, this); populateMIMECombo(); - mMediaResetCtrl = getChild<LLSpinCtrl>("media_reset_time"); - childSetCommitCallback("media_reset_time", onCommitAny, this); - mMediaResetCtrlLabel = getChild<LLTextBox>("media_reset"); - mMediaWidthCtrl = getChild<LLSpinCtrl>("media_size_width"); childSetCommitCallback("media_size_width", onCommitAny, this); mMediaHeightCtrl = getChild<LLSpinCtrl>("media_size_height"); childSetCommitCallback("media_size_height", onCommitAny, this); mMediaSizeCtrlLabel = getChild<LLTextBox>("media_size"); - mMediaNavigateAllowCheck = getChild<LLCheckBoxCtrl>("check navigate allow"); - childSetCommitCallback("check navigate allow", onCommitAny, this); - mMediaURLFilterCheck = getChild<LLCheckBoxCtrl>("check navigate filter"); - childSetCommitCallback("check navigate filter", onCommitAny, this); - mSetURLButton = getChild<LLButton>("set_media_url"); childSetAction("set_media_url", onSetBtn, this); - mResetURLButton = getChild<LLButton>("reset_media_url"); - childSetAction("reset_media_url", onResetBtn, this); - - mURLFilterList = getChild<LLScrollListCtrl>("filter_list"); - - mMediaURLFilterDomainEdit = getChild<LLLineEditor>("navigate_filter_domain"); - - mMediaURLFilterAddButton = getChild<LLButton>("add_navigate_filter"); - childSetAction("add_navigate_filter", onClickAddURLFilter, this); - - mMediaURLFilterRemoveButton = getChild<LLButton>("remove_navigate_filter"); - childSetAction("remove_navigate_filter", onClickRemoveURLFilter, this); - - mRadioNavigateControl = getChild<LLRadioGroup>("radio_navigate_allow"); - childSetCommitCallback("radio_navigate_allow", onCommitAny, this); - - return TRUE; } @@ -171,9 +177,59 @@ void LLPanelLandMedia::refresh() // Display options BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); - mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->setEnabled( can_change_media ); + + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + if (!region) + { + // never seen this happen, but log it + llwarns << "Couldn't get selected region." << llendl; + } + + // We need to do this differently for OpenSim because it doesn't include + // REGION_FLAGS_ALLOW_VOICE in the "RegionInfo" message as of 0.6.9 PF -- MC + bool allow_voice = parcel->getParcelFlagAllowVoice(); + if (gHippoGridManager->getConnectedGrid()->isSecondLife()) + { + if (region && region->isVoiceEnabled()) // estate-wide voice-disable overrides all + { + mCheckEnableVoiceChatIsEstateDisabled->setVisible(false); + + mCheckEnableVoiceChat->setVisible(true); + mCheckEnableVoiceChat->setEnabled( can_change_media ); + mCheckEnableVoiceChat->set(allow_voice); + + mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); + } + else // disabled at region level + { + mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); // always disabled + mCheckEnableVoiceChat->setVisible(false); + mCheckEnableVoiceChat->setEnabled(false); + mCheckEnableVoiceChat->set(false); + + mCheckEnableVoiceChatParcel->setEnabled(false); + } + } + else + { + mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); + + mCheckEnableVoiceChat->setVisible(true); + mCheckEnableVoiceChat->setEnabled( can_change_media ); + mCheckEnableVoiceChat->set(allow_voice); + + mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice ); + } + + mCheckEnableVoiceChatParcel->set(!parcel->getParcelFlagUseEstateVoiceChannel()); + + mMusicURLEdit->setText(parcel->getMusicURL()); + mMusicURLEdit->setEnabled( can_change_media ); - childSetText("current_url", parcel->getMediaCurrentURL()); + mMediaURLEdit->setText(parcel->getMediaURL()); + mMediaURLEdit->setEnabled( FALSE ); mMediaDescEdit->setText(parcel->getMediaDesc()); mMediaDescEdit->setEnabled( can_change_media ); @@ -190,11 +246,15 @@ void LLPanelLandMedia::refresh() mMediaUrlCheck->set( parcel->getObscureMedia() ); mMediaUrlCheck->setEnabled( can_change_media ); + mMusicUrlCheck->set( parcel->getObscureMusic() ); + mMusicUrlCheck->setEnabled( can_change_media ); + // don't display urls if you're not able to change it // much requested change in forums so people can't 'steal' urls // NOTE: bug#2009 means this is still vunerable - however, bug // should be closed since this bug opens up major security issues elsewhere. bool obscure_media = ! can_change_media && parcel->getObscureMedia(); + bool obscure_music = ! can_change_media && parcel->getObscureMusic(); // Special code to disable asterixes for html type if(mime_type == "text/html") @@ -204,6 +264,7 @@ void LLPanelLandMedia::refresh() mMediaUrlCheck->setEnabled( false ); } + mMusicURLEdit->setDrawAsterixes( obscure_music ); mMediaURLEdit->setDrawAsterixes( obscure_media ); mMediaAutoScaleCheck->set( parcel->getMediaAutoScale () ); @@ -217,10 +278,6 @@ void LLPanelLandMedia::refresh() else mMediaLoopCheck->set( false ); mMediaLoopCheck->setEnabled ( can_change_media && allow_looping ); - - mMediaResetCtrl->set( parcel->getMediaURLTimeout() ); - mMediaResetCtrl->setEnabled( can_change_media ); - mMediaResetCtrlLabel->setEnabled( can_change_media ); // disallow media size change for mime types that don't allow it bool allow_resize = LLMIMETypes::findAllowResize( mime_type ); @@ -244,45 +301,28 @@ void LLPanelLandMedia::refresh() mMediaTextureCtrl->setEnabled( can_change_media ); mSetURLButton->setEnabled( can_change_media ); - mResetURLButton->setEnabled( can_change_media ); - mMediaURLFilterCheck->set( parcel->getMediaURLFilterEnable() ); - mMediaURLFilterCheck->setEnabled( can_change_media ); + #if 0 + // there is a media url and a media texture selected + if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) + { + // turn on transport controls if allowed for this parcel + mMediaStopButton->setEnabled ( editable ); + mMediaStartButton->setEnabled ( editable ); + } + else + { + // no media url or no media texture + mMediaStopButton->setEnabled ( FALSE ); + mMediaStartButton->setEnabled ( FALSE ); + }; + #endif LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get(); if (floater_url_entry) { floater_url_entry->updateFromLandMediaPanel(); } - - // This radial control is really just an inverse mapping to the boolean allow_navigate value. - // It is set as a radial merely for user readability. - mRadioNavigateControl->setSelectedIndex(! parcel->getMediaAllowNavigate()); - mRadioNavigateControl->setEnabled( can_change_media ); - - mMediaURLFilterDomainEdit->setEnabled( can_change_media ); - mMediaURLFilterAddButton->setEnabled( can_change_media ); - mMediaURLFilterRemoveButton->setEnabled( can_change_media ); - - if (mURLFilterList) - { - mURLFilterList->setEnabled( can_change_media ); - - mURLFilterList->deleteAllItems(); - - LLSD list = parcel->getMediaURLFilterList(); - - for (LLSD::array_iterator i = list.beginArray(); i != list.endArray(); ++i) - { - std::string domain = (*i).asString(); - - LLSD element; - element["id"] = domain; - element["columns"][0]["value"] = domain; - - mURLFilterList->addElement(element); - } - } } } @@ -318,6 +358,7 @@ void LLPanelLandMedia::setMediaType(const std::string& mime_type) std::string media_key = LLMIMETypes::widgetType(mime_type); mMediaTypeCombo->setValue(media_key); + childSetText("mime_type", mime_type); } @@ -329,14 +370,14 @@ void LLPanelLandMedia::setMediaURL(const std::string& media_url) parcel->setMediaCurrentURL(media_url); // LLViewerMedia::navigateHome(); - mMediaURLEdit->onCommit(); - // LLViewerParcelMedia::sendMediaNavigateMessage(media_url); - childSetText("current_url", media_url); +// // LLViewerParcelMedia::sendMediaNavigateMessage(media_url); +// childSetText("current_url", media_url); } + std::string LLPanelLandMedia::getMediaURL() { - return mMediaURLEdit->getText(); + return mMediaURLEdit->getText(); } // static @@ -365,26 +406,33 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata) } // Extract data from UI + BOOL sound_local = self->mCheckSoundLocal->get(); + std::string music_url = self->mMusicURLEdit->getText(); std::string media_url = self->mMediaURLEdit->getText(); std::string media_desc = self->mMediaDescEdit->getText(); std::string mime_type = self->childGetText("mime_type"); U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); U8 media_loop = self->mMediaLoopCheck->get(); U8 obscure_media = self->mMediaUrlCheck->get(); - F32 media_reset_time = (F32)self->mMediaResetCtrl->get(); + U8 obscure_music = self->mMusicUrlCheck->get(); S32 media_width = (S32)self->mMediaWidthCtrl->get(); S32 media_height = (S32)self->mMediaHeightCtrl->get(); LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); - U8 navigate_allow = ! self->mRadioNavigateControl->getSelectedIndex(); - U8 navigate_filter = self->mMediaURLFilterCheck->get(); + BOOL voice_enabled = self->mCheckEnableVoiceChat->get(); + BOOL voice_estate_chan = ! self->mCheckEnableVoiceChatParcel->get(); self->childSetText("mime_type", mime_type); // Remove leading/trailing whitespace (common when copying/pasting) + LLStringUtil::trim(music_url); LLStringUtil::trim(media_url); // Push data into current parcel + parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); + parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); + parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); + parcel->setMusicURL(music_url); parcel->setMediaURL(media_url); parcel->setMediaType(mime_type); parcel->setMediaDesc(media_desc); @@ -394,10 +442,7 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata) parcel->setMediaAutoScale ( media_auto_scale ); parcel->setMediaLoop ( media_loop ); parcel->setObscureMedia( obscure_media ); - parcel->setMediaURLFilterEnable(navigate_filter); - parcel->setMediaAllowNavigate(navigate_allow); - parcel->setMediaURLTimeout(media_reset_time); - + parcel->setObscureMusic( obscure_music ); // Send current parcel data upstream to server LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); @@ -415,92 +460,4 @@ void LLPanelLandMedia::onSetBtn(void *userdata) { parent_floater->addDependentFloater(self->mURLEntryFloater.get()); } -} - -// static -void LLPanelLandMedia::onResetBtn(void *userdata) -{ - LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; - LLParcel* parcel = self->mParcel->getParcel(); - // LLViewerMedia::navigateHome(); - self->refresh(); - self->childSetText("current_url", parcel->getMediaURL()); - // LLViewerParcelMedia::sendMediaNavigateMessage(parcel->getMediaURL()); - -} -// static -void LLPanelLandMedia::onClickAddURLFilter(void *userdata) -{ - LLPanelLandMedia *panelp = (LLPanelLandMedia *)userdata; - LLParcel* parcel = panelp->mParcel->getParcel(); - - LLSD list = parcel->getMediaURLFilterList(); - - std::string domain = panelp->mMediaURLFilterDomainEdit->getText(); - LLStringUtil::trim(domain); - - BOOL add = TRUE; - if (domain == "") - { - add = FALSE; - } - - // check for dupes - for(S32 i = 0; i < list.size(); i++) - { - if (list[i].asString() == domain) - { - add = FALSE; - break; - } - } - - if (add) - { - list.append(domain); - parcel->setMediaURLFilterList(list); - - LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); - - panelp->mMediaURLFilterDomainEdit->setText(std::string("")); - - panelp->refresh(); - } - -} - -// static -void LLPanelLandMedia::onClickRemoveURLFilter(void *data) -{ - LLPanelLandMedia* panelp = (LLPanelLandMedia*)data; - if (panelp && panelp->mURLFilterList) - { - LLParcel* parcel = panelp->mParcel->getParcel(); - if (parcel) - { - LLSD list = parcel->getMediaURLFilterList(); - - std::vector<LLScrollListItem*> domains = panelp->mURLFilterList->getAllSelected(); - for (std::vector<LLScrollListItem*>::iterator iter = domains.begin(); iter != domains.end(); iter++) - { - LLScrollListItem* item = *iter; - const std::string domain = item->getValue().asString(); - - for(S32 i = 0; i < list.size(); i++) - { - if (list[i].asString() == domain) - { - list.erase(i); - break; - } - } - } - - parcel->setMediaURLFilterList(list); - LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); - - panelp->refresh(); - } - } - -} +} \ No newline at end of file diff --git a/linden/indra/newview/llpanellandmedia.h b/linden/indra/newview/llpanellandmedia.h index d63f0f6b5..845b95340 100644 --- a/linden/indra/newview/llpanellandmedia.h +++ b/linden/indra/newview/llpanellandmedia.h @@ -56,10 +56,8 @@ class LLPanelLandMedia static void onCommitAny(LLUICtrl* ctrl, void *userdata); static void onCommitType(LLUICtrl* ctrl, void *userdata); static void onSetBtn(void* userdata); - static void onResetBtn(void* userdata); - static void onClickAddURLFilter(void *userdata); - static void onClickRemoveURLFilter(void *userdata); - + static void onClickSoundHelp(void*); + private: LLCheckBoxCtrl* mCheckSoundLocal; LLButton* mSoundHelpButton; @@ -71,11 +69,8 @@ class LLPanelLandMedia LLLineEditor* mMediaDescEdit; LLComboBox* mMediaTypeCombo; LLButton* mSetURLButton; - LLButton* mResetURLButton; - LLSpinCtrl* mMediaResetCtrl; LLSpinCtrl* mMediaHeightCtrl; LLSpinCtrl* mMediaWidthCtrl; - LLTextBox* mMediaResetCtrlLabel; LLTextBox* mMediaSizeCtrlLabel; LLTextureCtrl* mMediaTextureCtrl; LLCheckBoxCtrl* mMediaAutoScaleCheck; @@ -83,17 +78,8 @@ class LLPanelLandMedia LLCheckBoxCtrl* mMediaUrlCheck; LLCheckBoxCtrl* mMusicUrlCheck; LLHandle<LLFloater> mURLEntryFloater; - LLCheckBoxCtrl* mMediaNavigateAllowCheck; - LLCheckBoxCtrl* mMediaURLFilterCheck; - LLLineEditor* mMediaURLFilterDomainEdit; - LLButton* mMediaURLFilterAddButton; - LLButton* mMediaURLFilterRemoveButton; - LLScrollListCtrl* mURLFilterList; - LLRadioGroup* mRadioNavigateControl; - - LLSafeHandle<LLParcelSelection>& mParcel; }; -#endif +#endif \ No newline at end of file From 106b42c9fc893c3172dc843a70b6e79a22eed985 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Mon, 9 Aug 2010 19:03:58 +0200 Subject: [PATCH 026/239] fix some mime type issues --- linden/indra/llinventory/llparcel.cpp | 13 ++-- .../skins/default/xui/en-us/mime_types.xml | 31 +++++++- .../default/xui/en-us/mime_types_linux.xml | 71 ++++++++++++++----- .../default/xui/en-us/mime_types_mac.xml | 69 +++++++++++++----- 4 files changed, 139 insertions(+), 45 deletions(-) mode change 100644 => 100755 linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml mode change 100644 => 100755 linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml diff --git a/linden/indra/llinventory/llparcel.cpp b/linden/indra/llinventory/llparcel.cpp index 547862f81..39605ebfd 100644 --- a/linden/indra/llinventory/llparcel.cpp +++ b/linden/indra/llinventory/llparcel.cpp @@ -306,11 +306,11 @@ void LLParcel::setMediaType(const std::string& type) mMediaType = type; mMediaType = rawstr_to_utf8(mMediaType); - // This code attempts to preserve legacy movie functioning - if(mMediaType.empty() && ! mMediaURL.empty()) - { - setMediaType(std::string("video/vnd.secondlife.qt.legacy")); - } +// // This legacy code prevents any media different from video from working on OpenSim +// if(mMediaType.empty() && ! mMediaURL.empty()) +// { +// setMediaType(std::string("video/vnd.secondlife.qt.legacy")); +// } } void LLParcel::setMediaWidth(S32 width) { @@ -762,7 +762,8 @@ void LLParcel::unpackMessage(LLMessageSystem* msg) } else { - setMediaType(std::string("video/vnd.secondlife.qt.legacy")); + setMediaType(std::string("")); //having mMediaType empty causes autodetect, + // thats what we want -- AW setMediaDesc(std::string("No Description available without Server Upgrade")); mMediaLoop = true; mObscureMedia = true; diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml index 9f0c631df..a585069fa 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml @@ -120,7 +120,7 @@ none </widgettype> <impl> - media_plugin_quicktime + media_plugin_webkit </impl> </mimetype> <mimetype name="none/none"> @@ -130,6 +130,9 @@ <widgettype> none </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/*"> <label name="audio2_label"> @@ -160,6 +163,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> @@ -179,6 +185,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/ogg"> <label name="application/ogg_label"> @@ -187,6 +196,9 @@ <widgettype> audio </widgettype> + <impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="application/pdf"> <label name="application/pdf_label"> @@ -195,6 +207,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/postscript"> <label name="application/postscript_label"> @@ -203,6 +218,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/rtf"> <label name="application/rtf_label"> @@ -211,6 +229,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/smil"> <label name="application/smil_label"> @@ -220,7 +241,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_webkit </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -230,6 +251,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/x-director"> <label name="application/x-director_label"> @@ -238,6 +262,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml old mode 100644 new mode 100755 index 2977d7a2e..e95b371d0 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_linux.xml @@ -120,7 +120,7 @@ none </widgettype> <impl> - media_plugin_gstreamer + media_plugin_webkit </impl> </mimetype> <mimetype name="none/none"> @@ -130,6 +130,9 @@ <widgettype> none </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/*"> <label name="audio2_label"> @@ -138,6 +141,9 @@ <widgettype> audio </widgettype> + <impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype name="video/*"> <label name="video2_label"> @@ -146,6 +152,9 @@ <widgettype> movie </widgettype> + <impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype name="image/*"> <label name="image2_label"> @@ -154,6 +163,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> @@ -163,8 +175,8 @@ movie </widgettype> <impl> - media_plugin_gstreamer - </impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype name="application/javascript"> <label name="application/javascript_label"> @@ -173,6 +185,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/ogg"> <label name="application/ogg_label"> @@ -181,6 +196,9 @@ <widgettype> audio </widgettype> + <impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype name="application/pdf"> <label name="application/pdf_label"> @@ -189,6 +207,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/postscript"> <label name="application/postscript_label"> @@ -197,6 +218,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/rtf"> <label name="application/rtf_label"> @@ -205,16 +229,19 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/smil"> <label name="application/smil_label"> - Synchronized Multimedia Integration Language (SMIL) + Synchronized Multimedia Integration Language (SMIL) </label> <widgettype> movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_webkit </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -224,6 +251,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/x-director"> <label name="application/x-director_label"> @@ -232,6 +262,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> @@ -351,8 +384,8 @@ web </widgettype> <impl> - media_plugin_webkit - </impl> + media_plugin_webkit + </impl> </mimetype> <mimetype menu="1" name="text/plain"> <label name="text/plain_label"> @@ -384,8 +417,8 @@ movie </widgettype> <impl> - media_plugin_gstreamer - </impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype name="video/mp4"> <label name="video/mp4_label"> @@ -395,8 +428,8 @@ movie </widgettype> <impl> - media_plugin_gstreamer - </impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype menu="1" name="video/quicktime"> <label name="video/quicktime_label"> @@ -406,8 +439,8 @@ movie </widgettype> <impl> - media_plugin_gstreamer - </impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype name="video/x-ms-asf"> <label name="video/x-ms-asf_label"> @@ -417,8 +450,8 @@ movie </widgettype> <impl> - media_plugin_gstreamer - </impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype name="video/x-ms-wmv"> <label name="video/x-ms-wmv_label"> @@ -428,8 +461,8 @@ movie </widgettype> <impl> - media_plugin_gstreamer - </impl> + media_plugin_gstreamer + </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> <label name="video/x-msvideo_label"> @@ -439,7 +472,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer - </impl> + media_plugin_gstreamer + </impl> </mimetype> </mimetypes> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml old mode 100644 new mode 100755 index 4a7a6e17a..7931e55c0 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_mac.xml @@ -130,6 +130,9 @@ <widgettype> none </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/*"> <label name="audio2_label"> @@ -138,6 +141,9 @@ <widgettype> audio </widgettype> + <impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="video/*"> <label name="video2_label"> @@ -146,6 +152,9 @@ <widgettype> movie </widgettype> + <impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="image/*"> <label name="image2_label"> @@ -154,6 +163,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> @@ -163,8 +175,8 @@ movie </widgettype> <impl> - media_plugin_quicktime - </impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="application/javascript"> <label name="application/javascript_label"> @@ -173,6 +185,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/ogg"> <label name="application/ogg_label"> @@ -181,6 +196,9 @@ <widgettype> audio </widgettype> + <impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="application/pdf"> <label name="application/pdf_label"> @@ -189,6 +207,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/postscript"> <label name="application/postscript_label"> @@ -197,6 +218,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/rtf"> <label name="application/rtf_label"> @@ -205,16 +229,19 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/smil"> <label name="application/smil_label"> - Synchronized Multimedia Integration Language (SMIL) + Synchronized Multimedia Integration Language (SMIL) </label> <widgettype> movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_webkit </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -224,6 +251,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/x-director"> <label name="application/x-director_label"> @@ -232,6 +262,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> @@ -351,8 +384,8 @@ web </widgettype> <impl> - media_plugin_webkit - </impl> + media_plugin_webkit + </impl> </mimetype> <mimetype menu="1" name="text/plain"> <label name="text/plain_label"> @@ -384,8 +417,8 @@ movie </widgettype> <impl> - media_plugin_quicktime - </impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="video/mp4"> <label name="video/mp4_label"> @@ -395,8 +428,8 @@ movie </widgettype> <impl> - media_plugin_quicktime - </impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype menu="1" name="video/quicktime"> <label name="video/quicktime_label"> @@ -406,8 +439,8 @@ movie </widgettype> <impl> - media_plugin_quicktime - </impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="video/x-ms-asf"> <label name="video/x-ms-asf_label"> @@ -417,8 +450,8 @@ movie </widgettype> <impl> - media_plugin_quicktime - </impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="video/x-ms-wmv"> <label name="video/x-ms-wmv_label"> @@ -428,8 +461,8 @@ movie </widgettype> <impl> - media_plugin_quicktime - </impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> <label name="video/x-msvideo_label"> @@ -439,7 +472,7 @@ movie </widgettype> <impl> - media_plugin_quicktime - </impl> + media_plugin_quicktime + </impl> </mimetype> </mimetypes> From 70800de39a3d942d2120abd926fbdb24577fb0f6 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Sat, 7 Aug 2010 19:17:13 +0200 Subject: [PATCH 027/239] update to viewer-external SLPlugin + webkit. Fixes (lots of) webpages not loading. Issue: llqtwebkit needs update for Linux 64bit --- linden/indra/cmake/PulseAudio.cmake | 28 + linden/indra/llplugin/CMakeLists.txt | 19 + linden/indra/llplugin/llpluginclassmedia.cpp | 26 +- linden/indra/llplugin/llpluginclassmedia.h | 9 + .../indra/llplugin/llpluginclassmediaowner.h | 2 + linden/indra/llplugin/llplugincookiestore.cpp | 671 ++++++++++++++++++ linden/indra/llplugin/llplugincookiestore.h | 127 ++++ linden/indra/llplugin/llpluginmessagepipe.cpp | 121 +++- linden/indra/llplugin/llpluginmessagepipe.h | 9 +- .../indra/llplugin/llpluginprocesschild.cpp | 77 +- linden/indra/llplugin/llpluginprocesschild.h | 7 + .../indra/llplugin/llpluginprocessparent.cpp | 455 +++++++++++- linden/indra/llplugin/llpluginprocessparent.h | 32 +- linden/indra/llplugin/slplugin/CMakeLists.txt | 39 +- .../indra/llplugin/slplugin/slplugin-objc.h | 42 ++ .../indra/llplugin/slplugin/slplugin-objc.mm | 89 +++ linden/indra/llplugin/slplugin/slplugin.cpp | 111 ++- .../llplugin/slplugin/slplugin_info.plist | 4 +- .../indra/media_plugins/webkit/CMakeLists.txt | 35 +- .../webkit/dummy_volume_catcher.cpp | 65 ++ .../webkit/linux_volume_catcher.cpp | 79 +-- .../webkit/linux_volume_catcher_pa_syms.inc | 0 .../linux_volume_catcher_paglib_syms.inc | 0 .../webkit/mac_volume_catcher.cpp | 275 +++++++ .../webkit/media_plugin_webkit.cpp | 62 +- .../media_plugins/webkit/volume_catcher.h | 61 ++ .../webkit/windows_volume_catcher.cpp | 124 ++++ linden/install.xml | 38 +- 28 files changed, 2445 insertions(+), 162 deletions(-) create mode 100644 linden/indra/cmake/PulseAudio.cmake create mode 100644 linden/indra/llplugin/llplugincookiestore.cpp create mode 100644 linden/indra/llplugin/llplugincookiestore.h create mode 100644 linden/indra/llplugin/slplugin/slplugin-objc.h create mode 100644 linden/indra/llplugin/slplugin/slplugin-objc.mm create mode 100644 linden/indra/media_plugins/webkit/dummy_volume_catcher.cpp mode change 100755 => 100644 linden/indra/media_plugins/webkit/linux_volume_catcher.cpp mode change 100755 => 100644 linden/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc mode change 100755 => 100644 linden/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc create mode 100644 linden/indra/media_plugins/webkit/mac_volume_catcher.cpp create mode 100644 linden/indra/media_plugins/webkit/volume_catcher.h create mode 100644 linden/indra/media_plugins/webkit/windows_volume_catcher.cpp diff --git a/linden/indra/cmake/PulseAudio.cmake b/linden/indra/cmake/PulseAudio.cmake new file mode 100644 index 000000000..f8087a808 --- /dev/null +++ b/linden/indra/cmake/PulseAudio.cmake @@ -0,0 +1,28 @@ +# -*- cmake -*- +include(Prebuilt) + +if (STANDALONE) + include(FindPkgConfig) + + pkg_check_modules(PULSEAUDIO REQUIRED libpulse-mainloop-glib) + +elseif (LINUX) + use_prebuilt_binary(pulseaudio) + set(PULSEAUDIO_FOUND ON FORCE BOOL) + set(PULSEAUDIO_INCLUDE_DIRS + ${LIBS_PREBUILT_DIR}/include + ) + # We don't need to explicitly link against pulseaudio itself, because + # the viewer probes for the system's copy at runtime. + set(PULSEAUDIO_LIBRARIES + # none needed! + ) +endif (STANDALONE) + +if (PULSEAUDIO_FOUND) + set(PULSEAUDIO ON CACHE BOOL "Build with PulseAudio support, if available.") +endif (PULSEAUDIO_FOUND) + +if (PULSEAUDIO) + add_definitions(-DLL_PULSEAUDIO_ENABLED=1) +endif (PULSEAUDIO) diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt index 8a2eff876..8eead9453 100644 --- a/linden/indra/llplugin/CMakeLists.txt +++ b/linden/indra/llplugin/CMakeLists.txt @@ -7,6 +7,7 @@ if(HAVE_64_BIT) endif(HAVE_64_BIT) include(00-Common) +include(CURL) include(LLCommon) include(LLImage) include(LLMath) @@ -27,6 +28,7 @@ include_directories( set(llplugin_SOURCE_FILES llpluginclassmedia.cpp + llplugincookiestore.cpp llplugininstance.cpp llpluginmessage.cpp llpluginmessagepipe.cpp @@ -40,6 +42,7 @@ set(llplugin_HEADER_FILES llpluginclassmedia.h llpluginclassmediaowner.h + llplugincookiestore.h llplugininstance.h llpluginmessage.h llpluginmessageclasses.h @@ -65,3 +68,19 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) add_subdirectory(slplugin) + +# # Add tests +# include(LLAddBuildTest) +# # UNIT TESTS +# SET(llplugin_TEST_SOURCE_FILES +# llplugincookiestore.cpp +# ) +# +# # llplugincookiestore has a dependency on curl, so we need to link the curl library into the test. +# set_source_files_properties( +# llplugincookiestore.cpp +# PROPERTIES +# LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES}" +# ) +# +# LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}") \ No newline at end of file diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp index b958f0c70..86645248b 100755 --- a/linden/indra/llplugin/llpluginclassmedia.cpp +++ b/linden/indra/llplugin/llpluginclassmedia.cpp @@ -59,11 +59,15 @@ LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner) mOwner = owner; mPlugin = NULL; reset(); + + //debug use + mDeleteOK = true ; } LLPluginClassMedia::~LLPluginClassMedia() { + llassert_always(mDeleteOK) ; reset(); } @@ -162,7 +166,7 @@ void LLPluginClassMedia::idle(void) mPlugin->idle(); } - if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL)) + if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked())) { // Can't process a size change at this time } @@ -439,6 +443,12 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int { if(type == MOUSE_EVENT_MOVE) { + if(!mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked()) + { + // Don't queue up mouse move events that can't be delivered. + return; + } + if((x == mLastMouseX) && (y == mLastMouseY)) { // Don't spam unnecessary mouse move events. @@ -995,6 +1005,13 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) mClickTargetType = TARGET_NONE; mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); } + else if(message_name == "cookie_set") + { + if(mOwner) + { + mOwner->handleCookieSet(this, message.getValue("cookie")); + } + } else { LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; @@ -1078,6 +1095,13 @@ void LLPluginClassMedia::clear_cookies() sendMessage(message); } +void LLPluginClassMedia::set_cookies(const std::string &cookies) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies"); + message.setValue("cookies", cookies); + sendMessage(message); +} + void LLPluginClassMedia::enable_cookies(bool enable) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies"); diff --git a/linden/indra/llplugin/llpluginclassmedia.h b/linden/indra/llplugin/llpluginclassmedia.h index fc94563b2..abb79268f 100755 --- a/linden/indra/llplugin/llpluginclassmedia.h +++ b/linden/indra/llplugin/llpluginclassmedia.h @@ -191,6 +191,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner void focus(bool focused); void clear_cache(); void clear_cookies(); + void set_cookies(const std::string &cookies); void enable_cookies(bool enable); void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0); void browse_stop(); @@ -374,6 +375,14 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner F64 mCurrentRate; F64 mLoadedDuration; +//-------------------------------------- + //debug use only + // +private: + bool mDeleteOK ; +public: + void setDeleteOK(bool flag) { mDeleteOK = flag ;} +//-------------------------------------- }; #endif // LL_LLPLUGINCLASSMEDIA_H diff --git a/linden/indra/llplugin/llpluginclassmediaowner.h b/linden/indra/llplugin/llpluginclassmediaowner.h index c1f6ae170..9d1f35220 100755 --- a/linden/indra/llplugin/llpluginclassmediaowner.h +++ b/linden/indra/llplugin/llpluginclassmediaowner.h @@ -41,6 +41,7 @@ #include <queue> class LLPluginClassMedia; +class LLPluginCookieStore; class LLPluginClassMediaOwner { @@ -80,6 +81,7 @@ class LLPluginClassMediaOwner virtual ~LLPluginClassMediaOwner() {}; virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {}; + virtual void handleCookieSet(LLPluginClassMedia* /*self*/, const std::string &/*cookie*/) {}; }; #endif // LL_LLPLUGINCLASSMEDIAOWNER_H diff --git a/linden/indra/llplugin/llplugincookiestore.cpp b/linden/indra/llplugin/llplugincookiestore.cpp new file mode 100644 index 000000000..283ba356f --- /dev/null +++ b/linden/indra/llplugin/llplugincookiestore.cpp @@ -0,0 +1,671 @@ +/** + * @file llplugincookiestore.cpp + * @brief LLPluginCookieStore provides central storage for http cookies used by plugins + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +#include "linden_common.h" +#include "indra_constants.h" + +#include "llplugincookiestore.h" +#include <iostream> + +// for curl_getdate() (apparently parsing RFC 1123 dates is hard) +#include <curl/curl.h> + +LLPluginCookieStore::LLPluginCookieStore(): + mHasChangedCookies(false) +{ +} + + +LLPluginCookieStore::~LLPluginCookieStore() +{ + clearCookies(); +} + + +LLPluginCookieStore::Cookie::Cookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end): + mCookie(s, cookie_start, cookie_end - cookie_start), + mNameStart(0), mNameEnd(0), + mValueStart(0), mValueEnd(0), + mDomainStart(0), mDomainEnd(0), + mPathStart(0), mPathEnd(0), + mDead(false), mChanged(true) +{ +} + +LLPluginCookieStore::Cookie *LLPluginCookieStore::Cookie::createFromString(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, const std::string &host) +{ + Cookie *result = new Cookie(s, cookie_start, cookie_end); + + if(!result->parse(host)) + { + delete result; + result = NULL; + } + + return result; +} + +std::string LLPluginCookieStore::Cookie::getKey() const +{ + std::string result; + if(mDomainEnd > mDomainStart) + { + result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart); + } + result += ';'; + if(mPathEnd > mPathStart) + { + result += mCookie.substr(mPathStart, mPathEnd - mPathStart); + } + result += ';'; + result += mCookie.substr(mNameStart, mNameEnd - mNameStart); + return result; +} + +bool LLPluginCookieStore::Cookie::parse(const std::string &host) +{ + bool first_field = true; + + std::string::size_type cookie_end = mCookie.size(); + std::string::size_type field_start = 0; + + LL_DEBUGS("CookieStoreParse") << "parsing cookie: " << mCookie << LL_ENDL; + while(field_start < cookie_end) + { + // Finding the start of the next field requires honoring special quoting rules + // see the definition of 'quoted-string' in rfc2616 for details + std::string::size_type next_field_start = findFieldEnd(field_start); + + // The end of this field should not include the terminating ';' or any trailing whitespace + std::string::size_type field_end = mCookie.find_last_not_of("; ", next_field_start); + if(field_end == std::string::npos || field_end < field_start) + { + // This field was empty or all whitespace. Set end = start so it shows as empty. + field_end = field_start; + } + else if (field_end < next_field_start) + { + // we actually want the index of the char _after_ what 'last not of' found + ++field_end; + } + + // find the start of the actual name (skip separator and possible whitespace) + std::string::size_type name_start = mCookie.find_first_not_of("; ", field_start); + if(name_start == std::string::npos || name_start > next_field_start) + { + // Again, nothing but whitespace. + name_start = field_start; + } + + // the name and value are separated by the first equals sign + std::string::size_type name_value_sep = mCookie.find_first_of("=", name_start); + if(name_value_sep == std::string::npos || name_value_sep > field_end) + { + // No separator found, so this is a field without an = + name_value_sep = field_end; + } + + // the name end is before the name-value separator + std::string::size_type name_end = mCookie.find_last_not_of("= ", name_value_sep); + if(name_end == std::string::npos || name_end < name_start) + { + // I'm not sure how we'd hit this case... it seems like it would have to be an empty name. + name_end = name_start; + } + else if (name_end < name_value_sep) + { + // we actually want the index of the char _after_ what 'last not of' found + ++name_end; + } + + // Value is between the name-value sep and the end of the field. + std::string::size_type value_start = mCookie.find_first_not_of("= ", name_value_sep); + if(value_start == std::string::npos || value_start > field_end) + { + // All whitespace or empty value + value_start = field_end; + } + std::string::size_type value_end = mCookie.find_last_not_of("; ", field_end); + if(value_end == std::string::npos || value_end < value_start) + { + // All whitespace or empty value + value_end = value_start; + } + else if (value_end < field_end) + { + // we actually want the index of the char _after_ what 'last not of' found + ++value_end; + } + + LL_DEBUGS("CookieStoreParse") + << " field name: \"" << mCookie.substr(name_start, name_end - name_start) + << "\", value: \"" << mCookie.substr(value_start, value_end - value_start) << "\"" + << LL_ENDL; + + // See whether this field is one we know + if(first_field) + { + // The first field is the name=value pair + mNameStart = name_start; + mNameEnd = name_end; + mValueStart = value_start; + mValueEnd = value_end; + first_field = false; + } + else + { + // Subsequent fields must come from the set in rfc2109 + if(matchName(name_start, name_end, "expires")) + { + std::string date_string(mCookie, value_start, value_end - value_start); + // If the cookie contains an "expires" field, it MUST contain a parsable date. + + // HACK: LLDate apparently can't PARSE an rfc1123-format date, even though it can GENERATE one. + // The curl function curl_getdate can do this, but I'm hesitant to unilaterally introduce a curl dependency in LLDate. +#if 1 + time_t date = curl_getdate(date_string.c_str(), NULL ); + mDate.secondsSinceEpoch((F64)date); + LL_DEBUGS("CookieStoreParse") << " expire date parsed to: " << mDate.asRFC1123() << LL_ENDL; +#else + // This doesn't work (rfc1123-format dates cause it to fail) + if(!mDate.fromString(date_string)) + { + // Date failed to parse. + LL_WARNS("CookieStoreParse") << "failed to parse cookie's expire date: " << date << LL_ENDL; + return false; + } +#endif + } + else if(matchName(name_start, name_end, "domain")) + { + mDomainStart = value_start; + mDomainEnd = value_end; + } + else if(matchName(name_start, name_end, "path")) + { + mPathStart = value_start; + mPathEnd = value_end; + } + else if(matchName(name_start, name_end, "max-age")) + { + // TODO: how should we handle this? + } + else if(matchName(name_start, name_end, "secure")) + { + // We don't care about the value of this field (yet) + } + else if(matchName(name_start, name_end, "version")) + { + // We don't care about the value of this field (yet) + } + else if(matchName(name_start, name_end, "comment")) + { + // We don't care about the value of this field (yet) + } + else if(matchName(name_start, name_end, "httponly")) + { + // We don't care about the value of this field (yet) + } + else + { + // An unknown field is a parse failure + LL_WARNS("CookieStoreParse") << "unexpected field name: " << mCookie.substr(name_start, name_end - name_start) << LL_ENDL; + return false; + } + + } + + + // move on to the next field, skipping this field's separator and any leading whitespace + field_start = mCookie.find_first_not_of("; ", next_field_start); + } + + // The cookie MUST have a name + if(mNameEnd <= mNameStart) + return false; + + // If the cookie doesn't have a domain, add the current host as the domain. + if(mDomainEnd <= mDomainStart) + { + if(host.empty()) + { + // no domain and no current host -- this is a parse failure. + return false; + } + + // Figure out whether this cookie ended with a ";" or not... + std::string::size_type last_char = mCookie.find_last_not_of(" "); + if((last_char != std::string::npos) && (mCookie[last_char] != ';')) + { + mCookie += ";"; + } + + mCookie += " domain="; + mDomainStart = mCookie.size(); + mCookie += host; + mDomainEnd = mCookie.size(); + + LL_DEBUGS("CookieStoreParse") << "added domain (" << mDomainStart << " to " << mDomainEnd << "), new cookie is: " << mCookie << LL_ENDL; + } + + // If the cookie doesn't have a path, add "/". + if(mPathEnd <= mPathStart) + { + // Figure out whether this cookie ended with a ";" or not... + std::string::size_type last_char = mCookie.find_last_not_of(" "); + if((last_char != std::string::npos) && (mCookie[last_char] != ';')) + { + mCookie += ";"; + } + + mCookie += " path="; + mPathStart = mCookie.size(); + mCookie += "/"; + mPathEnd = mCookie.size(); + + LL_DEBUGS("CookieStoreParse") << "added path (" << mPathStart << " to " << mPathEnd << "), new cookie is: " << mCookie << LL_ENDL; + } + + + return true; +} + +std::string::size_type LLPluginCookieStore::Cookie::findFieldEnd(std::string::size_type start, std::string::size_type end) +{ + std::string::size_type result = start; + + if(end == std::string::npos) + end = mCookie.size(); + + bool in_quotes = false; + for(; (result < end); result++) + { + switch(mCookie[result]) + { + case '\\': + if(in_quotes) + result++; // The next character is backslash-quoted. Skip over it. + break; + case '"': + in_quotes = !in_quotes; + break; + case ';': + if(!in_quotes) + return result; + break; + } + } + + // If we got here, no ';' was found. + return end; +} + +bool LLPluginCookieStore::Cookie::matchName(std::string::size_type start, std::string::size_type end, const char *name) +{ + // NOTE: this assumes 'name' is already in lowercase. The code which uses it should be able to arrange this... + + while((start < end) && (*name != '\0')) + { + if(tolower(mCookie[start]) != *name) + return false; + + start++; + name++; + } + + // iff both strings hit the end at the same time, they're equal. + return ((start == end) && (*name == '\0')); +} + +std::string LLPluginCookieStore::getAllCookies() +{ + std::stringstream result; + writeAllCookies(result); + return result.str(); +} + +void LLPluginCookieStore::writeAllCookies(std::ostream& s) +{ + cookie_map_t::iterator iter; + for(iter = mCookies.begin(); iter != mCookies.end(); iter++) + { + // Don't return expired cookies + if(!iter->second->isDead()) + { + s << (iter->second->getCookie()) << "\n"; + } + } + +} + +std::string LLPluginCookieStore::getPersistentCookies() +{ + std::stringstream result; + writePersistentCookies(result); + return result.str(); +} + +void LLPluginCookieStore::writePersistentCookies(std::ostream& s) +{ + cookie_map_t::iterator iter; + for(iter = mCookies.begin(); iter != mCookies.end(); iter++) + { + // Don't return expired cookies or session cookies + if(!iter->second->isDead() && !iter->second->isSessionCookie()) + { + s << iter->second->getCookie() << "\n"; + } + } +} + +std::string LLPluginCookieStore::getChangedCookies(bool clear_changed) +{ + std::stringstream result; + writeChangedCookies(result, clear_changed); + + return result.str(); +} + +void LLPluginCookieStore::writeChangedCookies(std::ostream& s, bool clear_changed) +{ + if(mHasChangedCookies) + { + lldebugs << "returning changed cookies: " << llendl; + cookie_map_t::iterator iter; + for(iter = mCookies.begin(); iter != mCookies.end(); ) + { + cookie_map_t::iterator next = iter; + next++; + + // Only return cookies marked as "changed" + if(iter->second->isChanged()) + { + s << iter->second->getCookie() << "\n"; + + lldebugs << " " << iter->second->getCookie() << llendl; + + // If requested, clear the changed mark + if(clear_changed) + { + if(iter->second->isDead()) + { + // If this cookie was previously marked dead, it needs to be removed entirely. + delete iter->second; + mCookies.erase(iter); + } + else + { + // Not dead, just mark as not changed. + iter->second->setChanged(false); + } + } + } + + iter = next; + } + } + + if(clear_changed) + mHasChangedCookies = false; +} + +void LLPluginCookieStore::setAllCookies(const std::string &cookies, bool mark_changed) +{ + clearCookies(); + setCookies(cookies, mark_changed); +} + +void LLPluginCookieStore::readAllCookies(std::istream& s, bool mark_changed) +{ + clearCookies(); + readCookies(s, mark_changed); +} + +void LLPluginCookieStore::setCookies(const std::string &cookies, bool mark_changed) +{ + std::string::size_type start = 0; + + while(start != std::string::npos) + { + std::string::size_type end = cookies.find_first_of("\r\n", start); + if(end > start) + { + // The line is non-empty. Try to create a cookie from it. + setOneCookie(cookies, start, end, mark_changed); + } + start = cookies.find_first_not_of("\r\n ", end); + } +} + +void LLPluginCookieStore::setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed) +{ + std::string::size_type start = 0; + + while(start != std::string::npos) + { + std::string::size_type end = cookies.find_first_of("\r\n", start); + if(end > start) + { + // The line is non-empty. Try to create a cookie from it. + setOneCookie(cookies, start, end, mark_changed, host); + } + start = cookies.find_first_not_of("\r\n ", end); + } +} + +void LLPluginCookieStore::readCookies(std::istream& s, bool mark_changed) +{ + std::string line; + while(s.good() && !s.eof()) + { + std::getline(s, line); + if(!line.empty()) + { + // Try to create a cookie from this line. + setOneCookie(line, 0, std::string::npos, mark_changed); + } + } +} + +std::string LLPluginCookieStore::quoteString(const std::string &s) +{ + std::stringstream result; + + result << '"'; + + for(std::string::size_type i = 0; i < s.size(); ++i) + { + char c = s[i]; + switch(c) + { + // All these separators need to be quoted in HTTP headers, according to section 2.2 of rfc 2616: + case '(': case ')': case '<': case '>': case '@': + case ',': case ';': case ':': case '\\': case '"': + case '/': case '[': case ']': case '?': case '=': + case '{': case '}': case ' ': case '\t': + result << '\\'; + break; + } + + result << c; + } + + result << '"'; + + return result.str(); +} + +std::string LLPluginCookieStore::unquoteString(const std::string &s) +{ + std::stringstream result; + + bool in_quotes = false; + + for(std::string::size_type i = 0; i < s.size(); ++i) + { + char c = s[i]; + switch(c) + { + case '\\': + if(in_quotes) + { + // The next character is backslash-quoted. Pass it through untouched. + ++i; + if(i < s.size()) + { + result << s[i]; + } + continue; + } + break; + case '"': + in_quotes = !in_quotes; + continue; + break; + } + + result << c; + } + + return result.str(); +} + +// The flow for deleting a cookie is non-obvious enough that I should call it out here... +// Deleting a cookie is done by setting a cookie with the same name, path, and domain, but with an expire timestamp in the past. +// (This is exactly how a web server tells a browser to delete a cookie.) +// When deleting with mark_changed set to true, this replaces the existing cookie in the list with an entry that's marked both dead and changed. +// Some time later when writeChangedCookies() is called with clear_changed set to true, the dead cookie is deleted from the list after being returned, so that the +// delete operation (in the form of the expired cookie) is passed along. +void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host) +{ + Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end, host); + if(cookie) + { + LL_DEBUGS("CookieStoreUpdate") << "setting cookie: " << cookie->getCookie() << LL_ENDL; + + // Create a key for this cookie + std::string key = cookie->getKey(); + + // Check to see whether this cookie should have expired + if(!cookie->isSessionCookie() && (cookie->getDate() < LLDate::now())) + { + // This cookie has expired. + if(mark_changed) + { + // If we're marking cookies as changed, we should keep it anyway since we'll need to send it out with deltas. + cookie->setDead(true); + LL_DEBUGS("CookieStoreUpdate") << " marking dead" << LL_ENDL; + } + else + { + // If we're not marking cookies as changed, we don't need to keep this cookie at all. + // If the cookie was already in the list, delete it. + removeCookie(key); + + delete cookie; + cookie = NULL; + + LL_DEBUGS("CookieStoreUpdate") << " removing" << LL_ENDL; + } + } + + if(cookie) + { + // If it already exists in the map, replace it. + cookie_map_t::iterator iter = mCookies.find(key); + if(iter != mCookies.end()) + { + if(iter->second->getCookie() == cookie->getCookie()) + { + // The new cookie is identical to the old -- don't mark as changed. + // Just leave the old one in the map. + delete cookie; + cookie = NULL; + + LL_DEBUGS("CookieStoreUpdate") << " unchanged" << LL_ENDL; + } + else + { + // A matching cookie was already in the map. Replace it. + delete iter->second; + iter->second = cookie; + + cookie->setChanged(mark_changed); + if(mark_changed) + mHasChangedCookies = true; + + LL_DEBUGS("CookieStoreUpdate") << " replacing" << LL_ENDL; + } + } + else + { + // The cookie wasn't in the map. Insert it. + mCookies.insert(std::make_pair(key, cookie)); + + cookie->setChanged(mark_changed); + if(mark_changed) + mHasChangedCookies = true; + + LL_DEBUGS("CookieStoreUpdate") << " adding" << LL_ENDL; + } + } + } + else + { + LL_WARNS("CookieStoreUpdate") << "failed to parse cookie: " << s.substr(cookie_start, cookie_end - cookie_start) << LL_ENDL; + } + +} + +void LLPluginCookieStore::clearCookies() +{ + while(!mCookies.empty()) + { + cookie_map_t::iterator iter = mCookies.begin(); + delete iter->second; + mCookies.erase(iter); + } +} + +void LLPluginCookieStore::removeCookie(const std::string &key) +{ + cookie_map_t::iterator iter = mCookies.find(key); + if(iter != mCookies.end()) + { + delete iter->second; + mCookies.erase(iter); + } +} + diff --git a/linden/indra/llplugin/llplugincookiestore.h b/linden/indra/llplugin/llplugincookiestore.h new file mode 100644 index 000000000..69f0cf130 --- /dev/null +++ b/linden/indra/llplugin/llplugincookiestore.h @@ -0,0 +1,127 @@ +/** + * @file llplugincookiestore.h + * @brief LLPluginCookieStore provides central storage for http cookies used by plugins + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +#ifndef LL_LLPLUGINCOOKIESTORE_H +#define LL_LLPLUGINCOOKIESTORE_H + +#include "lldate.h" +#include <map> +#include <string> +#include <iostream> + +class LLPluginCookieStore +{ + LOG_CLASS(LLPluginCookieStore); +public: + LLPluginCookieStore(); + ~LLPluginCookieStore(); + + // gets all cookies currently in storage -- use when initializing a plugin + std::string getAllCookies(); + void writeAllCookies(std::ostream& s); + + // gets only persistent cookies (i.e. not session cookies) -- use when writing cookies to a file + std::string getPersistentCookies(); + void writePersistentCookies(std::ostream& s); + + // gets cookies which are marked as "changed" -- use when sending periodic updates to plugins + std::string getChangedCookies(bool clear_changed = true); + void writeChangedCookies(std::ostream& s, bool clear_changed = true); + + // (re)initializes internal data structures and bulk-sets cookies -- use when reading cookies from a file + void setAllCookies(const std::string &cookies, bool mark_changed = false); + void readAllCookies(std::istream& s, bool mark_changed = false); + + // sets one or more cookies (without reinitializing anything) -- use when receiving cookies from a plugin + void setCookies(const std::string &cookies, bool mark_changed = true); + void readCookies(std::istream& s, bool mark_changed = true); + + // sets one or more cookies (without reinitializing anything), supplying a hostname the cookies came from -- use when setting a cookie manually + void setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed = true); + + // quote or unquote a string as per the definition of 'quoted-string' in rfc2616 + static std::string quoteString(const std::string &s); + static std::string unquoteString(const std::string &s); + +private: + + void setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host = LLStringUtil::null); + + class Cookie + { + public: + static Cookie *createFromString(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos, const std::string &host = LLStringUtil::null); + + // Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map. + std::string getKey() const; + + const std::string &getCookie() const { return mCookie; }; + bool isSessionCookie() const { return mDate.isNull(); }; + + bool isDead() const { return mDead; }; + void setDead(bool dead) { mDead = dead; }; + + bool isChanged() const { return mChanged; }; + void setChanged(bool changed) { mChanged = changed; }; + + const LLDate &getDate() const { return mDate; }; + + private: + Cookie(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos); + bool parse(const std::string &host); + std::string::size_type findFieldEnd(std::string::size_type start = 0, std::string::size_type end = std::string::npos); + bool matchName(std::string::size_type start, std::string::size_type end, const char *name); + + std::string mCookie; // The full cookie, in RFC 2109 string format + LLDate mDate; // The expiration date of the cookie. For session cookies, this will be a null date (mDate.isNull() is true). + // Start/end indices of various parts of the cookie string. Stored as indices into the string to save space and time. + std::string::size_type mNameStart, mNameEnd; + std::string::size_type mValueStart, mValueEnd; + std::string::size_type mDomainStart, mDomainEnd; + std::string::size_type mPathStart, mPathEnd; + bool mDead; + bool mChanged; + }; + + typedef std::map<std::string, Cookie*> cookie_map_t; + + cookie_map_t mCookies; + bool mHasChangedCookies; + + void clearCookies(); + void removeCookie(const std::string &key); +}; + +#endif // LL_LLPLUGINCOOKIESTORE_H diff --git a/linden/indra/llplugin/llpluginmessagepipe.cpp b/linden/indra/llplugin/llpluginmessagepipe.cpp index b16381c48..8168b32c4 100755 --- a/linden/indra/llplugin/llpluginmessagepipe.cpp +++ b/linden/indra/llplugin/llpluginmessagepipe.cpp @@ -98,11 +98,14 @@ void LLPluginMessagePipeOwner::killMessagePipe(void) } } -LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket) +LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): + mInputMutex(gAPRPoolp), + mOutputMutex(gAPRPoolp), + mOwner(owner), + mSocket(socket) { - mOwner = owner; + mOwner->setMessagePipe(this); - mSocket = socket; } LLPluginMessagePipe::~LLPluginMessagePipe() @@ -116,6 +119,7 @@ LLPluginMessagePipe::~LLPluginMessagePipe() bool LLPluginMessagePipe::addMessage(const std::string &message) { // queue the message for later output + LLMutexLock lock(&mOutputMutex); mOutput += message; mOutput += MESSAGE_DELIMITER; // message separator @@ -150,6 +154,18 @@ void LLPluginMessagePipe::setSocketTimeout(apr_interval_time_t timeout_usec) } bool LLPluginMessagePipe::pump(F64 timeout) +{ + bool result = pumpOutput(); + + if(result) + { + result = pumpInput(timeout); + } + + return result; +} + +bool LLPluginMessagePipe::pumpOutput() { bool result = true; @@ -158,6 +174,7 @@ bool LLPluginMessagePipe::pump(F64 timeout) apr_status_t status; apr_size_t size; + LLMutexLock lock(&mOutputMutex); if(!mOutput.empty()) { // write any outgoing messages @@ -185,6 +202,17 @@ bool LLPluginMessagePipe::pump(F64 timeout) // remove the written part from the buffer and try again later. mOutput = mOutput.substr(size); } + else if(APR_STATUS_IS_EOF(status)) + { + // This is what we normally expect when a plugin exits. + llinfos << "Got EOF from plugin socket. " << llendl; + + if(mOwner) + { + mOwner->socketError(status); + } + result = false; + } else { // some other error @@ -198,6 +226,19 @@ bool LLPluginMessagePipe::pump(F64 timeout) result = false; } } + } + + return result; +} + +bool LLPluginMessagePipe::pumpInput(F64 timeout) +{ + bool result = true; + + if(mSocket) + { + apr_status_t status; + apr_size_t size; // FIXME: For some reason, the apr timeout stuff isn't working properly on windows. // Until such time as we figure out why, don't try to use the socket timeout -- just sleep here instead. @@ -218,8 +259,16 @@ bool LLPluginMessagePipe::pump(F64 timeout) char input_buf[1024]; apr_size_t request_size; - // Start out by reading one byte, so that any data received will wake us up. - request_size = 1; + if(timeout == 0.0f) + { + // If we have no timeout, start out with a full read. + request_size = sizeof(input_buf); + } + else + { + // Start out by reading one byte, so that any data received will wake us up. + request_size = 1; + } // and use the timeout so we'll sleep if no data is available. setSocketTimeout((apr_interval_time_t)(timeout * 1000000)); @@ -238,11 +287,14 @@ bool LLPluginMessagePipe::pump(F64 timeout) // LL_INFOS("Plugin") << "after apr_socket_recv, size = " << size << LL_ENDL; if(size > 0) + { + LLMutexLock lock(&mInputMutex); mInput.append(input_buf, size); + } if(status == APR_SUCCESS) { -// llinfos << "success, read " << size << llendl; + LL_DEBUGS("PluginSocket") << "success, read " << size << LL_ENDL; if(size != request_size) { @@ -252,16 +304,28 @@ bool LLPluginMessagePipe::pump(F64 timeout) } else if(APR_STATUS_IS_TIMEUP(status)) { -// llinfos << "TIMEUP, read " << size << llendl; + LL_DEBUGS("PluginSocket") << "TIMEUP, read " << size << LL_ENDL; // Timeout was hit. Since the initial read is 1 byte, this should never be a partial read. break; } else if(APR_STATUS_IS_EAGAIN(status)) { -// llinfos << "EAGAIN, read " << size << llendl; + LL_DEBUGS("PluginSocket") << "EAGAIN, read " << size << LL_ENDL; - // We've been doing partial reads, and we're done now. + // Non-blocking read returned immediately. + break; + } + else if(APR_STATUS_IS_EOF(status)) + { + // This is what we normally expect when a plugin exits. + LL_INFOS("PluginSocket") << "Got EOF from plugin socket. " << LL_ENDL; + + if(mOwner) + { + mOwner->socketError(status); + } + result = false; break; } else @@ -278,22 +342,18 @@ bool LLPluginMessagePipe::pump(F64 timeout) break; } - // Second and subsequent reads should not use the timeout - setSocketTimeout(0); - // and should try to fill the input buffer - request_size = sizeof(input_buf); + if(timeout != 0.0f) + { + // Second and subsequent reads should not use the timeout + setSocketTimeout(0); + // and should try to fill the input buffer + request_size = sizeof(input_buf); + } } processInput(); } } - - if(!result) - { - // If we got an error, we're done. - LL_INFOS("Plugin") << "Error from socket, cleaning up." << LL_ENDL; - delete this; - } return result; } @@ -301,26 +361,27 @@ bool LLPluginMessagePipe::pump(F64 timeout) void LLPluginMessagePipe::processInput(void) { // Look for input delimiter(s) in the input buffer. - int start = 0; int delim; - while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos) + mInputMutex.lock(); + while((delim = mInput.find(MESSAGE_DELIMITER)) != std::string::npos) { // Let the owner process this message if (mOwner) { - mOwner->receiveMessageRaw(mInput.substr(start, delim - start)); + // Pull the message out of the input buffer before calling receiveMessageRaw. + // It's now possible for this function to get called recursively (in the case where the plugin makes a blocking request) + // and this guarantees that the messages will get dequeued correctly. + std::string message(mInput, 0, delim); + mInput.erase(0, delim + 1); + mInputMutex.unlock(); + mOwner->receiveMessageRaw(message); + mInputMutex.lock(); } else { LL_WARNS("Plugin") << "!mOwner" << LL_ENDL; } - - start = delim + 1; } - - // Remove delivered messages from the input buffer. - if(start != 0) - mInput = mInput.substr(start); - + mInputMutex.unlock(); } diff --git a/linden/indra/llplugin/llpluginmessagepipe.h b/linden/indra/llplugin/llpluginmessagepipe.h index 8f74f38f8..6eedca27f 100755 --- a/linden/indra/llplugin/llpluginmessagepipe.h +++ b/linden/indra/llplugin/llpluginmessagepipe.h @@ -37,6 +37,7 @@ #define LL_LLPLUGINMESSAGEPIPE_H #include "lliosocket.h" +#include "llthread.h" class LLPluginMessagePipe; @@ -53,7 +54,7 @@ class LLPluginMessagePipeOwner virtual apr_status_t socketError(apr_status_t error); // called from LLPluginMessagePipe to manage the connection with LLPluginMessagePipeOwner -- do not use! - virtual void setMessagePipe(LLPluginMessagePipe *message_pipe) ; + virtual void setMessagePipe(LLPluginMessagePipe *message_pipe); protected: // returns false if writeMessageRaw() would drop the message @@ -78,14 +79,18 @@ class LLPluginMessagePipe void clearOwner(void); bool pump(F64 timeout = 0.0f); - + bool pumpOutput(); + bool pumpInput(F64 timeout = 0.0f); + protected: void processInput(void); // used internally by pump() void setSocketTimeout(apr_interval_time_t timeout_usec); + LLMutex mInputMutex; std::string mInput; + LLMutex mOutputMutex; std::string mOutput; LLPluginMessagePipeOwner *mOwner; diff --git a/linden/indra/llplugin/llpluginprocesschild.cpp b/linden/indra/llplugin/llpluginprocesschild.cpp index 0b7ce3db4..8dbf2b3e9 100755 --- a/linden/indra/llplugin/llpluginprocesschild.cpp +++ b/linden/indra/llplugin/llpluginprocesschild.cpp @@ -50,6 +50,8 @@ LLPluginProcessChild::LLPluginProcessChild() mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz mCPUElapsed = 0.0f; + mBlockingRequest = false; + mBlockingResponseReceived = false; } LLPluginProcessChild::~LLPluginProcessChild() @@ -85,9 +87,14 @@ void LLPluginProcessChild::idle(void) bool idle_again; do { - if(mSocketError != APR_SUCCESS) + if(APR_STATUS_IS_EOF(mSocketError)) { - LL_INFOS("Plugin") << "message pipe is in error state, moving to STATE_ERROR"<< LL_ENDL; + // Plugin socket was closed. This covers both normal plugin termination and host crashes. + setState(STATE_ERROR); + } + else if(mSocketError != APR_SUCCESS) + { + LL_INFOS("Plugin") << "message pipe is in error state (" << mSocketError << "), moving to STATE_ERROR"<< LL_ENDL; setState(STATE_ERROR); } @@ -228,6 +235,7 @@ void LLPluginProcessChild::idle(void) void LLPluginProcessChild::sleep(F64 seconds) { + deliverQueuedMessages(); if(mMessagePipe) { mMessagePipe->pump(seconds); @@ -240,6 +248,7 @@ void LLPluginProcessChild::sleep(F64 seconds) void LLPluginProcessChild::pump(void) { + deliverQueuedMessages(); if(mMessagePipe) { mMessagePipe->pump(0.0f); @@ -311,15 +320,32 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) LL_DEBUGS("Plugin") << "Received from parent: " << message << LL_ENDL; + // Decode this message + LLPluginMessage parsed; + parsed.parse(message); + + if(mBlockingRequest) + { + // We're blocking the plugin waiting for a response. + + if(parsed.hasValue("blocking_response")) + { + // This is the message we've been waiting for -- fall through and send it immediately. + mBlockingResponseReceived = true; + } + else + { + // Still waiting. Queue this message and don't process it yet. + mMessageQueue.push(message); + return; + } + } + bool passMessage = true; // FIXME: how should we handle queueing here? { - // Decode this message - LLPluginMessage parsed; - parsed.parse(message); - std::string message_class = parsed.getClass(); if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) { @@ -427,7 +453,13 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) void LLPluginProcessChild::receivePluginMessage(const std::string &message) { LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL; - + + if(mBlockingRequest) + { + // + LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL; + } + // Incoming message from the plugin instance bool passMessage = true; @@ -438,6 +470,12 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message) // Decode this message LLPluginMessage parsed; parsed.parse(message); + + if(parsed.hasValue("blocking_request")) + { + mBlockingRequest = true; + } + std::string message_class = parsed.getClass(); if(message_class == "base") { @@ -496,6 +534,19 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message) LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL; writeMessageRaw(message); } + + while(mBlockingRequest) + { + // The plugin wants to block and wait for a response to this message. + sleep(mSleepTime); // this will pump the message pipe and process messages + + if(mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL)) + { + // Response has been received, or we've hit an error state. Stop waiting. + mBlockingRequest = false; + mBlockingResponseReceived = false; + } + } } @@ -504,3 +555,15 @@ void LLPluginProcessChild::setState(EState state) LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; mState = state; }; + +void LLPluginProcessChild::deliverQueuedMessages() +{ + if(!mBlockingRequest) + { + while(!mMessageQueue.empty()) + { + receiveMessageRaw(mMessageQueue.front()); + mMessageQueue.pop(); + } + } +} diff --git a/linden/indra/llplugin/llpluginprocesschild.h b/linden/indra/llplugin/llpluginprocesschild.h index 96ae7b491..5d643d792 100755 --- a/linden/indra/llplugin/llpluginprocesschild.h +++ b/linden/indra/llplugin/llpluginprocesschild.h @@ -36,6 +36,8 @@ #ifndef LL_LLPLUGINPROCESSCHILD_H #define LL_LLPLUGINPROCESSCHILD_H +#include <queue> //imprudence + #include "llpluginmessage.h" #include "llpluginmessagepipe.h" #include "llplugininstance.h" @@ -108,6 +110,11 @@ class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInst LLTimer mHeartbeat; F64 mSleepTime; F64 mCPUElapsed; + bool mBlockingRequest; + bool mBlockingResponseReceived; + std::queue<std::string> mMessageQueue; + + void deliverQueuedMessages(); }; diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp index 8ea28f19e..1bf34c5c4 100755 --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp @@ -47,8 +47,51 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() } -LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) +bool LLPluginProcessParent::sUseReadThread = false; +apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; +bool LLPluginProcessParent::sPollsetNeedsRebuild = false; +LLMutex *LLPluginProcessParent::sInstancesMutex; +std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; +LLThread *LLPluginProcessParent::sReadThread = NULL; + + +class LLPluginProcessParentPollThread: public LLThread { +public: + LLPluginProcessParentPollThread() : + LLThread("LLPluginProcessParentPollThread", gAPRPoolp) + { + } +protected: + // Inherited from LLThread + /*virtual*/ void run(void) + { + while(!isQuitting() && LLPluginProcessParent::getUseReadThread()) + { + LLPluginProcessParent::poll(0.1f); + checkPause(); + } + + // Final poll to clean up the pollset, etc. + LLPluginProcessParent::poll(0.0f); + } + + // Inherited from LLThread + /*virtual*/ bool runCondition(void) + { + return(LLPluginProcessParent::canPollThreadRun()); + } + +}; + +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): + mIncomingQueueMutex(gAPRPoolp) +{ + if(!sInstancesMutex) + { + sInstancesMutex = new LLMutex(gAPRPoolp); + } + mOwner = owner; mBoundPort = 0; mState = STATE_UNINITIALIZED; @@ -56,18 +99,38 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) mCPUUsage = 0.0; mDisableTimeout = false; mDebug = false; + mBlocked = false; + mPolledInput = false; + mPollFD.client_data = NULL; mPluginLaunchTimeout = 60.0f; mPluginLockupTimeout = 15.0f; // Don't start the timer here -- start it when we actually launch the plugin process. mHeartbeat.stop(); + + + // Don't add to the global list until fully constructed. + { + LLMutexLock lock(sInstancesMutex); + sInstances.push_back(this); + } } LLPluginProcessParent::~LLPluginProcessParent() { LL_DEBUGS("Plugin") << "destructor" << LL_ENDL; + // Remove from the global list before beginning destruction. + { + // Make sure to get the global mutex _first_ here, to avoid a possible deadlock against LLPluginProcessParent::poll() + LLMutexLock lock(sInstancesMutex); + { + LLMutexLock lock2(&mIncomingQueueMutex); + sInstances.remove(this); + } + } + // Destroy any remaining shared memory regions sharedMemoryRegionsType::iterator iter; while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end()) @@ -79,15 +142,17 @@ LLPluginProcessParent::~LLPluginProcessParent() mSharedMemoryRegions.erase(iter); } - // orphaning the process means it won't be killed when the LLProcessLauncher is destructed. - // This is what we want -- it should exit cleanly once it notices the sockets have been closed. - mProcess.orphan(); + mProcess.kill(); killSockets(); } void LLPluginProcessParent::killSockets(void) { - killMessagePipe(); + { + LLMutexLock lock(&mIncomingQueueMutex); + killMessagePipe(); + } + mListenSocket.reset(); mSocket.reset(); } @@ -161,21 +226,47 @@ void LLPluginProcessParent::idle(void) do { + // process queued messages + mIncomingQueueMutex.lock(); + while(!mIncomingQueue.empty()) + { + LLPluginMessage message = mIncomingQueue.front(); + mIncomingQueue.pop(); + mIncomingQueueMutex.unlock(); + + receiveMessage(message); + + mIncomingQueueMutex.lock(); + } + + mIncomingQueueMutex.unlock(); + // Give time to network processing if(mMessagePipe) { - if(!mMessagePipe->pump()) + // Drain any queued outgoing messages + mMessagePipe->pumpOutput(); + + // Only do input processing here if this instance isn't in a pollset. + if(!mPolledInput) { -// LL_WARNS("Plugin") << "Message pipe hit an error state" << LL_ENDL; - errorState(); + mMessagePipe->pumpInput(); } } - - if((mSocketError != APR_SUCCESS) && (mState <= STATE_RUNNING)) + + if(mState <= STATE_RUNNING) { - // The socket is in an error state -- the plugin is gone. - LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; - errorState(); + if(APR_STATUS_IS_EOF(mSocketError)) + { + // Plugin socket was closed. This covers both normal plugin termination and plugin crashes. + errorState(); + } + else if(mSocketError != APR_SUCCESS) + { + // The socket is in an error state -- the plugin is gone. + LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; + errorState(); + } } // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). @@ -356,7 +447,7 @@ void LLPluginProcessParent::idle(void) break; case STATE_HELLO: - LL_DEBUGS("Plugin") << "received hello message" << llendl; + LL_DEBUGS("Plugin") << "received hello message" << LL_ENDL; // Send the message to load the plugin { @@ -390,7 +481,7 @@ void LLPluginProcessParent::idle(void) } else if(pluginLockedUp()) { - LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << llendl; + LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << LL_ENDL; errorState(); } break; @@ -412,8 +503,7 @@ void LLPluginProcessParent::idle(void) break; case STATE_CLEANUP: - // Don't do a kill here anymore -- closing the sockets is the new 'kill'. - mProcess.orphan(); + mProcess.kill(); killSockets(); setState(STATE_DONE); break; @@ -481,23 +571,323 @@ void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send) void LLPluginProcessParent::sendMessage(const LLPluginMessage &message) { + if(message.hasValue("blocking_response")) + { + mBlocked = false; + + // reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked. + mHeartbeat.setTimerExpirySec(mPluginLockupTimeout); + } std::string buffer = message.generate(); LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL; writeMessageRaw(buffer); + + // Try to send message immediately. + if(mMessagePipe) + { + mMessagePipe->pumpOutput(); + } +} + +//virtual +void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) +{ + bool update_pollset = false; + + if(mMessagePipe) + { + // Unsetting an existing message pipe -- remove from the pollset + mPollFD.client_data = NULL; + + // pollset needs an update + update_pollset = true; + } + if(message_pipe != NULL) + { + // Set up the apr_pollfd_t + mPollFD.p = gAPRPoolp; + mPollFD.desc_type = APR_POLL_SOCKET; + mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; + mPollFD.rtnevents = 0; + mPollFD.desc.s = mSocket->getSocket(); + mPollFD.client_data = (void*)this; + + // pollset needs an update + update_pollset = true; + } + + mMessagePipe = message_pipe; + + if(update_pollset) + { + dirtyPollSet(); + } +} + +//static +void LLPluginProcessParent::dirtyPollSet() +{ + sPollsetNeedsRebuild = true; + + if(sReadThread) + { + LL_DEBUGS("PluginPoll") << "unpausing read thread " << LL_ENDL; + sReadThread->unpause(); + } +} + +void LLPluginProcessParent::updatePollset() +{ + if(!sInstancesMutex) + { + // No instances have been created yet. There's no work to do. + return; + } + + LLMutexLock lock(sInstancesMutex); + + if(sPollSet) + { + LL_DEBUGS("PluginPoll") << "destroying pollset " << sPollSet << LL_ENDL; + // delete the existing pollset. + apr_pollset_destroy(sPollSet); + sPollSet = NULL; + } + + std::list<LLPluginProcessParent*>::iterator iter; + int count = 0; + + // Count the number of instances that want to be in the pollset + for(iter = sInstances.begin(); iter != sInstances.end(); iter++) + { + (*iter)->mPolledInput = false; + if((*iter)->mPollFD.client_data) + { + // This instance has a socket that needs to be polled. + ++count; + } + } + + if(sUseReadThread && sReadThread && !sReadThread->isQuitting()) + { + if(!sPollSet && (count > 0)) + { +#ifdef APR_POLLSET_NOCOPY + // The pollset doesn't exist yet. Create it now. + apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); + if(status != APR_SUCCESS) + { +#endif // APR_POLLSET_NOCOPY + LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; + sPollSet = NULL; +#ifdef APR_POLLSET_NOCOPY + } + else + { + LL_DEBUGS("PluginPoll") << "created pollset " << sPollSet << LL_ENDL; + + // Pollset was created, add all instances to it. + for(iter = sInstances.begin(); iter != sInstances.end(); iter++) + { + if((*iter)->mPollFD.client_data) + { + status = apr_pollset_add(sPollSet, &((*iter)->mPollFD)); + if(status == APR_SUCCESS) + { + (*iter)->mPolledInput = true; + } + else + { + LL_WARNS("PluginPoll") << "apr_pollset_add failed with status " << status << LL_ENDL; + } + } + } + } +#endif // APR_POLLSET_NOCOPY + } + } +} + +void LLPluginProcessParent::setUseReadThread(bool use_read_thread) +{ + if(sUseReadThread != use_read_thread) + { + sUseReadThread = use_read_thread; + + if(sUseReadThread) + { + if(!sReadThread) + { + // start up the read thread + LL_INFOS("PluginPoll") << "creating read thread " << LL_ENDL; + + // make sure the pollset gets rebuilt. + sPollsetNeedsRebuild = true; + + sReadThread = new LLPluginProcessParentPollThread; + sReadThread->start(); + } + } + else + { + if(sReadThread) + { + // shut down the read thread + LL_INFOS("PluginPoll") << "destroying read thread " << LL_ENDL; + delete sReadThread; + sReadThread = NULL; + } + } + + } +} + +void LLPluginProcessParent::poll(F64 timeout) +{ + if(sPollsetNeedsRebuild || !sUseReadThread) + { + sPollsetNeedsRebuild = false; + updatePollset(); + } + + if(sPollSet) + { + apr_status_t status; + apr_int32_t count; + const apr_pollfd_t *descriptors; + status = apr_pollset_poll(sPollSet, (apr_interval_time_t)(timeout * 1000000), &count, &descriptors); + if(status == APR_SUCCESS) + { + // One or more of the descriptors signalled. Call them. + for(int i = 0; i < count; i++) + { + LLPluginProcessParent *self = (LLPluginProcessParent *)(descriptors[i].client_data); + // NOTE: the descriptor returned here is actually a COPY of the original (even though we create the pollset with APR_POLLSET_NOCOPY). + // This means that even if the parent has set its mPollFD.client_data to NULL, the old pointer may still there in this descriptor. + // It's even possible that the old pointer no longer points to a valid LLPluginProcessParent. + // This means that we can't safely dereference the 'self' pointer here without some extra steps... + if(self) + { + // Make sure this pointer is still in the instances list + bool valid = false; + { + LLMutexLock lock(sInstancesMutex); + for(std::list<LLPluginProcessParent*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + { + if(*iter == self) + { + // Lock the instance's mutex before unlocking the global mutex. + // This avoids a possible race condition where the instance gets deleted between this check and the servicePoll() call. + self->mIncomingQueueMutex.lock(); + valid = true; + break; + } + } + } + + if(valid) + { + // The instance is still valid. + // Pull incoming messages off the socket + self->servicePoll(); + self->mIncomingQueueMutex.unlock(); + } + else + { + LL_DEBUGS("PluginPoll") << "detected deleted instance " << self << LL_ENDL; + } + + } + } + } + else if(APR_STATUS_IS_TIMEUP(status)) + { + // timed out with no incoming data. Just return. + } + else if(status == EBADF) + { + // This happens when one of the file descriptors in the pollset is destroyed, which happens whenever a plugin's socket is closed. + // The pollset has been or will be recreated, so just return. + LL_DEBUGS("PluginPoll") << "apr_pollset_poll returned EBADF" << LL_ENDL; + } + else if(status != APR_SUCCESS) + { + LL_WARNS("PluginPoll") << "apr_pollset_poll failed with status " << status << LL_ENDL; + } + } } +void LLPluginProcessParent::servicePoll() +{ + bool result = true; + + // poll signalled on this object's socket. Try to process incoming messages. + if(mMessagePipe) + { + result = mMessagePipe->pumpInput(0.0f); + } + + if(!result) + { + // If we got a read error on input, remove this pipe from the pollset + apr_pollset_remove(sPollSet, &mPollFD); + + // and tell the code not to re-add it + mPollFD.client_data = NULL; + } +} void LLPluginProcessParent::receiveMessageRaw(const std::string &message) { LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL; - - // FIXME: should this go into a queue instead? LLPluginMessage parsed; if(parsed.parse(message) != -1) { - receiveMessage(parsed); + if(parsed.hasValue("blocking_request")) + { + mBlocked = true; + } + + if(mPolledInput) + { + // This is being called on the polling thread -- only do minimal processing/queueing. + receiveMessageEarly(parsed); + } + else + { + // This is not being called on the polling thread -- do full message processing at this time. + receiveMessage(parsed); + } + } +} + +void LLPluginProcessParent::receiveMessageEarly(const LLPluginMessage &message) +{ + // NOTE: this function will be called from the polling thread. It will be called with mIncomingQueueMutex _already locked_. + + bool handled = false; + + std::string message_class = message.getClass(); + if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL) + { + // no internal messages need to be handled early. + } + else + { + // Call out to the owner and see if they to reply + // TODO: Should this only happen when blocked? + if(mOwner != NULL) + { + handled = mOwner->receivePluginMessageEarly(message); + } + } + + if(!handled) + { + // any message that wasn't handled early needs to be queued. + mIncomingQueue.push(message); } } @@ -691,18 +1081,15 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit() { bool result = false; - if(!mDisableTimeout && !mDebug) + if(!mProcess.isRunning()) { - if(!mProcess.isRunning()) - { - LL_WARNS("Plugin") << "child exited" << llendl; - result = true; - } - else if(pluginLockedUp()) - { - LL_WARNS("Plugin") << "timeout" << llendl; - result = true; - } + LL_WARNS("Plugin") << "child exited" << LL_ENDL; + result = true; + } + else if(pluginLockedUp()) + { + LL_WARNS("Plugin") << "timeout" << LL_ENDL; + result = true; } return result; @@ -710,6 +1097,12 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit() bool LLPluginProcessParent::pluginLockedUp() { + if(mDisableTimeout || mDebug || mBlocked) + { + // Never time out a plugin process in these cases. + return false; + } + // If the timer is running and has expired, the plugin has locked up. return (mHeartbeat.getStarted() && mHeartbeat.hasExpired()); } diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h index 523ce510c..a8929b194 100755 --- a/linden/indra/llplugin/llpluginprocessparent.h +++ b/linden/indra/llplugin/llpluginprocessparent.h @@ -36,6 +36,8 @@ #ifndef LL_LLPLUGINPROCESSPARENT_H #define LL_LLPLUGINPROCESSPARENT_H +#include <queue> //imprudence + #include "llapr.h" #include "llprocesslauncher.h" #include "llpluginmessage.h" @@ -43,12 +45,14 @@ #include "llpluginsharedmemory.h" #include "lliosocket.h" +#include "llthread.h" class LLPluginProcessParentOwner { public: virtual ~LLPluginProcessParentOwner(); virtual void receivePluginMessage(const LLPluginMessage &message) = 0; + virtual bool receivePluginMessageEarly(const LLPluginMessage &message) {return false;}; // This will only be called when the plugin has died unexpectedly virtual void pluginLaunchFailed() {}; virtual void pluginDied() {}; @@ -76,6 +80,9 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner // returns true if the process has exited or we've had a fatal error bool isDone(void); + // returns true if the process is currently waiting on a blocking request + bool isBlocked(void) { return mBlocked; }; + void killSockets(void); // Go to the proper error state @@ -89,7 +96,9 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner void receiveMessage(const LLPluginMessage &message); // Inherited from LLPluginMessagePipeOwner - void receiveMessageRaw(const std::string &message); + /*virtual*/ void receiveMessageRaw(const std::string &message); + /*virtual*/ void receiveMessageEarly(const LLPluginMessage &message); + /*virtual*/ void setMessagePipe(LLPluginMessagePipe *message_pipe) ; // This adds a memory segment shared with the client, generating a name for the segment. The name generated is guaranteed to be unique on the host. // The caller must call removeSharedMemory first (and wait until getSharedMemorySize returns 0 for the indicated name) before re-adding a segment with the same name. @@ -112,7 +121,11 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner void setLockupTimeout(F32 timeout) { mPluginLockupTimeout = timeout; }; F64 getCPUUsage() { return mCPUUsage; }; - + + static void poll(F64 timeout); + static bool canPollThreadRun() { return (sPollSet || sPollsetNeedsRebuild || sUseReadThread); }; + static void setUseReadThread(bool use_read_thread); + static bool getUseReadThread() { return sUseReadThread; }; private: enum EState @@ -162,12 +175,27 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner bool mDisableTimeout; bool mDebug; + bool mBlocked; + bool mPolledInput; LLProcessLauncher mDebugger; F32 mPluginLaunchTimeout; // Somewhat longer timeout for initial launch. F32 mPluginLockupTimeout; // If we don't receive a heartbeat in this many seconds, we declare the plugin locked up. + static bool sUseReadThread; + apr_pollfd_t mPollFD; + static apr_pollset_t *sPollSet; + static bool sPollsetNeedsRebuild; + static LLMutex *sInstancesMutex; + static std::list<LLPluginProcessParent*> sInstances; + static void dirtyPollSet(); + static void updatePollset(); + void servicePoll(); + static LLThread *sReadThread; + + LLMutex mIncomingQueueMutex; + std::queue<LLPluginMessage> mIncomingQueue; }; #endif // LL_LLPLUGINPROCESSPARENT_H diff --git a/linden/indra/llplugin/slplugin/CMakeLists.txt b/linden/indra/llplugin/slplugin/CMakeLists.txt index 4a7d670c2..81d929969 100755 --- a/linden/indra/llplugin/slplugin/CMakeLists.txt +++ b/linden/indra/llplugin/slplugin/CMakeLists.txt @@ -16,6 +16,7 @@ include_directories( if (DARWIN) include(CMakeFindFrameworks) find_library(CARBON_LIBRARY Carbon) + find_library(COCOA_LIBRARY Cocoa) endif (DARWIN) @@ -25,11 +26,33 @@ set(SLPlugin_SOURCE_FILES slplugin.cpp ) +if (DARWIN) + list(APPEND SLPlugin_SOURCE_FILES + slplugin-objc.mm + ) + list(APPEND SLPlugin_HEADER_FILES + slplugin-objc.h + ) +endif (DARWIN) + +set_source_files_properties(${SLPlugin_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +if (SLPlugin_HEADER_FILES) + list(APPEND SLPlugin_SOURCE_FILES ${SLPlugin_HEADER_FILES}) +endif (SLPlugin_HEADER_FILES) + add_executable(SLPlugin WIN32 + MACOSX_BUNDLE ${SLPlugin_SOURCE_FILES} ) +set_target_properties(SLPlugin + PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist + ) + target_link_libraries(SLPlugin ${LLPLUGIN_LIBRARIES} ${LLMESSAGE_LIBRARIES} @@ -44,12 +67,16 @@ add_dependencies(SLPlugin ) if (DARWIN) - # Mac version needs to link against carbon, and also needs an embedded plist (to set LSBackgroundOnly) - target_link_libraries(SLPlugin ${CARBON_LIBRARY}) - set_target_properties( - SLPlugin - PROPERTIES - LINK_FLAGS "-Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist" + # Mac version needs to link against Carbon + target_link_libraries(SLPlugin ${CARBON_LIBRARY} ${COCOA_LIBRARY}) + # Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later) + add_custom_command( + TARGET SLPlugin POST_BUILD + COMMAND mkdir + ARGS + -p + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SLPlugin.app/Contents/Resources ) endif (DARWIN) +#ll_deploy_sharedlibs_command(SLPlugin) diff --git a/linden/indra/llplugin/slplugin/slplugin-objc.h b/linden/indra/llplugin/slplugin/slplugin-objc.h new file mode 100644 index 000000000..42029e45b --- /dev/null +++ b/linden/indra/llplugin/slplugin/slplugin-objc.h @@ -0,0 +1,42 @@ +/** + * @file slplugin-objc.h + * @brief Header file for slplugin-objc.mm. + * + * @cond + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * + * @endcond + */ + + +/* Defined in slplugin-objc.mm: */ +void setupCocoa(); +void createAutoReleasePool(); +void deleteAutoReleasePool(); diff --git a/linden/indra/llplugin/slplugin/slplugin-objc.mm b/linden/indra/llplugin/slplugin/slplugin-objc.mm new file mode 100644 index 000000000..125b26412 --- /dev/null +++ b/linden/indra/llplugin/slplugin/slplugin-objc.mm @@ -0,0 +1,89 @@ +/** + * @file slplugin-objc.mm + * @brief Objective-C++ file for use with the loader shell, so we can use a couple of Cocoa APIs. + * + * @cond + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * + * @endcond + */ + + +#include <AppKit/AppKit.h> + +#include "slplugin-objc.h" + + +void setupCocoa() +{ + static bool inited = false; + + if(!inited) + { + createAutoReleasePool(); + + // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. + // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' + // when init'ing the Cocoa App window. + [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; + + // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor": + // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html + + // Needed for Carbon based applications which call into Cocoa + NSApplicationLoad(); + + // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image + [[[NSWindow alloc] init] release]; + + deleteAutoReleasePool(); + + inited = true; + } +} + +static NSAutoreleasePool *sPool = NULL; + +void createAutoReleasePool() +{ + if(!sPool) + { + sPool = [[NSAutoreleasePool alloc] init]; + } +} + +void deleteAutoReleasePool() +{ + if(sPool) + { + [sPool release]; + sPool = NULL; + } +} diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp index 649d56847..64c087bec 100755 --- a/linden/indra/llplugin/slplugin/slplugin.cpp +++ b/linden/indra/llplugin/slplugin/slplugin.cpp @@ -46,6 +46,7 @@ #if LL_DARWIN #include <Carbon/Carbon.h> + #include "slplugin-objc.h" #endif #if LL_DARWIN || LL_LINUX @@ -53,7 +54,7 @@ #endif /* - On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly flag in the Info.plist. + On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly or LSUIElement flag in the Info.plist. Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags: @@ -62,7 +63,8 @@ which means adding this to the gcc flags: -Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist - + + Now that SLPlugin is a bundled app on the Mac, this is no longer necessary (it can just use a regular Info.plist file), but I'm leaving this comment in for posterity. */ #if LL_DARWIN || LL_LINUX @@ -230,10 +232,19 @@ int main(int argc, char **argv) signal(SIGSYS, &crash_handler); // non-existent system call invoked #endif +#if LL_DARWIN + setupCocoa(); + createAutoReleasePool(); +#endif + LLPluginProcessChild *plugin = new LLPluginProcessChild(); plugin->init(port); +#if LL_DARWIN + deleteAutoReleasePool(); +#endif + LLTimer timer; timer.start(); @@ -241,11 +252,29 @@ int main(int argc, char **argv) checkExceptionHandler(); #endif +#if LL_DARWIN + // If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground. + // Use this to track the current frontmost window and bring this process to the front if it changes. + WindowRef front_window = NULL; + WindowGroupRef layer_group = NULL; + int window_hack_state = 0; + CreateWindowGroup(kWindowGroupAttrFixedLevel, &layer_group); + if(layer_group) + { + // Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube) + SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer")); + SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel); + } +#endif + #if LL_DARWIN EventTargetRef event_target = GetEventDispatcherTarget(); #endif while(!plugin->isDone()) { +#if LL_DARWIN + createAutoReleasePool(); +#endif timer.reset(); plugin->idle(); #if LL_DARWIN @@ -257,6 +286,80 @@ int main(int argc, char **argv) SendEventToEventTarget (event, event_target); ReleaseEvent(event); } + + // Check for a change in this process's frontmost window. + if(FrontWindow() != front_window) + { + ProcessSerialNumber self = { 0, kCurrentProcess }; + ProcessSerialNumber parent = { 0, kNoProcess }; + ProcessSerialNumber front = { 0, kNoProcess }; + Boolean this_is_front_process = false; + Boolean parent_is_front_process = false; + { + // Get this process's parent + ProcessInfoRec info; + info.processInfoLength = sizeof(ProcessInfoRec); + info.processName = NULL; + info.processAppSpec = NULL; + if(GetProcessInformation( &self, &info ) == noErr) + { + parent = info.processLauncher; + } + + // and figure out whether this process or its parent are currently frontmost + if(GetFrontProcess(&front) == noErr) + { + (void) SameProcess(&self, &front, &this_is_front_process); + (void) SameProcess(&parent, &front, &parent_is_front_process); + } + } + + if((FrontWindow() != NULL) && (front_window == NULL)) + { + // Opening the first window + + if(window_hack_state == 0) + { + // Next time through the event loop, lower the window group layer + window_hack_state = 1; + } + + if(layer_group) + { + SetWindowGroup(FrontWindow(), layer_group); + } + + if(parent_is_front_process) + { + // Bring this process's windows to the front. + (void) SetFrontProcess( &self ); + } + + ActivateWindow(FrontWindow(), true); + } + else if((FrontWindow() == NULL) && (front_window != NULL)) + { + // Closing the last window + + if(this_is_front_process) + { + // Try to bring this process's parent to the front + (void) SetFrontProcess(&parent); + } + } + else if(window_hack_state == 1) + { + if(layer_group) + { + // Set the window group level back to something less extreme + SetWindowGroupLevel(layer_group, kCGNormalWindowLevel); + } + window_hack_state = 2; + } + + front_window = FrontWindow(); + + } } #endif F64 elapsed = timer.getElapsedTimeF64(); @@ -289,6 +392,10 @@ int main(int argc, char **argv) // exception handler such as QuickTime. //checkExceptionHandler(); #endif + +#if LL_DARWIN + deleteAutoReleasePool(); +#endif } delete plugin; diff --git a/linden/indra/llplugin/slplugin/slplugin_info.plist b/linden/indra/llplugin/slplugin/slplugin_info.plist index b1daf8742..c4597380e 100755 --- a/linden/indra/llplugin/slplugin/slplugin_info.plist +++ b/linden/indra/llplugin/slplugin/slplugin_info.plist @@ -6,7 +6,7 @@ <string>English</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> - <key>LSBackgroundOnly</key> - <true/> + <key>LSUIElement</key> + <string>1</string> </dict> </plist> diff --git a/linden/indra/media_plugins/webkit/CMakeLists.txt b/linden/indra/media_plugins/webkit/CMakeLists.txt index a47d5e015..2ab4a95fa 100644 --- a/linden/indra/media_plugins/webkit/CMakeLists.txt +++ b/linden/indra/media_plugins/webkit/CMakeLists.txt @@ -18,7 +18,7 @@ include(Linking) include(PluginAPI) include(MediaPluginBase) include(FindOpenGL) -#include(PulseAudio) +include(PulseAudio) include(WebKitLibPlugin) @@ -48,6 +48,9 @@ if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) add_definitions(-fPIC) endif(WINDOWS) endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) +set(media_plugin_webkit_HEADER_FILES + volume_catcher.h + ) set(media_plugin_webkit_LINK_LIBRARIES ${LLPLUGIN_LIBRARIES} @@ -58,13 +61,33 @@ set(media_plugin_webkit_LINK_LIBRARIES ${PULSEAUDIO_LIBRARIES} ) +# Select which VolumeCatcher implementation to use if (LINUX) - list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp) + if (PULSEAUDIO) + list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp) + endif (PULSEAUDIO) list(APPEND media_plugin_webkit_LINK_LIBRARIES - ${UI_LIBRARIES} # for glib/GTK - ) -endif(LINUX) - + ${UI_LIBRARIES} # for glib/GTK + ) +elseif (DARWIN) + list(APPEND media_plugin_webkit_SOURCE_FILES mac_volume_catcher.cpp) + find_library(CORESERVICES_LIBRARY CoreServices) + find_library(AUDIOUNIT_LIBRARY AudioUnit) + list(APPEND media_plugin_webkit_LINK_LIBRARIES + ${CORESERVICES_LIBRARY} # for Component Manager calls + ${AUDIOUNIT_LIBRARY} # for AudioUnit calls + ) +elseif (WINDOWS) + list(APPEND media_plugin_webkit_SOURCE_FILES windows_volume_catcher.cpp) +else (LINUX) + # All other platforms use the dummy volume catcher for now. + list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp) +endif (LINUX) + +set_source_files_properties(${media_plugin_webkit_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND media_plugin_webkit_SOURCE_FILES ${media_plugin_webkit_HEADER_FILES}) add_library(media_plugin_webkit SHARED diff --git a/linden/indra/media_plugins/webkit/dummy_volume_catcher.cpp b/linden/indra/media_plugins/webkit/dummy_volume_catcher.cpp new file mode 100644 index 000000000..4df988789 --- /dev/null +++ b/linden/indra/media_plugins/webkit/dummy_volume_catcher.cpp @@ -0,0 +1,65 @@ +/** + * @file dummy_volume_catcher.cpp + * @brief A null implementation of the "VolumeCatcher" class for platforms where it's not implemented yet. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +#include "volume_catcher.h" + + +class VolumeCatcherImpl +{ +}; + +///////////////////////////////////////////////////// + +VolumeCatcher::VolumeCatcher() +{ + pimpl = NULL; +} + +VolumeCatcher::~VolumeCatcher() +{ +} + +void VolumeCatcher::setVolume(F32 volume) +{ +} + +void VolumeCatcher::setPan(F32 pan) +{ +} + +void VolumeCatcher::pump() +{ +} + diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp old mode 100755 new mode 100644 index 15a2dfb1f..c4c4181a4 --- a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp +++ b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp @@ -42,15 +42,16 @@ 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call */ -#include "linden_common.h" +# include <set> //imprudence -#include "linux_volume_catcher.h" +#include "linden_common.h" +#include "volume_catcher.h" -#if LL_PULSEAUDIO_ENABLED extern "C" { #include <glib.h> +#include <glib-object.h> #include <pulse/introspect.h> #include <pulse/context.h> @@ -163,11 +164,11 @@ extern "C" { } -class LinuxVolumeCatcherImpl +class VolumeCatcherImpl { public: - LinuxVolumeCatcherImpl(); - ~LinuxVolumeCatcherImpl(); + VolumeCatcherImpl(); + ~VolumeCatcherImpl(); void setVolume(F32 volume); void pump(void); @@ -191,7 +192,7 @@ class LinuxVolumeCatcherImpl bool mGotSyms; }; -LinuxVolumeCatcherImpl::LinuxVolumeCatcherImpl() +VolumeCatcherImpl::VolumeCatcherImpl() : mDesiredVolume(0.0f), mMainloop(NULL), mPAContext(NULL), @@ -201,17 +202,17 @@ LinuxVolumeCatcherImpl::LinuxVolumeCatcherImpl() init(); } -LinuxVolumeCatcherImpl::~LinuxVolumeCatcherImpl() +VolumeCatcherImpl::~VolumeCatcherImpl() { cleanup(); } -bool LinuxVolumeCatcherImpl::loadsyms(std::string pulse_dso_name) +bool VolumeCatcherImpl::loadsyms(std::string pulse_dso_name) { return grab_pa_syms(pulse_dso_name); } -void LinuxVolumeCatcherImpl::init() +void VolumeCatcherImpl::init() { // try to be as defensive as possible because PA's interface is a // bit fragile and (for our purposes) we'd rather simply not function @@ -224,6 +225,10 @@ void LinuxVolumeCatcherImpl::init() mGotSyms = loadsyms("libpulse-mainloop-glib.so.0"); if (!mGotSyms) return; + // better make double-sure glib itself is initialized properly. + if (!g_thread_supported ()) g_thread_init (NULL); + g_type_init(); + mMainloop = llpa_glib_mainloop_new(g_main_context_default()); if (mMainloop) { @@ -264,7 +269,7 @@ void LinuxVolumeCatcherImpl::init() } } -void LinuxVolumeCatcherImpl::cleanup() +void VolumeCatcherImpl::cleanup() { mConnected = false; @@ -282,7 +287,7 @@ void LinuxVolumeCatcherImpl::cleanup() mMainloop = NULL; } -void LinuxVolumeCatcherImpl::setVolume(F32 volume) +void VolumeCatcherImpl::setVolume(F32 volume) { mDesiredVolume = volume; @@ -296,13 +301,13 @@ void LinuxVolumeCatcherImpl::setVolume(F32 volume) pump(); } -void LinuxVolumeCatcherImpl::pump() +void VolumeCatcherImpl::pump() { gboolean may_block = FALSE; g_main_context_iteration(g_main_context_default(), may_block); } -void LinuxVolumeCatcherImpl::connected_okay() +void VolumeCatcherImpl::connected_okay() { pa_operation *op; @@ -326,7 +331,7 @@ void LinuxVolumeCatcherImpl::connected_okay() } } -void LinuxVolumeCatcherImpl::update_all_volumes(F32 volume) +void VolumeCatcherImpl::update_all_volumes(F32 volume) { for (std::set<U32>::iterator it = mSinkInputIndices.begin(); it != mSinkInputIndices.end(); ++it) @@ -335,7 +340,7 @@ void LinuxVolumeCatcherImpl::update_all_volumes(F32 volume) } } -void LinuxVolumeCatcherImpl::update_index_volume(U32 index, F32 volume) +void VolumeCatcherImpl::update_index_volume(U32 index, F32 volume) { static pa_cvolume cvol; llpa_cvolume_set(&cvol, mSinkInputNumChannels[index], @@ -357,7 +362,7 @@ void LinuxVolumeCatcherImpl::update_index_volume(U32 index, F32 volume) void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata) { - LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata); llassert(impl); if (0 == eol) @@ -388,7 +393,7 @@ void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata) { - LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata); llassert(impl); switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { @@ -422,7 +427,7 @@ void callback_subscription_alert(pa_context *context, pa_subscription_event_type void callback_context_state(pa_context *context, void *userdata) { - LinuxVolumeCatcherImpl *impl = dynamic_cast<LinuxVolumeCatcherImpl*>((LinuxVolumeCatcherImpl*)userdata); + VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata); llassert(impl); switch (llpa_context_get_state(context)) @@ -443,48 +448,30 @@ void callback_context_state(pa_context *context, void *userdata) ///////////////////////////////////////////////////// -LinuxVolumeCatcher::LinuxVolumeCatcher() +VolumeCatcher::VolumeCatcher() { - pimpl = new LinuxVolumeCatcherImpl(); + pimpl = new VolumeCatcherImpl(); } -LinuxVolumeCatcher::~LinuxVolumeCatcher() +VolumeCatcher::~VolumeCatcher() { delete pimpl; pimpl = NULL; } -void LinuxVolumeCatcher::setVolume(F32 volume) +void VolumeCatcher::setVolume(F32 volume) { llassert(pimpl); pimpl->setVolume(volume); } -void LinuxVolumeCatcher::pump() -{ - llassert(pimpl); - pimpl->pump(); -} - -#else // !LL_PULSEAUDIO_ENABLED - -// stub. - -LinuxVolumeCatcher::LinuxVolumeCatcher() -{ - pimpl = NULL; -} - -LinuxVolumeCatcher::~LinuxVolumeCatcher() -{ -} - -void LinuxVolumeCatcher::setVolume(F32 volume) +void VolumeCatcher::setPan(F32 pan) { + // TODO: implement this (if possible) } -void LinuxVolumeCatcher::pump() +void VolumeCatcher::pump() { + llassert(pimpl); + pimpl->pump(); } - -#endif // LL_PULSEAUDIO_ENABLED diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/linden/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc old mode 100755 new mode 100644 diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc b/linden/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc old mode 100755 new mode 100644 diff --git a/linden/indra/media_plugins/webkit/mac_volume_catcher.cpp b/linden/indra/media_plugins/webkit/mac_volume_catcher.cpp new file mode 100644 index 000000000..190823f73 --- /dev/null +++ b/linden/indra/media_plugins/webkit/mac_volume_catcher.cpp @@ -0,0 +1,275 @@ +/** + * @file mac_volume_catcher.cpp + * @brief A Mac OS X specific hack to control the volume level of all audio channels opened by a process. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +/************************************************************************************************************** + This code works by using CaptureComponent to capture the "Default Output" audio component + (kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput) and delegating all calls to the original component. + It does this just to keep track of all instances of the default output component, so that it can set the + kHALOutputParam_Volume parameter on all of them to adjust the output volume. +**************************************************************************************************************/ + +#include "volume_catcher.h" + +#include <Carbon/Carbon.h> +#include <QuickTime/QuickTime.h> +#include <AudioUnit/AudioUnit.h> + +struct VolumeCatcherStorage; + +class VolumeCatcherImpl +{ +public: + + void setVolume(F32 volume); + void setPan(F32 pan); + + void setInstanceVolume(VolumeCatcherStorage *instance); + + std::list<VolumeCatcherStorage*> mComponentInstances; + Component mOriginalDefaultOutput; + Component mVolumeAdjuster; + + static VolumeCatcherImpl *getInstance(); +private: + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + VolumeCatcherImpl(); + static VolumeCatcherImpl *sInstance; + + // The singlar instance of this class is expected to last until the process exits. + // To ensure this, we declare the destructor here but never define it, so any code which attempts to destroy the instance will not link. + ~VolumeCatcherImpl(); + + F32 mVolume; + F32 mPan; +}; + +VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL;; + +struct VolumeCatcherStorage +{ + ComponentInstance self; + ComponentInstance delegate; +}; + +static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage); +static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self); +static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self); + +VolumeCatcherImpl *VolumeCatcherImpl::getInstance() +{ + if(!sInstance) + { + sInstance = new VolumeCatcherImpl; + } + + return sInstance; +} + +VolumeCatcherImpl::VolumeCatcherImpl() +{ + mVolume = 1.0; // default to full volume + mPan = 0.0; // and center pan + + ComponentDescription desc; + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + // Find the original default output component + mOriginalDefaultOutput = FindNextComponent(NULL, &desc); + + // Register our own output component with the same parameters + mVolumeAdjuster = RegisterComponent(&desc, NewComponentRoutineUPP(volume_catcher_component_entry), 0, NULL, NULL, NULL); + + // Capture the original component, so we always get found instead. + CaptureComponent(mOriginalDefaultOutput, mVolumeAdjuster); + +} + +static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage) +{ + ComponentResult result = badComponentSelector; + VolumeCatcherStorage *storage = (VolumeCatcherStorage*)componentStorage; + + switch(cp->what) + { + case kComponentOpenSelect: +// std::cerr << "kComponentOpenSelect" << std::endl; + result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_open, uppCallComponentOpenProcInfo); + break; + + case kComponentCloseSelect: +// std::cerr << "kComponentCloseSelect" << std::endl; + result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_close, uppCallComponentCloseProcInfo); + // CallComponentFunctionWithStorageProcInfo + break; + + default: +// std::cerr << "Delegating selector: " << cp->what << " to component instance " << storage->delegate << std::endl; + result = DelegateComponentCall(cp, storage->delegate); + break; + } + + return result; +} + +static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self) +{ + ComponentResult result = noErr; + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + + storage = new VolumeCatcherStorage; + + storage->self = self; + storage->delegate = NULL; + + result = OpenAComponent(impl->mOriginalDefaultOutput, &(storage->delegate)); + + if(result != noErr) + { +// std::cerr << "OpenAComponent result = " << result << ", component ref = " << storage->delegate << std::endl; + + // If we failed to open the delagate component, our open is going to fail. Clean things up. + delete storage; + } + else + { + // Success -- set up this component's storage + SetComponentInstanceStorage(self, (Handle)storage); + + // add this instance to the global list + impl->mComponentInstances.push_back(storage); + + // and set up the initial volume + impl->setInstanceVolume(storage); + } + + return result; +} + +static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self) +{ + ComponentResult result = noErr; + + if(storage) + { + if(storage->delegate) + { + CloseComponent(storage->delegate); + storage->delegate = NULL; + } + + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + impl->mComponentInstances.remove(storage); + delete[] storage; + } + + return result; +} + +void VolumeCatcherImpl::setVolume(F32 volume) +{ + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + impl->mVolume = volume; + + // Iterate through all known instances, setting the volume on each. + for(std::list<VolumeCatcherStorage*>::iterator iter = mComponentInstances.begin(); iter != mComponentInstances.end(); ++iter) + { + impl->setInstanceVolume(*iter); + } +} + +void VolumeCatcherImpl::setPan(F32 pan) +{ + VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance(); + impl->mPan = pan; + + // TODO: implement this. + // This will probably require adding a "panner" audio unit to the chain somehow. + // There's also a "3d mixer" component that we might be able to use... +} + +void VolumeCatcherImpl::setInstanceVolume(VolumeCatcherStorage *instance) +{ +// std::cerr << "Setting volume on component instance: " << (instance->delegate) << " to " << mVolume << std::endl; + + OSStatus err = noErr; + + if(instance && instance->delegate) + { + err = AudioUnitSetParameter( + instance->delegate, + kHALOutputParam_Volume, + kAudioUnitScope_Global, + 0, + mVolume, + 0); + } + + if(err) + { +// std::cerr << " AudioUnitSetParameter returned " << err << std::endl; + } +} + +///////////////////////////////////////////////////// + +VolumeCatcher::VolumeCatcher() +{ + pimpl = VolumeCatcherImpl::getInstance(); +} + +VolumeCatcher::~VolumeCatcher() +{ + // Let the instance persist until exit. +} + +void VolumeCatcher::setVolume(F32 volume) +{ + pimpl->setVolume(volume); +} + +void VolumeCatcher::setPan(F32 pan) +{ + pimpl->setPan(pan); +} + +void VolumeCatcher::pump() +{ + // No periodic tasks are necessary for this implementation. +} + diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index 09ba8dc21..f9b645111 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -49,13 +49,15 @@ #if LL_LINUX # include <iomanip> # define LL_QTWEBKIT_USES_PIXMAPS 0 +extern "C" { +# include <glib.h> +# include <glib-object.h> +} #else # define LL_QTWEBKIT_USES_PIXMAPS 0 #endif // LL_LINUX -#if LL_LINUX -# include "linux_volume_catcher.h" -#endif // LL_LINUX +# include "volume_catcher.h" #if LL_WINDOWS # include <direct.h> @@ -65,7 +67,7 @@ #endif #if LL_WINDOWS - // *NOTE:Mani - This captures the module handle fo rthe dll. This is used below + // *NOTE:Mani - This captures the module handle for the dll. This is used below // to get the path to this dll for webkit initialization. // I don't know how/if this can be done with apr... namespace { HMODULE gModuleHandle;}; @@ -122,9 +124,7 @@ class MediaPluginWebKit : F32 mBackgroundG; F32 mBackgroundB; -#if LL_LINUX - LinuxVolumeCatcher mLinuxVolumeCatcher; -#endif // LL_LINUX + VolumeCatcher mVolumeCatcher; void setInitState(int state) { @@ -136,11 +136,19 @@ class MediaPluginWebKit : // void update(int milliseconds) { +#if LL_QTLINUX_DOESNT_HAVE_GLIB + // pump glib generously, as Linux browser plugins are on the + // glib main loop, even if the browser itself isn't - ugh + // This is NOT NEEDED if Qt itself was built with glib + // mainloop integration. + GMainContext *mainc = g_main_context_default(); + while(g_main_context_iteration(mainc, FALSE)); +#endif // LL_QTLINUX_DOESNT_HAVE_GLIB + + // pump qt LLQtWebKit::getInstance()->pump( milliseconds ); -#if LL_LINUX - mLinuxVolumeCatcher.pump(); -#endif // LL_LINUX + mVolumeCatcher.pump(); checkEditState(); @@ -209,6 +217,14 @@ class MediaPluginWebKit : } std::string application_dir = std::string( cwd ); +#if LL_LINUX + // take care to initialize glib properly, because some + // versions of Qt don't, and we indirectly need it for (some + // versions of) Flash to not crash the browser. + if (!g_thread_supported ()) g_thread_init (NULL); + g_type_init(); +#endif + #if LL_DARWIN // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on. // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger. @@ -306,11 +322,14 @@ class MediaPluginWebKit : // append details to agent string LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); + // Set up window open behavior + LLQtWebKit::getInstance()->setWindowOpenBehavior(mBrowserWindowId, LLQtWebKit::WOB_SIMULATE_BLANK_HREF_CLICK); + #if !LL_QTWEBKIT_USES_PIXMAPS // don't flip bitmap LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); #endif // !LL_QTWEBKIT_USES_PIXMAPS - + // set background color // convert background color channels from [0.0, 1.0] to [0, 255]; LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) ); @@ -511,6 +530,19 @@ class MediaPluginWebKit : sendMessage(message); } + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onCookieChanged(const EventType& event) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookie_set"); + message.setValue("cookie", event.getStringValue()); + // These could be passed through as well, but aren't really needed. +// message.setValue("uri", event.getEventUri()); +// message.setValueBoolean("dead", (event.getIntValue() != 0)) + sendMessage(message); + } + LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers) { int result = 0; @@ -1056,6 +1088,10 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) mJavascriptEnabled = message_in.getValueBoolean("enable"); //LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); } + else if(message_name == "set_cookies") + { + LLQtWebKit::getInstance()->setCookies(message_in.getValue("cookies")); + } else if(message_name == "proxy_setup") { bool val = message_in.getValueBoolean("enable"); @@ -1125,9 +1161,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string) void MediaPluginWebKit::setVolume(F32 volume) { -#if LL_LINUX - mLinuxVolumeCatcher.setVolume(volume); -#endif // LL_LINUX + mVolumeCatcher.setVolume(volume); } int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) diff --git a/linden/indra/media_plugins/webkit/volume_catcher.h b/linden/indra/media_plugins/webkit/volume_catcher.h new file mode 100644 index 000000000..855e99fc0 --- /dev/null +++ b/linden/indra/media_plugins/webkit/volume_catcher.h @@ -0,0 +1,61 @@ +/** + * @file volume_catcher.h + * @brief Interface to a class with platform-specific implementations that allows control of the audio volume of all sources in the current process. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +#ifndef VOLUME_CATCHER_H +#define VOLUME_CATCHER_H + +#include "linden_common.h" + +class VolumeCatcherImpl; + +class VolumeCatcher +{ + public: + VolumeCatcher(); + ~VolumeCatcher(); + + void setVolume(F32 volume); // 0.0 - 1.0 + + // Set the left-right pan of audio sources + // where -1.0 = left, 0 = center, and 1.0 = right + void setPan(F32 pan); + + void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume + + private: + VolumeCatcherImpl *pimpl; +}; + +#endif // VOLUME_CATCHER_H diff --git a/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp new file mode 100644 index 000000000..c02e7fc0d --- /dev/null +++ b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -0,0 +1,124 @@ +/** + * @file windows_volume_catcher.cpp + * @brief A Windows implementation of volume level control of all audio channels opened by a process. + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + * @endcond + */ + +#include "volume_catcher.h" +#include <windows.h> +#include "llsingleton.h" +class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl> +{ +friend LLSingleton<VolumeCatcherImpl>; +public: + + void setVolume(F32 volume); + void setPan(F32 pan); + +private: + // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. + VolumeCatcherImpl(); + ~VolumeCatcherImpl(); + + typedef void (WINAPI *set_volume_func_t)(F32); + typedef void (WINAPI *set_mute_func_t)(bool); + + set_volume_func_t mSetVolumeFunc; + set_mute_func_t mSetMuteFunc; + + F32 mVolume; + F32 mPan; +}; +VolumeCatcherImpl::VolumeCatcherImpl() +: mVolume(1.0f), // default volume is max + mPan(0.f) // default pan is centered +{ + HMODULE handle = ::LoadLibrary(L"winmm.dll"); + if(handle) + { + mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume"); + mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute"); + } +} + +VolumeCatcherImpl::~VolumeCatcherImpl() +{ +} + + +void VolumeCatcherImpl::setVolume(F32 volume) +{ + mVolume = volume; + + if (mSetMuteFunc) + { + mSetMuteFunc(volume == 0.f); + } + if (mSetVolumeFunc) + { + mSetVolumeFunc(mVolume); + } +} + +void VolumeCatcherImpl::setPan(F32 pan) +{ // remember pan for calculating individual channel levels later + mPan = pan; +} + +///////////////////////////////////////////////////// + +VolumeCatcher::VolumeCatcher() +{ + pimpl = VolumeCatcherImpl::getInstance(); +} + +VolumeCatcher::~VolumeCatcher() +{ + // Let the instance persist until exit. +} + +void VolumeCatcher::setVolume(F32 volume) +{ + pimpl->setVolume(volume); +} + +void VolumeCatcher::setPan(F32 pan) +{ + pimpl->setPan(pan); +} + +void VolumeCatcher::pump() +{ + // No periodic tasks are necessary for this implementation. +} + + diff --git a/linden/install.xml b/linden/install.xml index 07e7498c8..402ce00ef 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -1144,30 +1144,23 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <key>darwin</key> <map> <key>md5sum</key> - <string>38a31c64cbb021320c6f8c0296933f2b</string> + <string>becffca6bd8dcb239de284ea2a8b485b</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100402.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6+cookies-darwin-20100617.tar.bz2</uri> </map> <key>linux</key> <map> <key>md5sum</key> - <string>78e22d53c84c8642fbaa027fed20cc48</string> + <string>414d72dd59e3d83c96f0e1531360792e</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20100407.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>d602324a827be7e0a8c90f85d27d6151</string> - <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/llqtwebkit-linux64-20100617.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20100618.tar.bz2</uri> </map> <key>windows</key> <map> <key>md5sum</key> - <string>b6ec5fe296b8ad9097b182b5c09a9589</string> + <string>df1bdd683128e060d60e435f65d8f7e8</string> <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100402.tar.bz2</uri> + <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100617.tar.bz2</uri> </map> </map> </map> @@ -1456,6 +1449,25 @@ Copyright (C) 2004-2005 Vladimir Berezniker @ http://public.xdi.org/=vmpn </map> </map> </map> + <key>pulseaudio</key> + <map> + <key>copyright</key> + <string>Copyright 2004-2006 Lennart Poettering, Copyright 2006 Pierre Ossman (ossman@cendio.se) for Cendio AB</string> + <key>description</key> + <string>pulseaudio: headers only</string> + <key>license</key> + <string>lgpl</string> + <key>packages</key> + <map> + <key>linux</key> + <map> + <key>md5sum</key> + <string>30cb00069fe2a545fbf7be1070386236</string> + <key>url</key> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/linux-pulse-headers-0.9.14.tar.bz2</uri> + </map> + </map> + </map> <key>quicktime</key> <map> <key>copyright</key> From fcf35900271fbcb123b9d0d5652d79db0d1965fb Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Tue, 7 Sep 2010 17:38:53 +0200 Subject: [PATCH 028/239] fix platform specific mime_type xml loading note: mime_type<_nonwindowsplatform>.xml directs SLPlugin to the actual implementation. For using gstreamer on mac + win the file has to be changed (try the linux one :) ) --- linden/indra/newview/CMakeLists.txt | 14 +------------- linden/indra/newview/llappviewer.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 6fd259aa8..3dabb3bb1 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1547,19 +1547,7 @@ if (WINDOWS) COMMENT "Copying Quicktime Plugin to the runtime folder." ) - # Copying the mime_types.xml file to app_settings - set(mime_types_source "${CMAKE_SOURCE_DIR}/newview/skins/default/xui/en-us") - set(mime_types_dest "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/app_settings") - add_custom_command( - TARGET ${VIEWER_BINARY_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - copy_if_different - ${mime_types_source}/mime_types_windows.xml - ${mime_types_dest}/mime_types.xml - COMMENT "Copying mime_types_windows.xml to mime_types.xml." - ) + endif (WINDOWS) diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index a9a6052f1..f422f3311 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -707,8 +707,15 @@ bool LLAppViewer::init() LLViewerJointMesh::updateVectorize(); // load MIME type -> media impl mappings - LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") ); - + std::string mime_types_name; +#if LL_DARWIN + mime_types_name = "mime_types_mac.xml"; +#elif LL_LINUX + mime_types_name = "mime_types_linux.xml"; +#else + mime_types_name = "mime_types.xml"; +#endif + LLMIMETypes::parseMIMETypes( mime_types_name ); // Copy settings to globals. *TODO: Remove or move to appropriage class initializers settings_to_globals(); From f27a85fab0418b3aa6cd70a7111f970f7982e72e Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Thu, 9 Sep 2010 00:38:21 -0700 Subject: [PATCH 029/239] Removed more unused 'prepare' dependencies --- linden/indra/llprimitive/CMakeLists.txt | 1 - linden/indra/llrender/CMakeLists.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/linden/indra/llprimitive/CMakeLists.txt b/linden/indra/llprimitive/CMakeLists.txt index 716b2476f..e7ee81141 100755 --- a/linden/indra/llprimitive/CMakeLists.txt +++ b/linden/indra/llprimitive/CMakeLists.txt @@ -52,7 +52,6 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) -add_dependencies(llprimitive prepare) #add unit tests INCLUDE(LLAddBuildTest) diff --git a/linden/indra/llrender/CMakeLists.txt b/linden/indra/llrender/CMakeLists.txt index e42f9ab26..3ba841e53 100644 --- a/linden/indra/llrender/CMakeLists.txt +++ b/linden/indra/llrender/CMakeLists.txt @@ -90,4 +90,3 @@ else (SERVER AND NOT WINDOWS AND NOT DARWIN) ) endif (SERVER AND NOT WINDOWS AND NOT DARWIN) add_library (llrender ${llrender_SOURCE_FILES}) -add_dependencies(llrender prepare) From adc28fac384c713638946a37df2628dbffed3244 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <hakushakukun@gmail.com> Date: Thu, 9 Sep 2010 05:06:41 -0700 Subject: [PATCH 030/239] Fixed plugin compile issues on windows --- linden/indra/media_plugins/webkit/media_plugin_webkit.cpp | 1 + linden/indra/media_plugins/webkit/windows_volume_catcher.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index f9b645111..ebf64f865 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -37,6 +37,7 @@ #include "linden_common.h" #include "indra_constants.h" // for indra keyboard codes +#include <iomanip> #include "llgl.h" diff --git a/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp index c02e7fc0d..f1afea7ee 100644 --- a/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp +++ b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -35,7 +35,7 @@ #include "volume_catcher.h" #include <windows.h> -#include "llsingleton.h" +#include "llmemory.h" class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl> { friend LLSingleton<VolumeCatcherImpl>; From f41c6363087f95ce5f7d99385e455d7e0105d883 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Sat, 10 Jul 2010 14:35:58 +0200 Subject: [PATCH 031/239] Imprudence style gstreamer plugin (remove llgst, syms and such) --- .../media_plugins/gstreamer010/CMakeLists.txt | 2 - .../llmediaimplgstreamer_syms.cpp | 174 ------- .../gstreamer010/llmediaimplgstreamer_syms.h | 81 ---- .../llmediaimplgstreamer_syms_raw.inc | 51 -- .../llmediaimplgstreamer_syms_rawv.inc | 5 - .../llmediaimplgstreamervidplug.cpp | 166 ++++--- .../llmediaimplgstreamervidplug.h | 5 +- .../media_plugin_gstreamer010.cpp | 454 ++++++++++++------ linden/indra/newview/lloverlaybar.cpp | 52 +- linden/indra/newview/llstartup.cpp | 2 +- .../newview/llviewermedia_streamingaudio.cpp | 22 +- .../newview/llviewermedia_streamingaudio.h | 10 +- 12 files changed, 440 insertions(+), 584 deletions(-) delete mode 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp delete mode 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h delete mode 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc delete mode 100755 linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt index 6eab49cd0..a031157f2 100644 --- a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -44,13 +44,11 @@ endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) set(media_plugin_gstreamer010_SOURCE_FILES media_plugin_gstreamer010.cpp - llmediaimplgstreamer_syms.cpp llmediaimplgstreamervidplug.cpp ) set(media_plugin_gstreamer010_HEADER_FILES llmediaimplgstreamervidplug.h - llmediaimplgstreamer_syms.h llmediaimplgstreamertriviallogging.h ) diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp deleted file mode 100755 index 82978addf..000000000 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/** - * @file llmediaimplgstreamer_syms.cpp - * @brief dynamic GStreamer symbol-grabbing code - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2010, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - * - * @endcond - */ - -#if LL_GSTREAMER010_ENABLED - -#include <string> - -extern "C" { -#include <gst/gst.h> - -#include "apr_pools.h" -#include "apr_dso.h" -} - -#include "llmediaimplgstreamertriviallogging.h" - -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL -#include "llmediaimplgstreamer_syms_raw.inc" -#include "llmediaimplgstreamer_syms_rawv.inc" -#undef LL_GST_SYM - -// a couple of stubs for disgusting reasons -GstDebugCategory* -ll_gst_debug_category_new(gchar *name, guint color, gchar *description) -{ - static GstDebugCategory dummy; - return &dummy; -} -void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname) -{ -} - -static bool sSymsGrabbed = false; -static apr_pool_t *sSymGSTDSOMemoryPool = NULL; -static apr_dso_handle_t *sSymGSTDSOHandleG = NULL; -static apr_dso_handle_t *sSymGSTDSOHandleV = NULL; - - -bool grab_gst_syms(std::string gst_dso_name, - std::string gst_dso_name_vid) -{ - if (sSymsGrabbed) - { - // already have grabbed good syms - return TRUE; - } - - bool sym_error = false; - bool rtn = false; - apr_status_t rv; - apr_dso_handle_t *sSymGSTDSOHandle = NULL; - -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0) - - //attempt to load the shared libraries - apr_pool_create(&sSymGSTDSOMemoryPool, NULL); - - if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, - gst_dso_name.c_str(), - sSymGSTDSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", gst_dso_name.c_str()); -#include "llmediaimplgstreamer_syms_raw.inc" - - if ( sSymGSTDSOHandle ) - { - sSymGSTDSOHandleG = sSymGSTDSOHandle; - sSymGSTDSOHandle = NULL; - } - - if ( APR_SUCCESS == - (rv = apr_dso_load(&sSymGSTDSOHandle, - gst_dso_name_vid.c_str(), - sSymGSTDSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); -#include "llmediaimplgstreamer_syms_rawv.inc" - rtn = !sym_error; - } - else - { - INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); - rtn = false; // failure - } - } - else - { - INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); - rtn = false; // failure - } - - if (sym_error) - { - WARNMSG("Failed to find necessary symbols in GStreamer libraries."); - } - - if ( sSymGSTDSOHandle ) - { - sSymGSTDSOHandleV = sSymGSTDSOHandle; - sSymGSTDSOHandle = NULL; - } -#undef LL_GST_SYM - - sSymsGrabbed = !!rtn; - return rtn; -} - - -void ungrab_gst_syms() -{ - // should be safe to call regardless of whether we've - // actually grabbed syms. - - if ( sSymGSTDSOHandleG ) - { - apr_dso_unload(sSymGSTDSOHandleG); - sSymGSTDSOHandleG = NULL; - } - - if ( sSymGSTDSOHandleV ) - { - apr_dso_unload(sSymGSTDSOHandleV); - sSymGSTDSOHandleV = NULL; - } - - if ( sSymGSTDSOMemoryPool ) - { - apr_pool_destroy(sSymGSTDSOMemoryPool); - sSymGSTDSOMemoryPool = NULL; - } - - // NULL-out all of the symbols we'd grabbed -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0) -#include "llmediaimplgstreamer_syms_raw.inc" -#include "llmediaimplgstreamer_syms_rawv.inc" -#undef LL_GST_SYM - - sSymsGrabbed = false; -} - - -#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h deleted file mode 100755 index c30904311..000000000 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file llmediaimplgstreamer_syms.h - * @brief dynamic GStreamer symbol-grabbing code - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2010, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - * - * @endcond - */ - -#include "linden_common.h" - -#if LL_GSTREAMER010_ENABLED - -extern "C" { -#include <gst/gst.h> -} - -bool grab_gst_syms(std::string gst_dso_name, - std::string gst_dso_name_vid); -void ungrab_gst_syms(); - -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__) -#include "llmediaimplgstreamer_syms_raw.inc" -#include "llmediaimplgstreamer_syms_rawv.inc" -#undef LL_GST_SYM - -// regrettable hacks to give us better runtime compatibility with older systems -#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) -#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0) - -// regrettable hacks because GStreamer was not designed for runtime loading -#undef GST_TYPE_MESSAGE -#define GST_TYPE_MESSAGE (llgst_message_get_type()) -#undef GST_TYPE_OBJECT -#define GST_TYPE_OBJECT (llgst_object_get_type()) -#undef GST_TYPE_PIPELINE -#define GST_TYPE_PIPELINE (llgst_pipeline_get_type()) -#undef GST_TYPE_ELEMENT -#define GST_TYPE_ELEMENT (llgst_element_get_type()) -#undef GST_TYPE_VIDEO_SINK -#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type()) -// more regrettable hacks to stub-out these .h-exposed GStreamer internals -void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname); -#undef _gst_debug_register_funcptr -#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr -GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description); -#undef _gst_debug_category_new -#define _gst_debug_category_new ll_gst_debug_category_new -#undef __gst_debug_enabled -#define __gst_debug_enabled (0) - -// more hacks -#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M))) - -#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc deleted file mode 100755 index b33e59363..000000000 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc +++ /dev/null @@ -1,51 +0,0 @@ - -// required symbols to grab -LL_GST_SYM(true, gst_pad_peer_accept_caps, gboolean, GstPad *pad, GstCaps *caps); -LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void); -LL_GST_SYM(true, gst_buffer_set_caps, void, GstBuffer*, GstCaps *); -LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*); -LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err); -LL_GST_SYM(true, gst_message_get_type, GType, void); -LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type); -LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug); -LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug); -LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending); -LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state); -LL_GST_SYM(true, gst_object_unref, void, gpointer object); -LL_GST_SYM(true, gst_object_get_type, GType, void); -LL_GST_SYM(true, gst_pipeline_get_type, GType, void); -LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline); -LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data); -LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name); -LL_GST_SYM(true, gst_element_get_type, GType, void); -LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template); -LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp); -LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details); -LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps); -LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps); -//LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps); -LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string); -LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps); -LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index); -LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps); -//LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2); -LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type); -LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc); -LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value); -LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname); -LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value); -LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value); -LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure); -LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64); - -// optional symbols to grab -LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled); -LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled); -LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent); -LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug); -LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur); -LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano); - -// GStreamer 'internal' symbols which may not be visible in some runtimes but are still used in expanded GStreamer header macros - yuck! We'll substitute our own stubs for these. -//LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname); -//LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description); diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc deleted file mode 100755 index 14fbcb48b..000000000 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc +++ /dev/null @@ -1,5 +0,0 @@ - -// required symbols to grab -LL_GST_SYM(true, gst_video_sink_get_type, GType, void); - -// optional symbols to grab diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index 924283011..1fee54593 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -33,7 +33,7 @@ * @endcond */ -#if LL_GSTREAMER010_ENABLED +///#if LL_GSTREAMER010_ENABLED #include "linden_common.h" @@ -41,15 +41,29 @@ #include <gst/video/video.h> #include <gst/video/gstvideosink.h> -#include "llmediaimplgstreamer_syms.h" #include "llmediaimplgstreamertriviallogging.h" +// #include "llthread.h" #include "llmediaimplgstreamervidplug.h" - GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); #define GST_CAT_DEFAULT gst_slvideo_debug +/* Filter signals and args *//* +enum +{ + *//* FILL ME *//* + LAST_SIGNAL +}; + +enum +{ + ARG_0 +}; + +#define SLV_SIZECAPS ", width=(int){1,2,4,8,16,32,64,128,256,512,1024}, height=(int){1,2,4,8,16,32,64,128,256,512,1024} " +#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS ";" GST_VIDEO_CAPS_BGRx SLV_SIZECAPS +*/ #define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] " #define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS @@ -81,9 +95,9 @@ gst_slvideo_base_init (gpointer gclass) }; GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - llgst_element_class_add_pad_template (element_class, - llgst_static_pad_template_get (&sink_factory)); - llgst_element_class_set_details (element_class, &element_details); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); + gst_element_class_set_details (element_class, &element_details); } @@ -94,7 +108,7 @@ gst_slvideo_finalize (GObject * object) slvideo = GST_SLVIDEO (object); if (slvideo->caps) { - llgst_caps_unref(slvideo->caps); + gst_caps_unref(slvideo->caps); } G_OBJECT_CLASS(parent_class)->finalize (object); @@ -105,7 +119,7 @@ static GstFlowReturn gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) { GstSLVideo *slvideo; - llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); + g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); slvideo = GST_SLVIDEO(bsink); @@ -197,7 +211,7 @@ gst_slvideo_get_caps (GstBaseSink * bsink) GstSLVideo *slvideo; slvideo = GST_SLVIDEO(bsink); - return llgst_caps_ref (slvideo->caps); + return gst_caps_ref (slvideo->caps); } @@ -207,21 +221,32 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) { GstSLVideo *filter; GstStructure *structure; +// GstCaps *intersection; GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); filter = GST_SLVIDEO(bsink); - int width, height; +/* + intersection = gst_caps_intersect (filter->caps, caps); + if (gst_caps_is_empty (intersection)) + { + // no overlap between our caps and requested caps + return FALSE; + } + gst_caps_unref(intersection); +*/ + int width = 0; + int height = 0; gboolean ret; const GValue *fps; const GValue *par; - structure = llgst_caps_get_structure (caps, 0); - ret = llgst_structure_get_int (structure, "width", &width); - ret = ret && llgst_structure_get_int (structure, "height", &height); - fps = llgst_structure_get_value (structure, "framerate"); + structure = gst_caps_get_structure (caps, 0); + ret = gst_structure_get_int (structure, "width", &width); + ret = ret && gst_structure_get_int (structure, "height", &height); + fps = gst_structure_get_value (structure, "framerate"); ret = ret && (fps != NULL); - par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); + par = gst_structure_get_value (structure, "pixel-aspect-ratio"); if (!ret) return FALSE; @@ -231,34 +256,35 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) filter->width = width; filter->height = height; - - filter->fps_n = llgst_value_get_fraction_numerator(fps); - filter->fps_d = llgst_value_get_fraction_denominator(fps); + filter->fps_n = gst_value_get_fraction_numerator(fps); + filter->fps_d = gst_value_get_fraction_denominator(fps); if (par) { - filter->par_n = llgst_value_get_fraction_numerator(par); - filter->par_d = llgst_value_get_fraction_denominator(par); + filter->par_n = gst_value_get_fraction_numerator(par); + filter->par_d = gst_value_get_fraction_denominator(par); } else { filter->par_n = 1; filter->par_d = 1; } + GST_VIDEO_SINK_WIDTH(filter) = width; GST_VIDEO_SINK_HEIGHT(filter) = height; - + // crufty lump - we *always* accept *only* RGBX now. /* + filter->format = SLV_PF_UNKNOWN; - if (0 == strcmp(llgst_structure_get_name(structure), + if (0 == strcmp(gst_structure_get_name(structure), "video/x-raw-rgb")) { int red_mask; int green_mask; int blue_mask; - llgst_structure_get_int(structure, "red_mask", &red_mask); - llgst_structure_get_int(structure, "green_mask", &green_mask); - llgst_structure_get_int(structure, "blue_mask", &blue_mask); + gst_structure_get_int(structure, "red_mask", &red_mask); + gst_structure_get_int(structure, "green_mask", &green_mask); + gst_structure_get_int(structure, "blue_mask", &blue_mask); if ((unsigned int)red_mask == 0xFF000000 && (unsigned int)green_mask == 0x00FF0000 && (unsigned int)blue_mask == 0x0000FF00) @@ -272,12 +298,13 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) filter->format = SLV_PF_BGRX; //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n"); } - }*/ - + + }*/ + filter->format = SLV_PF_RGBX; GST_OBJECT_UNLOCK(filter); - + return TRUE; } @@ -324,15 +351,15 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, // we can ignore these and reverse-negotiate our preferred dimensions with // the peer if we like - we need to do this to obey dynamic resize requests // flowing in from the app. - structure = llgst_caps_get_structure (caps, 0); - if (!llgst_structure_get_int(structure, "width", &width) || - !llgst_structure_get_int(structure, "height", &height)) + structure = gst_caps_get_structure (caps, 0); + if (!gst_structure_get_int(structure, "width", &width) || + !gst_structure_get_int(structure, "height", &height)) { GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps); return GST_FLOW_NOT_NEGOTIATED; } - GstBuffer *newbuf = llgst_buffer_new(); + GstBuffer *newbuf = gst_buffer_new(); bool made_bufferdata_ptr = false; #define MAXDEPTHHACK 4 @@ -352,19 +379,19 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, GstCaps *desired_caps; GstStructure *desired_struct; - desired_caps = llgst_caps_copy (caps); - desired_struct = llgst_caps_get_structure (desired_caps, 0); + desired_caps = gst_caps_copy (caps); + desired_struct = gst_caps_get_structure (desired_caps, 0); GValue value = {0}; g_value_init(&value, G_TYPE_INT); g_value_set_int(&value, slwantwidth); - llgst_structure_set_value (desired_struct, "width", &value); + gst_structure_set_value (desired_struct, "width", &value); g_value_unset(&value); g_value_init(&value, G_TYPE_INT); g_value_set_int(&value, slwantheight); - llgst_structure_set_value (desired_struct, "height", &value); + gst_structure_set_value (desired_struct, "height", &value); - if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), + if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), desired_caps)) { // todo: re-use buffers from a pool? @@ -375,13 +402,13 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK; GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); - llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); + gst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); made_bufferdata_ptr = true; } else { // peer hates our cap suggestion INFOMSG("peer hates us :("); - llgst_caps_unref(desired_caps); + gst_caps_unref(desired_caps); } } } @@ -393,7 +420,7 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); - llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); + gst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); } *buf = GST_BUFFER_CAST(newbuf); @@ -435,6 +462,20 @@ gst_slvideo_class_init (GstSLVideoClass * klass) #undef LLGST_DEBUG_FUNCPTR } +/* +static void +gst_slvideo_update_caps (GstSLVideo * slvideo) +{ + GstCaps *caps; + + // GStreamer will automatically convert colourspace if necessary. + // GStreamer will automatically resize media to one of these enumerated + // powers-of-two that we ask for (yay GStreamer!) + caps = gst_caps_from_string (SLV_ALLCAPS); + + gst_caps_replace (&slvideo->caps, caps); +} +*/ /* initialize the new element * instantiate pads and add them to element @@ -457,24 +498,24 @@ gst_slvideo_init (GstSLVideo * filter, filter->retained_frame_width = filter->width; filter->retained_frame_height = filter->height; filter->retained_frame_format = SLV_PF_UNKNOWN; - GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); - llgst_caps_replace (&filter->caps, caps); + GstCaps *caps = gst_caps_from_string (SLV_ALLCAPS); + gst_caps_replace (&filter->caps, caps); filter->resize_forced_always = false; filter->resize_try_width = -1; filter->resize_try_height = -1; GST_OBJECT_UNLOCK(filter); + + //gst_slvideo_update_caps(filter); } static void gst_slvideo_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - llg_return_if_fail (GST_IS_SLVIDEO (object)); + g_return_if_fail (GST_IS_SLVIDEO (object)); - switch (prop_id) { - default: + if (prop_id) { G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; } } @@ -482,12 +523,10 @@ static void gst_slvideo_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - llg_return_if_fail (GST_IS_SLVIDEO (object)); + g_return_if_fail (GST_IS_SLVIDEO (object)); - switch (prop_id) { - default: + if (prop_id) { G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; } } @@ -505,7 +544,7 @@ plugin_init (GstPlugin * plugin) GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", 0, (gchar*)"Second Life Video Sink"); - return llgst_element_register (plugin, "private-slvideo", + return gst_element_register (plugin, "private-slvideo", GST_RANK_NONE, GST_TYPE_SLVIDEO); } @@ -515,20 +554,19 @@ plugin_init (GstPlugin * plugin) some g++ versions buggily avoid __attribute__((constructor)) functions - so we provide an explicit plugin init function. */ -#define PACKAGE (gchar*)"packagehack" - // this macro quietly refers to PACKAGE internally - GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - (gchar*)"private-slvideoplugin", - (gchar*)"SL Video sink plugin", - plugin_init, (gchar*)"0.1", (gchar*)GST_LICENSE_UNKNOWN, - (gchar*)"Second Life", - (gchar*)"http://www.secondlife.com/"); -#undef PACKAGE + void gst_slvideo_init_class (void) { - ll_gst_plugin_register_static (&gst_plugin_desc); - DEBUGMSG("CLASS INIT"); + gst_plugin_register_static( GST_VERSION_MAJOR, + GST_VERSION_MINOR, + (const gchar *)"private-slvideoplugin", + (gchar *)"SL Video sink plugin", + plugin_init, + (const gchar *)"0.1", + GST_LICENSE_UNKNOWN, + (const gchar *)"Second Life", + (const gchar *)"Second Life", + (const gchar *)"http://www.secondlife.com/" ); } -#endif // LL_GSTREAMER010_ENABLED +///#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index 56f6db956..0ad8cf176 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -36,12 +36,13 @@ #ifndef __GST_SLVIDEO_H__ #define __GST_SLVIDEO_H__ -#if LL_GSTREAMER010_ENABLED +///#if LL_GSTREAMER010_ENABLED extern "C" { #include <gst/gst.h> #include <gst/video/video.h> #include <gst/video/gstvideosink.h> +// #include <glib/gthread.h> } G_BEGIN_DECLS @@ -107,6 +108,6 @@ void gst_slvideo_init_class (void); G_END_DECLS -#endif // LL_GSTREAMER010_ENABLED +///#endif // LL_GSTREAMER010_ENABLED #endif /* __GST_SLVIDEO_H__ */ diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 7d34a1ec0..4dd182eb7 100755 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -46,6 +46,7 @@ extern "C" { #include <gst/gst.h> +#include <gst/gstelement.h> } #include "llmediaimplgstreamer.h" @@ -53,8 +54,6 @@ extern "C" { #include "llmediaimplgstreamervidplug.h" -#include "llmediaimplgstreamer_syms.h" - ////////////////////////////////////////////////////////////////////////////// // class MediaPluginGStreamer010 : public MediaPluginBase @@ -68,6 +67,8 @@ class MediaPluginGStreamer010 : public MediaPluginBase static bool startup(); static bool closedown(); + static void set_gst_plugin_path(); + gboolean processGSTEvents(GstBus *bus, GstMessage *message); @@ -139,6 +140,8 @@ class MediaPluginGStreamer010 : public MediaPluginBase bool mSeekWanted; double mSeekDestination; + + std::string mLastTitle; // Very GStreamer-specific GMainLoop *mPump; // event pump for this media @@ -196,149 +199,179 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus, GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) { DEBUGMSG("Got GST message type: %s", - LLGST_MESSAGE_TYPE_NAME (message)); + GST_MESSAGE_TYPE_NAME (message)); } else { // TODO: grok 'duration' message type DEBUGMSG("Got GST message type: %s", - LLGST_MESSAGE_TYPE_NAME (message)); + GST_MESSAGE_TYPE_NAME (message)); } - switch (GST_MESSAGE_TYPE (message)) { - case GST_MESSAGE_BUFFERING: { - // NEEDS GST 0.10.11+ - if (llgst_message_parse_buffering) + switch (GST_MESSAGE_TYPE (message)) + { + case GST_MESSAGE_BUFFERING: { + // NEEDS GST 0.10.11+ and America discovered by C.Columbus gint percent = 0; - llgst_message_parse_buffering(message, &percent); + gst_message_parse_buffering(message, &percent); DEBUGMSG("GST buffering: %d%%", percent); - } - break; - } - case GST_MESSAGE_STATE_CHANGED: { - GstState old_state; - GstState new_state; - GstState pending_state; - llgst_message_parse_state_changed(message, - &old_state, - &new_state, - &pending_state); -#ifdef LL_GST_REPORT_STATE_CHANGES - // not generally very useful, and rather spammy. - DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", - get_gst_state_name(old_state), - get_gst_state_name(new_state), - get_gst_state_name(pending_state)); -#endif // LL_GST_REPORT_STATE_CHANGES - switch (new_state) { - case GST_STATE_VOID_PENDING: - break; - case GST_STATE_NULL: break; - case GST_STATE_READY: - setStatus(STATUS_LOADED); - break; - case GST_STATE_PAUSED: - setStatus(STATUS_PAUSED); + } + case GST_MESSAGE_STATE_CHANGED: { + GstState old_state; + GstState new_state; + GstState pending_state; + gst_message_parse_state_changed(message, + &old_state, + &new_state, + &pending_state); + #ifdef LL_GST_REPORT_STATE_CHANGES + // not generally very useful, and rather spammy. + DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", + get_gst_state_name(old_state), + get_gst_state_name(new_state), + get_gst_state_name(pending_state)); + #endif // LL_GST_REPORT_STATE_CHANGES + + switch (new_state) + { + case GST_STATE_VOID_PENDING: + break; + case GST_STATE_NULL: + break; + case GST_STATE_READY: + setStatus(STATUS_LOADED); + break; + case GST_STATE_PAUSED: + setStatus(STATUS_PAUSED); + break; + case GST_STATE_PLAYING: + setStatus(STATUS_PLAYING); + break; + } break; - case GST_STATE_PLAYING: - setStatus(STATUS_PLAYING); + } + case GST_MESSAGE_ERROR: + { + GError *err = NULL; + gchar *debug = NULL; + + gst_message_parse_error (message, &err, &debug); + WARNMSG("GST error: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + + mCommand = COMMAND_STOP; + + setStatus(STATUS_ERROR); + break; } - break; - } - case GST_MESSAGE_ERROR: { - GError *err = NULL; - gchar *debug = NULL; - - llgst_message_parse_error (message, &err, &debug); - WARNMSG("GST error: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); - - mCommand = COMMAND_STOP; - - setStatus(STATUS_ERROR); - - break; - } - case GST_MESSAGE_INFO: { - if (llgst_message_parse_info) + case GST_MESSAGE_INFO: { GError *err = NULL; gchar *debug = NULL; - llgst_message_parse_info (message, &err, &debug); + gst_message_parse_info (message, &err, &debug); INFOMSG("GST info: %s", err?err->message:"(unknown)"); if (err) g_error_free (err); g_free (debug); + + break; } - break; - } - case GST_MESSAGE_WARNING: { - GError *err = NULL; - gchar *debug = NULL; + case GST_MESSAGE_WARNING: + { + GError *err = NULL; + gchar *debug = NULL; + + gst_message_parse_warning (message, &err, &debug); + WARNMSG("GST warning: %s", err?err->message:"(unknown)"); + if (err) + g_error_free (err); + g_free (debug); + + break; + } + case GST_MESSAGE_TAG: + { + GstTagList *new_tags; - llgst_message_parse_warning (message, &err, &debug); - WARNMSG("GST warning: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); + gst_message_parse_tag( message, &new_tags ); - break; - } - case GST_MESSAGE_EOS: - /* end-of-stream */ - DEBUGMSG("GST end-of-stream."); - if (mIsLooping) - { - DEBUGMSG("looping media..."); - double eos_pos_sec = 0.0F; - bool got_eos_position = getTimePos(eos_pos_sec); + gchar *title = NULL; - if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) + if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) ) { - // if we know that the movie is really short, don't - // loop it else it can easily become a time-hog - // because of GStreamer spin-up overhead - DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); - // inject a COMMAND_PAUSE - mCommand = COMMAND_PAUSE; + //WARMING("Title: %s", title); + std::string newtitle(title); + gst_tag_list_free(new_tags); + + if ( newtitle != mLastTitle && !newtitle.empty() ) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", newtitle ); + sendMessage( message ); + mLastTitle = newtitle; + } + g_free(title); } - else + + break; + } + case GST_MESSAGE_EOS: + { + /* end-of-stream */ + DEBUGMSG("GST end-of-stream."); + if (mIsLooping) { -#undef LLGST_LOOP_BY_SEEKING -// loop with a stop-start instead of a seek, because it actually seems rather -// faster than seeking on remote streams. -#ifdef LLGST_LOOP_BY_SEEKING - // first, try looping by an explicit rewind - bool seeksuccess = seek(0.0); - if (seeksuccess) + DEBUGMSG("looping media..."); + double eos_pos_sec = 0.0F; + bool got_eos_position = getTimePos(eos_pos_sec); + + if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) { - play(1.0); + // if we know that the movie is really short, don't + // loop it else it can easily become a time-hog + // because of GStreamer spin-up overhead + DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); + // inject a COMMAND_PAUSE + mCommand = COMMAND_PAUSE; } else -#endif // LLGST_LOOP_BY_SEEKING - { // use clumsy stop-start to loop - DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); - stop(); - play(1.0); + { + #undef LLGST_LOOP_BY_SEEKING + // loop with a stop-start instead of a seek, because it actually seems rather + // faster than seeking on remote streams. + #ifdef LLGST_LOOP_BY_SEEKING + // first, try looping by an explicit rewind + bool seeksuccess = seek(0.0); + if (seeksuccess) + { + play(1.0); + } + else + #endif // LLGST_LOOP_BY_SEEKING + { // use clumsy stop-start to loop + DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); + stop(); + play(1.0); + } } } - } - else // not a looping media - { - // inject a COMMAND_STOP - mCommand = COMMAND_STOP; - } - break; - default: - /* unhandled message */ - break; + else // not a looping media + { + // inject a COMMAND_STOP + mCommand = COMMAND_STOP; + } + } break; + + default: + /* unhandled message */ + break; } /* we want to be notified again the next time there is a message @@ -544,7 +577,7 @@ MediaPluginGStreamer010::pause() { DEBUGMSG("pausing media..."); // todo: error-check this? - llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); + gst_element_set_state(mPlaybin, GST_STATE_PAUSED); return true; } @@ -553,7 +586,7 @@ MediaPluginGStreamer010::stop() { DEBUGMSG("stopping media..."); // todo: error-check this? - llgst_element_set_state(mPlaybin, GST_STATE_READY); + gst_element_set_state(mPlaybin, GST_STATE_READY); return true; } @@ -564,7 +597,7 @@ MediaPluginGStreamer010::play(double rate) DEBUGMSG("playing media... rate=%f", rate); // todo: error-check this? - llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); + gst_element_set_state(mPlaybin, GST_STATE_PLAYING); return true; } @@ -593,7 +626,7 @@ MediaPluginGStreamer010::seek(double time_sec) bool success = false; if (mDoneInit && mPlaybin) { - success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, + success = gst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, GstSeekFlags(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), @@ -612,11 +645,9 @@ MediaPluginGStreamer010::getTimePos(double &sec_out) { gint64 pos; GstFormat timefmt = GST_FORMAT_TIME; - got_position = - llgst_element_query_position && - llgst_element_query_position(mPlaybin, - &timefmt, - &pos); + got_position = gst_element_query_position(mPlaybin, + &timefmt, + &pos); got_position = got_position && (timefmt == GST_FORMAT_TIME); // GStreamer may have other ideas, but we consider the current position @@ -669,7 +700,7 @@ MediaPluginGStreamer010::load() } // instantiate a playbin element to do the hard work - mPlaybin = llgst_element_factory_make ("playbin", "play"); + mPlaybin = gst_element_factory_make ("playbin", "play"); if (!mPlaybin) { setStatus(STATUS_ERROR); @@ -677,21 +708,21 @@ MediaPluginGStreamer010::load() } // get playbin's bus - GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); + GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); if (!bus) { setStatus(STATUS_ERROR); return false; // error } - mBusWatchID = llgst_bus_add_watch (bus, + mBusWatchID = gst_bus_add_watch (bus, llmediaimplgstreamer_bus_callback, this); - llgst_object_unref (bus); + gst_object_unref (bus); if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { // instantiate a custom video sink mVideoSink = - GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); + GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo")); if (!mVideoSink) { WARNMSG("Could not instantiate private-slvideo element."); @@ -721,8 +752,8 @@ MediaPluginGStreamer010::unload () if (mPlaybin) { - llgst_element_set_state (mPlaybin, GST_STATE_NULL); - llgst_object_unref (GST_OBJECT (mPlaybin)); + gst_element_set_state (mPlaybin, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (mPlaybin)); mPlaybin = NULL; } @@ -755,7 +786,10 @@ MediaPluginGStreamer010::startup() // Init the glib type system - we need it. g_type_init(); + set_gst_plugin_path(); + +/* // Get symbols! #if LL_DARWIN if (! grab_gst_syms("libgstreamer-0.10.dylib", @@ -771,24 +805,24 @@ MediaPluginGStreamer010::startup() WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); return false; } - - if (llgst_segtrap_set_enabled) - { - llgst_segtrap_set_enabled(FALSE); - } - else - { - WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); - } - +*/ +// if (gst_segtrap_set_enabled) +// { + gst_segtrap_set_enabled(FALSE); +// } +// else +// { +// WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); +// } +/* #if LL_LINUX // Gstreamer tries a fork during init, waitpid-ing on it, // which conflicts with any installed SIGCHLD handler... struct sigaction tmpact, oldact; - if (llgst_registry_fork_set_enabled) { + if (gst_registry_fork_set_enabled) { // if we can disable SIGCHLD-using forking behaviour, // do it. - llgst_registry_fork_set_enabled(false); + gst_registry_fork_set_enabled(false); } else { // else temporarily install default SIGCHLD handler @@ -799,24 +833,24 @@ MediaPluginGStreamer010::startup() sigaction(SIGCHLD, &tmpact, &oldact); } #endif // LL_LINUX - +*/ // Protect against GStreamer resetting the locale, yuck. static std::string saved_locale; saved_locale = setlocale(LC_ALL, NULL); // finally, try to initialize GStreamer! GError *err = NULL; - gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); + gboolean init_gst_success = gst_init_check(NULL, NULL, &err); // restore old locale setlocale(LC_ALL, saved_locale.c_str() ); - +/* #if LL_LINUX // restore old SIGCHLD handler - if (!llgst_registry_fork_set_enabled) + if (!gst_registry_fork_set_enabled) sigaction(SIGCHLD, &oldact, NULL); #endif // LL_LINUX - +*/ if (!init_gst_success) // fail { if (err) @@ -830,16 +864,139 @@ MediaPluginGStreamer010::startup() } return false; } - + + // Set up logging facilities + gst_debug_remove_log_function( gst_debug_log_default ); +// gst_debug_add_log_function( gstreamer_log, NULL ); + // Init our custom plugins - only really need do this once. gst_slvideo_init_class(); - +/* + // List the plugins GStreamer can find + LL_DEBUGS("MediaImpl") << "Found GStreamer plugins:" << LL_ENDL; + GList *list; + GstRegistry *registry = gst_registry_get_default(); + std::string loaded = ""; + for (list = gst_registry_get_plugin_list(registry); + list != NULL; + list = g_list_next(list)) + { + GstPlugin *list_plugin = (GstPlugin *)list->data; + (bool)gst_plugin_is_loaded(list_plugin) ? loaded = "Yes" : loaded = "No"; + LL_DEBUGS("MediaImpl") << gst_plugin_get_name(list_plugin) << ", loaded? " << loaded << LL_ENDL; + } + gst_plugin_list_free(list); +*/ mDoneInit = true; } return true; } +void MediaPluginGStreamer010::set_gst_plugin_path() +{ + // Linux sets GST_PLUGIN_PATH in wrapper.sh, not here. +#if LL_WINDOWS || LL_DARWIN + + std::string imp_dir = ""; + + // Get the current working directory: +#if LL_WINDOWS + char* raw_dir; + raw_dir = _getcwd(NULL,0); + if( raw_dir != NULL ) + { + imp_dir = std::string( raw_dir ); + } +#elif LL_DARWIN + CFBundleRef main_bundle = CFBundleGetMainBundle(); + if( main_bundle != NULL ) + { + CFURLRef bundle_url = CFBundleCopyBundleURL( main_bundle ); + if( bundle_url != NULL ) + { + #ifndef MAXPATHLEN + #define MAXPATHLEN 1024 + #endif + char raw_dir[MAXPATHLEN]; + if( CFURLGetFileSystemRepresentation( bundle_url, true, (UInt8 *)raw_dir, MAXPATHLEN) ) + { + imp_dir = std::string( raw_dir ) + "/Contents/MacOS/"; + } + CFRelease(bundle_url); + } + } +#endif + + if( imp_dir == "" ) + { + WARNMSG("Could not get application directory, not setting GST_PLUGIN_PATH."); + return; + } + + DEBUGMSG("Imprudence is installed at %s", imp_dir); + + // ":" on Mac and 'Nix, ";" on Windows + std::string separator = G_SEARCHPATH_SEPARATOR_S; + + // Grab the current path, if it's set. + std::string old_plugin_path = ""; + char *old_path = getenv("GST_PLUGIN_PATH"); + if(old_path == NULL) + { + DEBUGMSG("Did not find user-set GST_PLUGIN_PATH."); + } + else + { + old_plugin_path = separator + std::string( old_path ); + } + + + // Search both Imprudence and Imprudence\lib\gstreamer-plugins. + // But we also want to search the path the user has set, if any. + std::string plugin_path = + "GST_PLUGIN_PATH=" + +#if LL_WINDOWS + imp_dir + "\\lib\\gstreamer-plugins" + +#elif LL_DARWIN + imp_dir + separator + + imp_dir + "/../Resources/lib/gstreamer-plugins" + +#endif + old_plugin_path; + + int put_result; + + // Place GST_PLUGIN_PATH in the environment settings +#if LL_WINDOWS + put_result = _putenv( (char*)plugin_path.c_str() ); +#elif LL_DARWIN + put_result = putenv( (char*)plugin_path.c_str() ); +#endif + + if( put_result == -1 ) + { + WARNMSG("Setting GST_PLUGIN_PATH failed!"); + } + else + { + DEBUGMSG("GST_PLUGIN_PATH set to %s", getenv("GST_PLUGIN_PATH")); + } + + // Don't load system plugins. We only want to use ours, to avoid conflicts. +#if LL_WINDOWS + put_result = _putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" ); +#elif LL_DARWIN + put_result = putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" ); +#endif + + if( put_result == -1 ) + { + WARNMSG("Setting GST_PLUGIN_SYSTEM_PATH=\"\" failed!"); + } + +#endif // LL_WINDOWS || LL_DARWIN +} + void MediaPluginGStreamer010::sizeChanged() @@ -881,7 +1038,7 @@ MediaPluginGStreamer010::closedown() if (!mDoneInit) return false; // error - ungrab_gst_syms(); +// ungrab_gst_syms(); mDoneInit = false; @@ -902,11 +1059,10 @@ std::string MediaPluginGStreamer010::getVersion() { std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; - if (mDoneInit && - llgst_version) + if (mDoneInit) // && gst_version) { guint major, minor, micro, nano; - llgst_version(&major, &minor, µ, &nano); + gst_version(&major, &minor, µ, &nano); plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); } else diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index e903df792..e713e22b0 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp @@ -43,7 +43,7 @@ #include "llagent.h" #include "llbutton.h" #include "llchatbar.h" -#include "llfloaterchat.h" +//#include "llfloaterchat.h" #include "llfocusmgr.h" #include "llimview.h" #include "llmediaremotectrl.h" @@ -75,60 +75,10 @@ LLOverlayBar *gOverlayBar = NULL; extern S32 MENU_BAR_HEIGHT; -//awfixme -/* -class LLTitleObserver - : public LLMediaObserver -{ -public: - void init(std::string url); - *//*virtual*//* void onMediaTitleChange(const EventType& event_in); -private: - LLMediaBase* mMediaSource; -}; - -static LLTitleObserver sTitleObserver; - -static LLRegisterWidget<LLMediaRemoteCtrl> r("media_remote"); - -void LLTitleObserver::init(std::string url) -{ - - if (!gAudiop) - { - return; - } - - mMediaSource = gAudiop->getStreamMedia(); // LLViewerMedia::getSource(); - - if ( mMediaSource ) - { - mMediaSource->addObserver(this); - } -} - -//virtual -void LLTitleObserver::onMediaTitleChange(const EventType& event_in) -{ - if ( !gSavedSettings.getBOOL("ShowStreamTitle") ) - { - return; - } - - LLChat chat; - //TODO: set this in XUI - std::string playing_msg = "Playing: " + event_in.getStringValue(); - chat.mText = playing_msg; - LLFloaterChat::addChat(chat, FALSE, FALSE); -} -*/ - // // Functions // - - void* LLOverlayBar::createMediaRemote(void* userdata) { LLOverlayBar *self = (LLOverlayBar*)userdata; diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 237a967d3..64a2308fe 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -39,7 +39,7 @@ #else # include <sys/stat.h> // mkdir() #endif - +#include "llpluginclassmediaowner.h" #include "llviewermedia_streamingaudio.h" #include "llaudioengine.h" diff --git a/linden/indra/newview/llviewermedia_streamingaudio.cpp b/linden/indra/newview/llviewermedia_streamingaudio.cpp index 06946daff..575dbc8d8 100644 --- a/linden/indra/newview/llviewermedia_streamingaudio.cpp +++ b/linden/indra/newview/llviewermedia_streamingaudio.cpp @@ -36,6 +36,7 @@ #include "linden_common.h" #include "llpluginclassmedia.h" #include "llviewermedia.h" +#include "llviewercontrol.h" #include "llviewermedia_streamingaudio.h" @@ -43,6 +44,8 @@ #include "llvfs.h" #include "lldir.h" +#include "llchat.h" +#include "llfloaterchat.h" LLStreamingAudio_MediaPlugins::LLStreamingAudio_MediaPlugins() : mMediaPlugin(NULL), @@ -153,9 +156,26 @@ std::string LLStreamingAudio_MediaPlugins::getURL() return mURL; } +void LLStreamingAudio_MediaPlugins::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + if (event == MEDIA_EVENT_NAME_CHANGED) + { + std::string title = self->getMediaName(); + if (!title.empty() && gSavedSettings.getBOOL("ShowStreamTitle")) + { + //llinfos << "Playing: " << title << llendl; + LLChat chat; + //TODO: set this in XUI + std::string playing_msg = "Playing: " + title; + chat.mText = playing_msg; + LLFloaterChat::addChat(chat, FALSE, FALSE); + } + } +} + LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::string& media_type) { - LLPluginClassMediaOwner* owner = NULL; + LLPluginClassMediaOwner* owner = this; S32 default_size = 1; // audio-only - be minimal, doesn't matter LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size); diff --git a/linden/indra/newview/llviewermedia_streamingaudio.h b/linden/indra/newview/llviewermedia_streamingaudio.h index 270bab762..816e21361 100644 --- a/linden/indra/newview/llviewermedia_streamingaudio.h +++ b/linden/indra/newview/llviewermedia_streamingaudio.h @@ -36,12 +36,13 @@ #include "stdtypes.h" // from llcommon - #include "llstreamingaudio.h" class LLPluginClassMedia; -class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface +class LLStreamingAudio_MediaPlugins : + public LLStreamingAudioInterface, + public LLPluginClassMediaOwner { public: LLStreamingAudio_MediaPlugins(); @@ -56,14 +57,17 @@ class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface /*virtual*/ F32 getGain(); /*virtual*/ std::string getURL(); + // inherited from LLPluginClassMediaOwner + /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); + private: LLPluginClassMedia* initializeMedia(const std::string& media_type); LLPluginClassMedia *mMediaPlugin; - std::string mURL; F32 mGain; }; + #endif //LL_VIEWERMEDIA_STREAMINGAUDIO_H From 197f915816579a14e102075cf25a26127dfc1d32 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Thu, 23 Sep 2010 20:30:12 +0200 Subject: [PATCH 032/239] linux* kill imprudence gstreamer, use system gstreamer instead. who ever builds a release with that needs to consider to install some really old gstreamer at /usr/local/lib - lenny has 0.10.19 --- linden/indra/cmake/GStreamer.cmake | 114 -- linden/indra/cmake/GStreamer010Plugin.cmake | 20 +- linden/indra/llmedia/llmediaimplgstreamer.cpp | 928 ------------- .../media_plugin_gstreamer010.cpp~ | 1219 ----------------- linden/indra/newview/linux_tools/getvoice.sh | 5 +- linden/indra/newview/linux_tools/wrapper.sh | 8 +- linden/indra/newview/viewer_manifest.py | 248 ++-- linden/indra/newview/viewer_manifest.py~ | 1176 ---------------- linden/install.xml | 14 - 9 files changed, 143 insertions(+), 3589 deletions(-) delete mode 100644 linden/indra/cmake/GStreamer.cmake delete mode 100644 linden/indra/llmedia/llmediaimplgstreamer.cpp delete mode 100755 linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ delete mode 100755 linden/indra/newview/viewer_manifest.py~ diff --git a/linden/indra/cmake/GStreamer.cmake b/linden/indra/cmake/GStreamer.cmake deleted file mode 100644 index f5f9c03a1..000000000 --- a/linden/indra/cmake/GStreamer.cmake +++ /dev/null @@ -1,114 +0,0 @@ -# -*- cmake -*- -include(Prebuilt) - - # Maybe libxml and glib should have their own .cmake files - use_prebuilt_binary(libxml) - use_prebuilt_binary(glib) - - set(GSTREAMER_FOUND ON FORCE BOOL) - set(GSTREAMER_PLUGINS_BASE_FOUND ON FORCE BOOL) - - use_prebuilt_binary(gstreamer) - use_prebuilt_binary(gstreamer-plugins) - -if (WINDOWS) - - use_prebuilt_binary(iconv) - set(GSTREAMER_FOUND ON FORCE BOOL) - set(GSTREAMER_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gio - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gobject - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/iconv - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gst - ) - - set(GSTREAMER_LIBRARIES - glib-2.0 - gio-2.0 - gmodule-2.0 - gobject-2.0 - gthread-2.0 - libgstvideo.lib - libgsttag.lib - libgstsdp.lib - libgstrtsp.lib - libgstrtp.lib - libgstriff.lib - libgstreamer-0.10.lib - libgstpbutils.lib - libgstnetbuffer.lib - libgstnet-0.10.lib - libgstinterfaces.lib - libgstdshow.lib - libgstdataprotocol-0.10.lib - libgstcontroller-0.10.lib - libgstbase-0.10.lib - libgstaudio.lib - libgstapp.lib - libxml2 - libxml2_a - libxml2_a_dll - iconv - iconv_a - ) - -else (WINDOWS) - - set(GSTREAMER_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10 - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0/glib - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0/gobject - ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 - ) - - if (DARWIN) # Mac - - use_prebuilt_binary(flac) - use_prebuilt_binary(liboil) - use_prebuilt_binary(neon) - use_prebuilt_binary(theora) - - set(GSTREAMER_LIBRARIES - gstvideo-0.10 - gstaudio-0.10 - gstbase-0.10 - gstreamer-0.10 - gobject-2.0 - gmodule-2.0 - gthread-2.0 - glib-2.0 - xml2.2 - ) - - else (DARWIN) # Linux - - use_prebuilt_binary(liboil) - use_prebuilt_binary(theora) - - set(GSTREAMER_LIBRARIES - gstvideo-0.10 - gstaudio-0.10 - gstbase-0.10 - gstreamer-0.10 - gobject-2.0 - gmodule-2.0 - dl - gthread-2.0 - rt - glib-2.0 - ) - - endif (DARWIN) - -endif (WINDOWS) - -if (GSTREAMER_FOUND AND GSTREAMER_PLUGINS_BASE_FOUND) - set(GSTREAMER ON CACHE BOOL "Build with GStreamer streaming media support.") -endif (GSTREAMER_FOUND AND GSTREAMER_PLUGINS_BASE_FOUND) - -if (GSTREAMER) - add_definitions(-DLL_GSTREAMER_ENABLED=1) -endif (GSTREAMER) diff --git a/linden/indra/cmake/GStreamer010Plugin.cmake b/linden/indra/cmake/GStreamer010Plugin.cmake index 0d334837d..78ffd941a 100644 --- a/linden/indra/cmake/GStreamer010Plugin.cmake +++ b/linden/indra/cmake/GStreamer010Plugin.cmake @@ -19,14 +19,18 @@ elseif (LINUX) ) # We don't need to explicitly link against gstreamer itself, because # LLMediaImplGStreamer probes for the system's copy at runtime. - set(GSTREAMER010_LIBRARIES - gobject-2.0 - gmodule-2.0 - dl - gthread-2.0 - rt - glib-2.0 - ) + set(GSTREAMER010_LIBRARIES + gstvideo-0.10 + gstaudio-0.10 + gstbase-0.10 + gstreamer-0.10 + gobject-2.0 + gmodule-2.0 + dl + gthread-2.0 + rt + glib-2.0 + ) endif (STANDALONE) if (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND) diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp deleted file mode 100644 index 7af9c9ae4..000000000 --- a/linden/indra/llmedia/llmediaimplgstreamer.cpp +++ /dev/null @@ -1,928 +0,0 @@ -/** - * @file llmediaimplgstreamer.cpp - * @author Tofu Linden - * @brief implementation that supports various media through GStreamer. - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -///#if LL_GSTREAMER_ENABLED - -#if LL_WINDOWS - // GStreamer 0.10.22 - gstutils.h - conversion from 'guint64' to 'guint8'. - // This was an intentional change to make GStreamer more threadsafe, and - // is okay. Delete this bit if GStreamer ever gets more VS-friendly -- McCabe - #pragma warning(disable : 4244) -#endif - -#include "linden_common.h" -#include "llmediaimplgstreamer.h" - -extern "C" { -#include <gst/gst.h> -#include <gst/gstelement.h> -} - -#if LL_WINDOWS - #pragma warning(default : 4244) -#include <direct.h> -#include <stdlib.h> -#endif - -#include "llmediamanager.h" -#include "llmediaimplregister.h" - -#include "llmediaimplgstreamervidplug.h" -#include "llgstplaythread.h" - - -#if LL_DARWIN -#include <CoreFoundation/CoreFoundation.h> // For CF functions used in set_gst_plugin_path -#endif - -// register this impl with media manager factory -static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() ); - -LLMediaImplGStreamerMaker::LLMediaImplGStreamerMaker() -{ - // Register to handle the scheme - mSchema.push_back( "rtsp" ); - mSchema.push_back( "rtmp" ); - - // Register to handle the category - mMimeTypeCategories.push_back( "video" ); - mMimeTypeCategories.push_back( "audio" ); -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplGStreamer:: -LLMediaImplGStreamer () : - mediaData ( NULL ), - mMediaRowbytes ( 1 ), - mTextureFormatPrimary ( LL_MEDIA_BGRA ), - mTextureFormatType ( LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV ), - mPump ( NULL ), - mPlaybin ( NULL ), - mVideoSink ( NULL ), - mLastTitle ( "" ), - mState( GST_STATE_NULL ), - mPlayThread ( NULL ) -{ - startup( NULL ); // Startup gstreamer if it hasn't been already. - - LL_DEBUGS("MediaManager") << "constructing media..." << LL_ENDL; - mVolume = -1.0; // XXX Hack to make the vould change happend first time - - setMediaDepth(4); - - // Create a pumpable main-loop for this media - mPump = g_main_loop_new (NULL, FALSE); - if (!mPump) - { - return; // error - } - - // instantiate a playbin element to do the hard work - mPlaybin = gst_element_factory_make ("playbin", "play"); - if (!mPlaybin) - { - // todo: cleanup pump - return; // error - } - - if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) - { - // instantiate and connect a custom video sink - LL_DEBUGS("MediaManager") << "extrenal video sink..." << LL_ENDL; - - // Plays inworld instead of in external player - mVideoSink = - GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo")); - if (!mVideoSink) - { - LL_WARNS("MediaImpl") << "Could not instantiate private-slvideo element." << LL_ENDL; - // todo: cleanup. - return; // error - } - - g_object_set(mPlaybin, "video-sink", mVideoSink, (void*)NULL); - } -} - -// virtual -int LLMediaImplGStreamer::getTextureFormatPrimary() const -{ - return mTextureFormatPrimary; -} - -// virtual -int LLMediaImplGStreamer::getTextureFormatType() const -{ - return mTextureFormatType; -} - -// virtual -int LLMediaImplGStreamer::getTextureFormatInternal() const -{ - return LL_MEDIA_RGB8; -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplGStreamer:: -~LLMediaImplGStreamer () -{ - LL_DEBUGS("MediaImpl") << ("dtor of media...") << LL_ENDL; - unload(); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -std::string LLMediaImplGStreamer::getVersion() -{ - guint major, minor, micro, nano; - gst_version(&major, &minor, µ, &nano); - std::string version = llformat("%d.%d.%d.%d",major,minor,micro,nano); - return version; -} - -// -// STARTUP -/////////////////////////////////////////////////////////////////////////////// -// (static) super-initialization - called once at application startup -bool LLMediaImplGStreamer::startup (LLMediaManagerData* init_data) -{ - static bool done_init = false; - if (!done_init) - { - // Init the glib type system - we need it. - g_type_init(); - - set_gst_plugin_path(); - - // Protect against GStreamer resetting the locale, yuck. - static std::string saved_locale; - saved_locale = setlocale(LC_ALL, NULL); - if (0 == gst_init_check(NULL, NULL, NULL)) - { - LL_WARNS("MediaImpl") << "GStreamer library failed to initialize and load standard plugins." << LL_ENDL; - setlocale(LC_ALL, saved_locale.c_str() ); - return false; - } - setlocale(LC_ALL, saved_locale.c_str() ); - - // Set up logging facilities - gst_debug_remove_log_function( gst_debug_log_default ); - gst_debug_add_log_function( gstreamer_log, NULL ); - - // Init our custom plugins - only really need do this once. - gst_slvideo_init_class(); - - - // List the plugins GStreamer can find - LL_DEBUGS("MediaImpl") << "Found GStreamer plugins:" << LL_ENDL; - GList *list; - GstRegistry *registry = gst_registry_get_default(); - std::string loaded = ""; - for (list = gst_registry_get_plugin_list(registry); - list != NULL; - list = g_list_next(list)) - { - GstPlugin *list_plugin = (GstPlugin *)list->data; - (bool)gst_plugin_is_loaded(list_plugin) ? loaded = "Yes" : loaded = "No"; - LL_DEBUGS("MediaImpl") << gst_plugin_get_name(list_plugin) << ", loaded? " << loaded << LL_ENDL; - } - gst_plugin_list_free(list); - - - done_init = true; - } - return true; -} - - -void LLMediaImplGStreamer::set_gst_plugin_path() -{ - // Linux sets GST_PLUGIN_PATH in wrapper.sh, not here. -#if LL_WINDOWS || LL_DARWIN - - std::string imp_dir = ""; - - // Get the current working directory: -#if LL_WINDOWS - char* raw_dir; - raw_dir = _getcwd(NULL,0); - if( raw_dir != NULL ) - { - imp_dir = std::string( raw_dir ); - } -#elif LL_DARWIN - CFBundleRef main_bundle = CFBundleGetMainBundle(); - if( main_bundle != NULL ) - { - CFURLRef bundle_url = CFBundleCopyBundleURL( main_bundle ); - if( bundle_url != NULL ) - { - #ifndef MAXPATHLEN - #define MAXPATHLEN 1024 - #endif - char raw_dir[MAXPATHLEN]; - if( CFURLGetFileSystemRepresentation( bundle_url, true, (UInt8 *)raw_dir, MAXPATHLEN) ) - { - imp_dir = std::string( raw_dir ) + "/Contents/MacOS/"; - } - CFRelease(bundle_url); - } - } -#endif - - if( imp_dir == "" ) - { - LL_WARNS("MediaImpl") << "Could not get application directory, not setting GST_PLUGIN_PATH." - << LL_ENDL; - return; - } - - LL_DEBUGS("MediaImpl") << "Imprudence is installed at " - << imp_dir << LL_ENDL; - - // ":" on Mac and 'Nix, ";" on Windows - std::string separator = G_SEARCHPATH_SEPARATOR_S; - - // Grab the current path, if it's set. - std::string old_plugin_path = ""; - char *old_path = getenv("GST_PLUGIN_PATH"); - if(old_path == NULL) - { - LL_DEBUGS("MediaImpl") << "Did not find user-set GST_PLUGIN_PATH." - << LL_ENDL; - } - else - { - old_plugin_path = separator + std::string( old_path ); - } - - - // Search both Imprudence and Imprudence\lib\gstreamer-plugins. - // But we also want to search the path the user has set, if any. - std::string plugin_path = -#if LL_WINDOWS - imp_dir + "\\lib\\gstreamer-plugins" + -#elif LL_DARWIN - imp_dir + separator + - imp_dir + "/../Resources/lib/gstreamer-plugins" + -#endif - old_plugin_path; - - int put_result; - - // Place GST_PLUGIN_PATH in the environment settings -#if LL_WINDOWS - put_result = _putenv_s( "GST_PLUGIN_PATH", (char*)plugin_path.c_str() ); -#elif LL_DARWIN - put_result = setenv( "GST_PLUGIN_PATH", (char*)plugin_path.c_str(), 1 ); -#endif - - if( put_result == -1 ) - { - LL_WARNS("MediaImpl") << "Setting GST_PLUGIN_PATH failed!" << LL_ENDL; - } - else - { - LL_DEBUGS("MediaImpl") << "GST_PLUGIN_PATH set to " - << getenv("GST_PLUGIN_PATH") << LL_ENDL; - } - - // Don't load system plugins. We only want to use ours, to avoid conflicts. -#if LL_WINDOWS - put_result = _putenv_s( "GST_PLUGIN_SYSTEM_PATH", "" ); -#elif LL_DARWIN - put_result = setenv( "GST_PLUGIN_SYSTEM_PATH", "", 1 ); -#endif - - if( put_result == -1 ) - { - LL_WARNS("MediaImpl") << "Setting GST_PLUGIN_SYSTEM_PATH=\"\" failed!" - << LL_ENDL; - } - -#endif // LL_WINDOWS || LL_DARWIN -} - - -void LLMediaImplGStreamer::gstreamer_log(GstDebugCategory *category, - GstDebugLevel level, - const gchar *file, - const gchar *function, - gint line, - GObject *object, - GstDebugMessage *message, - gpointer data) -{ - std::stringstream log(std::stringstream::out); - - // Log format example: - // - // GST_ELEMENT_PADS: removing pad 'sink' (in gstelement.c:757:gst_element_remove_pad) - // - log << gst_debug_category_get_name( category ) << ": " - << gst_debug_message_get(message) << " " - << "(in " << file << ":" << line << ":" << function << ")"; - - switch( level ) - { - case GST_LEVEL_ERROR: - LL_WARNS("MediaImpl") << "(ERROR) " << log.str() << LL_ENDL; - break; - case GST_LEVEL_WARNING: - LL_WARNS("MediaImpl") << log.str() << LL_ENDL; - break; - case GST_LEVEL_DEBUG: - LL_DEBUGS("MediaImpl") << log.str() << LL_ENDL; - break; - case GST_LEVEL_INFO: - LL_INFOS("MediaImpl") << log.str() << LL_ENDL; - break; - default: - // Do nothing. - break; - } -} - - -bool LLMediaImplGStreamer::closedown() -{ - return true; -} - - -bool LLMediaImplGStreamer::setDebugLevel( LLMediaBase::EDebugLevel level ) -{ - // Do parent class stuff. - LLMediaImplCommon::setDebugLevel(level); - - // Set GStreamer verbosity. - gst_debug_set_default_threshold( (GstDebugLevel)level ); - - return true; -} - - -/////////////////////////////////////////////////////////////////////////////// -// -// Uncomment the line below to enable spammy debug data. -//#define LL_GST_REPORT_STATE_CHANGES -#ifdef LL_GST_REPORT_STATE_CHANGES -static const char* get_gst_state_name(GstState state) -{ - switch (state) - { - case GST_STATE_VOID_PENDING: return "VOID_PENDING"; - case GST_STATE_NULL: return "NULL"; - case GST_STATE_READY: return "READY"; - case GST_STATE_PAUSED: return "PAUSED"; - case GST_STATE_PLAYING: return "PLAYING"; - } - return "(unknown)"; -} -#endif // LL_GST_REPORT_STATE_CHANGES - -//static -gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gpointer data) -{ -#ifdef LL_GST_REPORT_STATE_CHANGES - LL_DEBUGS("MediaCallback") << "Got GST message type: " << GST_MESSAGE_TYPE_NAME (message) << LL_ENDL; -#endif - - LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; - - switch (GST_MESSAGE_TYPE (message)) - { - case GST_MESSAGE_BUFFERING: - { - gint percent = 0; - gst_message_parse_buffering(message, &percent); -#ifdef LL_GST_REPORT_STATE_CHANGES - LL_DEBUGS("MediaBuffering") << "GST buffering: " << percent << "%%" << LL_ENDL; -#endif - LLMediaEvent event( impl, percent ); - impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); - } - break; - case GST_MESSAGE_STATE_CHANGED: - { - GstState old_state; - GstState new_state; - GstState pending_state; - gst_message_parse_state_changed(message, - &old_state, - &new_state, - &pending_state); -#ifdef LL_GST_REPORT_STATE_CHANGES - // not generally very useful, and rather spammy. - LL_DEBUGS("MediaState") << "GST state change (old,<new>,pending): "<< get_gst_state_name(old_state) << ",<" << get_gst_state_name(new_state) << ">," << get_gst_state_name(pending_state) << LL_ENDL; -#endif // LL_GST_REPORT_STATE_CHANGES - - switch (new_state) - { - case GST_STATE_VOID_PENDING: - break; - case GST_STATE_NULL: -#ifdef LL_GST_REPORT_STATE_CHANGES - LL_DEBUGS("MediaImpl") << "State changed to NULL" << LL_ENDL; -#endif - if (impl->getState() == GST_STATE_PLAYING) - { - // Stream was probably dropped, trying to restart - impl->play(); -#ifdef LL_GST_REPORT_STATE_CHANGES - LL_DEBUGS("MediaImpl") << "Trying to restart." << LL_ENDL; -#endif - } - break; - case GST_STATE_READY: - break; - case GST_STATE_PAUSED: - break; - case GST_STATE_PLAYING: - //impl->mLastTitle = ""; - - LLMediaEvent event( impl, 100 ); - impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); - // emit an event to say that a media source was loaded - LLMediaEvent event2( impl ); - impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 ); - break; - } - break; - } - case GST_MESSAGE_ERROR: - { - GError *err = NULL; - gchar *debug = NULL; - - gst_message_parse_error (message, &err, &debug); - LL_WARNS("MediaImpl") << "GST Error: " << err->message << LL_ENDL; - g_error_free (err); - g_free (debug); - - impl->addCommand(LLMediaBase::COMMAND_STOP); - //impl->addCommand(LLMediaBase::COMMAND_START); - - break; - } - case GST_MESSAGE_INFO: - { - GError *err = NULL; - gchar *debug = NULL; - - gst_message_parse_info (message, &err, &debug); - LL_INFOS("MediaImpl") << "GST info: " << err->message - << LL_ENDL; - g_error_free (err); - g_free (debug); - break; - } - case GST_MESSAGE_WARNING: - { - GError *err = NULL; - gchar *debug = NULL; - - gst_message_parse_warning (message, &err, &debug); - LL_WARNS("MediaImpl") << "GST warning: " << err->message - << LL_ENDL; - g_error_free (err); - g_free (debug); - - break; - } - case GST_MESSAGE_TAG: - { - GstTagList *new_tags; - - gst_message_parse_tag( message, &new_tags ); - - gchar *title; - - if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) ) - { - LL_INFOS("MediaInfo") << "Title: " << title << LL_ENDL; - std::string newtitle(title); - gst_tag_list_free(new_tags); - - if ( newtitle != impl->mLastTitle && newtitle != "" ) - { - impl->mLastTitle = newtitle; - LLMediaEvent event( impl, impl->mLastTitle ); - impl->getEventEmitter().update( &LLMediaObserver::onMediaTitleChange, event ); - } - - g_free(title); - } - - break; - } - case GST_MESSAGE_EOS: - { - /* end-of-stream */ - LL_DEBUGS("MediaImpl") << "GST end-of-stream." << LL_ENDL; - if (impl->isLooping()) - { - LL_DEBUGS("MediaImpl") << "looping media..." << LL_ENDL; - impl->stop(); - impl->play(); - } - else - { - // inject a COMMAND_STOP - impl->addCommand(LLMediaBase::COMMAND_STOP); - } - break; - } - default: - /* unhandled message */ - break; - } - /* we want to be notified again the next time there is a message - * on the bus, so return true (false means we want to stop watching - * for messages on the bus and our callback should not be called again) - */ - return TRUE; -} - -/////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplGStreamer::navigateTo (const std::string urlIn) -{ - LL_DEBUGS("MediaImpl") << "Setting media URI: " << urlIn.c_str() - << LL_ENDL; - - if (mPump == NULL || mPlaybin == NULL) - { - return false; - } - - setStatus( LLMediaBase::STATUS_NAVIGATING ); - - // set URI - g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), (void*)NULL); - - // get playbin's bus - perhaps this can/should be done in ctor - GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); - if (!bus) - { - return false; - } - gst_bus_add_watch (bus, bus_callback, this); - gst_object_unref (bus); - - mState = GST_STATE_READY; - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplGStreamer::unload() -{ - LL_DEBUGS("MediaImpl") << "unloading media..." << LL_ENDL; - if (mPlaybin) - { - gst_element_set_state (mPlaybin, GST_STATE_NULL); - mState = GST_STATE_NULL; - gst_object_unref (GST_OBJECT (mPlaybin)); - mPlaybin = NULL; - } - - if (mPump) - { - g_main_loop_quit(mPump); - mPump = NULL; - } - - if (mediaData) - { - delete [] mediaData; - mediaData = NULL; - } - - mVideoSink = NULL; - mState = GST_STATE_NULL; - setStatus(LLMediaBase::STATUS_UNKNOWN); - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplGStreamer::updateMedia() -{ - //LL_DEBUGS("MediaImpl") << "updating media..." << LL_ENDL; - - // sanity check - if (mPump == NULL || mPlaybin == NULL) - { -#ifdef LL_GST_REPORT_STATE_CHANGES - LL_DEBUGS("MediaImpl") << "dead media..." << LL_ENDL; -#endif - mState = GST_STATE_NULL; - setStatus(LLMediaBase::STATUS_DEAD); - return false; - } - - if (mState == GST_STATE_VOID_PENDING || mState == GST_STATE_NULL) - return false; - - // process next outstanding command - switch (nextCommand()) - { - case LLMediaBase::COMMAND_START: - LL_DEBUGS("MediaImpl") << "COMMAND_START" << LL_ENDL; - if (getStatus() == LLMediaBase::STATUS_PAUSED || - getStatus() == LLMediaBase::STATUS_NAVIGATING || - getStatus() == LLMediaBase::STATUS_STOPPED) - { - play(); - setStatus(LLMediaBase::STATUS_STARTED); - clearCommand(); - } - break; - case LLMediaBase::COMMAND_STOP: - LL_DEBUGS("MediaImpl") << "COMMAND_STOP" << LL_ENDL; - stop(); - setStatus(LLMediaBase::STATUS_STOPPED); - clearCommand(); - break; - case LLMediaBase::COMMAND_PAUSE: - LL_DEBUGS("MediaImpl") << "COMMAND_PAUSE" << LL_ENDL; - if (getStatus() == LLMediaBase::STATUS_STARTED) - { - pause(); - setStatus(LLMediaBase::STATUS_PAUSED); - clearCommand(); - } - break; - default: - LL_INFOS("MediaImpl") << "Unknown command" << LL_ENDL; - clearCommand(); - break; - case LLMediaBase::COMMAND_NONE: - break; - } - - // deal with results - if (g_main_context_pending(g_main_loop_get_context(mPump))) - { - g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); - } - - if (mVideoSink) - { - GST_OBJECT_LOCK(mVideoSink); - if (mVideoSink->retained_frame_ready) - { -#ifdef LL_GST_REPORT_STATE_CHANGES - LL_DEBUGS("MediaImpl") <<"NEW FRAME " << LL_ENDL; -#endif - if (mVideoSink->retained_frame_width != getMediaWidth() || - mVideoSink->retained_frame_height != getMediaHeight()) - // *TODO: also check for change in format - { - // just resize containe - int neww = mVideoSink->retained_frame_width; - int newh = mVideoSink->retained_frame_height; - int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; - if (SLV_PF_RGBX == mVideoSink->retained_frame_format) - { - mTextureFormatPrimary = LL_MEDIA_RGBA; - mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; - } - else - { - mTextureFormatPrimary = LL_MEDIA_BGRA; - mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; - } - mMediaRowbytes = neww * newd; - LL_DEBUGS("MediaImpl") - << "video container resized to " << - neww <<"x"<< newh << LL_ENDL; - - delete[] mediaData; - mediaData = new unsigned char[mMediaRowbytes * - newh]; - - GST_OBJECT_UNLOCK(mVideoSink); - - setMediaDepth(newd); - setMediaSize(neww, newh); - return true; - } - - // we're gonna totally consume this frame - reset 'ready' flag - mVideoSink->retained_frame_ready = FALSE; - memcpy(mediaData, mVideoSink->retained_frame_data, - mMediaRowbytes * getMediaHeight()); - - GST_OBJECT_UNLOCK(mVideoSink); - LLMediaEvent event( this ); - mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); - return true; - } - else - { - // nothing to do yet. - GST_OBJECT_UNLOCK(mVideoSink); - return true; - } - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplGStreamer::stop() -{ - LL_DEBUGS("MediaImpl") << "attempting to stop..." << LL_ENDL; - - if (!mPlaybin || mState == GST_STATE_NULL) - return true; - - GstStateChangeReturn state_change; - - state_change = gst_element_set_state(mPlaybin, GST_STATE_READY); - - LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; - - if (state_change == GST_STATE_CHANGE_FAILURE) - { - LL_WARNS("MediaImpl") << "could not stop stream!" << LL_ENDL; - return false; - } - else - { - // Going into pending after play keeps dead streams from looping - (mState == GST_STATE_PLAYING) ? (mState = GST_STATE_VOID_PENDING) : (mState = GST_STATE_READY); - return true; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplGStreamer::play() -{ - LL_DEBUGS("MediaImpl") << "attempting to play..." << LL_ENDL; - - if (!mPlaybin || mState == GST_STATE_NULL) - return true; - - - if( getState() == GST_STATE_PLAYING ) - { - LL_DEBUGS("MediaImpl") << "... but already playing." << LL_ENDL; - return true; - } - - // Clean up the existing thread, if any. - if( mPlayThread != NULL && mPlayThread->isStopped()) - { - delete mPlayThread; - mPlayThread = NULL; - } - - if( mPlayThread == NULL ) - { - // Make a new thread to start playing. This keeps the viewer - // responsive while the stream is resolved and buffered. - mPlayThread = new LLGstPlayThread( (LLMediaImplCommon *)this, "GstPlayThread", NULL); - mPlayThread->start(); - } - - return true; -} - - -void LLMediaImplGStreamer::startPlay() -{ - GstStateChangeReturn state_change; - - state_change = gst_element_set_state(mPlaybin, GST_STATE_PLAYING); - mState = GST_STATE_PLAYING; - - LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; - - // Check to make sure playing was successful. If not, stop. - // NOTE: state_change is almost always GST_STATE_CHANGE_ASYNC - if (state_change == GST_STATE_CHANGE_FAILURE) - { - // If failing from a bad stream, go into an unknown - // state to stop bus_callback from looping back. - // We also force a stop in case the operations don't sync - setStatus(LLMediaBase::STATUS_UNKNOWN); - stop(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaImplGStreamer::pause() -{ - LL_DEBUGS("MediaImpl") << "attempting to pause..." << LL_ENDL; - - if (!mPlaybin || mState == GST_STATE_NULL) - return true; - - GstStateChangeReturn state_change; - - state_change = gst_element_set_state(mPlaybin, GST_STATE_PAUSED); - - LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; - - if (state_change == GST_STATE_CHANGE_FAILURE) - { - LL_WARNS("MediaImpl") << "could not pause stream!" << LL_ENDL; - return false; - } - else - { - mState = GST_STATE_PAUSED; - return true; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// virtual -unsigned char* LLMediaImplGStreamer::getMediaData() -{ - return mediaData; -} - - -/////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplGStreamer::seek(double time) -{ - bool success = false; - if (mPlaybin) - { - success = gst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, - GstSeekFlags(GST_SEEK_FLAG_FLUSH | - GST_SEEK_FLAG_KEY_UNIT), - GST_SEEK_TYPE_SET, gint64(time*1000000000.0F), - GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); - } - LL_DEBUGS("MediaImpl") << "MEDIA SEEK REQUEST to " << float(time) - << "sec result was " << int(success) << LL_ENDL; - return success; -} - - -/////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaImplGStreamer::setVolume(float volume) -{ - // we try to only update volume as conservatively as - // possible, as many gst-plugins-base versions up to at least - // November 2008 have critical race-conditions in setting volume - sigh - if (mVolume == volume) - return true; // nothing to do, everything's fine - - mVolume = volume; - if (mPlaybin) - { - g_object_set(mPlaybin, "volume", mVolume, (void*)NULL); - return true; - } - - return false; -} - - - -///#endif // LL_GSTREAMER_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ deleted file mode 100755 index 7d34a1ec0..000000000 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp~ +++ /dev/null @@ -1,1219 +0,0 @@ -/** - * @file media_plugin_gstreamer010.cpp - * @brief GStreamer-0.10 plugin for LLMedia API plugin system - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2010, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - * - * @endcond - */ - -#include "linden_common.h" - -#include "llgl.h" - -#include "llplugininstance.h" -#include "llpluginmessage.h" -#include "llpluginmessageclasses.h" -#include "media_plugin_base.h" - -#if LL_GSTREAMER010_ENABLED - -extern "C" { -#include <gst/gst.h> -} - -#include "llmediaimplgstreamer.h" -#include "llmediaimplgstreamertriviallogging.h" - -#include "llmediaimplgstreamervidplug.h" - -#include "llmediaimplgstreamer_syms.h" - -////////////////////////////////////////////////////////////////////////////// -// -class MediaPluginGStreamer010 : public MediaPluginBase -{ -public: - MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginGStreamer010(); - - /* virtual */ void receiveMessage(const char *message_string); - - static bool startup(); - static bool closedown(); - - gboolean processGSTEvents(GstBus *bus, - GstMessage *message); - -private: - std::string getVersion(); - bool navigateTo( const std::string urlIn ); - bool seek( double time_sec ); - bool setVolume( float volume ); - - // misc - bool pause(); - bool stop(); - bool play(double rate); - bool getTimePos(double &sec_out); - - static const double MIN_LOOP_SEC = 1.0F; - - bool mIsLooping; - - enum ECommand { - COMMAND_NONE, - COMMAND_STOP, - COMMAND_PLAY, - COMMAND_FAST_FORWARD, - COMMAND_FAST_REWIND, - COMMAND_PAUSE, - COMMAND_SEEK, - }; - ECommand mCommand; - -private: - bool unload(); - bool load(); - - bool update(int milliseconds); - void mouseDown( int x, int y ); - void mouseUp( int x, int y ); - void mouseMove( int x, int y ); - - void sizeChanged(); - - static bool mDoneInit; - - guint mBusWatchID; - - float mVolume; - - int mDepth; - - // media NATURAL size - int mNaturalWidth; - int mNaturalHeight; - // media current size - int mCurrentWidth; - int mCurrentHeight; - int mCurrentRowbytes; - // previous media size so we can detect changes - int mPreviousWidth; - int mPreviousHeight; - // desired render size from host - int mWidth; - int mHeight; - // padded texture size we need to write into - int mTextureWidth; - int mTextureHeight; - - int mTextureFormatPrimary; - int mTextureFormatType; - - bool mSeekWanted; - double mSeekDestination; - - // Very GStreamer-specific - GMainLoop *mPump; // event pump for this media - GstElement *mPlaybin; - GstSLVideo *mVideoSink; -}; - -//static -bool MediaPluginGStreamer010::mDoneInit = false; - -MediaPluginGStreamer010::MediaPluginGStreamer010( - LLPluginInstance::sendMessageFunction host_send_func, - void *host_user_data ) : - MediaPluginBase(host_send_func, host_user_data), - mBusWatchID ( 0 ), - mCurrentRowbytes ( 4 ), - mTextureFormatPrimary ( GL_RGBA ), - mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ), - mSeekWanted(false), - mSeekDestination(0.0), - mPump ( NULL ), - mPlaybin ( NULL ), - mVideoSink ( NULL ), - mCommand ( COMMAND_NONE ) -{ - std::ostringstream str; - INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid())); -} - -/////////////////////////////////////////////////////////////////////////////// -// -//#define LL_GST_REPORT_STATE_CHANGES -#ifdef LL_GST_REPORT_STATE_CHANGES -static char* get_gst_state_name(GstState state) -{ - switch (state) { - case GST_STATE_VOID_PENDING: return "VOID_PENDING"; - case GST_STATE_NULL: return "NULL"; - case GST_STATE_READY: return "READY"; - case GST_STATE_PAUSED: return "PAUSED"; - case GST_STATE_PLAYING: return "PLAYING"; - } - return "(unknown)"; -} -#endif // LL_GST_REPORT_STATE_CHANGES - -gboolean -MediaPluginGStreamer010::processGSTEvents(GstBus *bus, - GstMessage *message) -{ - if (!message) - return TRUE; // shield against GStreamer bug - - if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && - GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) - { - DEBUGMSG("Got GST message type: %s", - LLGST_MESSAGE_TYPE_NAME (message)); - } - else - { - // TODO: grok 'duration' message type - DEBUGMSG("Got GST message type: %s", - LLGST_MESSAGE_TYPE_NAME (message)); - } - - switch (GST_MESSAGE_TYPE (message)) { - case GST_MESSAGE_BUFFERING: { - // NEEDS GST 0.10.11+ - if (llgst_message_parse_buffering) - { - gint percent = 0; - llgst_message_parse_buffering(message, &percent); - DEBUGMSG("GST buffering: %d%%", percent); - } - break; - } - case GST_MESSAGE_STATE_CHANGED: { - GstState old_state; - GstState new_state; - GstState pending_state; - llgst_message_parse_state_changed(message, - &old_state, - &new_state, - &pending_state); -#ifdef LL_GST_REPORT_STATE_CHANGES - // not generally very useful, and rather spammy. - DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", - get_gst_state_name(old_state), - get_gst_state_name(new_state), - get_gst_state_name(pending_state)); -#endif // LL_GST_REPORT_STATE_CHANGES - - switch (new_state) { - case GST_STATE_VOID_PENDING: - break; - case GST_STATE_NULL: - break; - case GST_STATE_READY: - setStatus(STATUS_LOADED); - break; - case GST_STATE_PAUSED: - setStatus(STATUS_PAUSED); - break; - case GST_STATE_PLAYING: - setStatus(STATUS_PLAYING); - break; - } - break; - } - case GST_MESSAGE_ERROR: { - GError *err = NULL; - gchar *debug = NULL; - - llgst_message_parse_error (message, &err, &debug); - WARNMSG("GST error: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); - - mCommand = COMMAND_STOP; - - setStatus(STATUS_ERROR); - - break; - } - case GST_MESSAGE_INFO: { - if (llgst_message_parse_info) - { - GError *err = NULL; - gchar *debug = NULL; - - llgst_message_parse_info (message, &err, &debug); - INFOMSG("GST info: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); - } - break; - } - case GST_MESSAGE_WARNING: { - GError *err = NULL; - gchar *debug = NULL; - - llgst_message_parse_warning (message, &err, &debug); - WARNMSG("GST warning: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); - - break; - } - case GST_MESSAGE_EOS: - /* end-of-stream */ - DEBUGMSG("GST end-of-stream."); - if (mIsLooping) - { - DEBUGMSG("looping media..."); - double eos_pos_sec = 0.0F; - bool got_eos_position = getTimePos(eos_pos_sec); - - if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) - { - // if we know that the movie is really short, don't - // loop it else it can easily become a time-hog - // because of GStreamer spin-up overhead - DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); - // inject a COMMAND_PAUSE - mCommand = COMMAND_PAUSE; - } - else - { -#undef LLGST_LOOP_BY_SEEKING -// loop with a stop-start instead of a seek, because it actually seems rather -// faster than seeking on remote streams. -#ifdef LLGST_LOOP_BY_SEEKING - // first, try looping by an explicit rewind - bool seeksuccess = seek(0.0); - if (seeksuccess) - { - play(1.0); - } - else -#endif // LLGST_LOOP_BY_SEEKING - { // use clumsy stop-start to loop - DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); - stop(); - play(1.0); - } - } - } - else // not a looping media - { - // inject a COMMAND_STOP - mCommand = COMMAND_STOP; - } - break; - default: - /* unhandled message */ - break; - } - - /* we want to be notified again the next time there is a message - * on the bus, so return true (false means we want to stop watching - * for messages on the bus and our callback should not be called again) - */ - return TRUE; -} - -extern "C" { -gboolean -llmediaimplgstreamer_bus_callback (GstBus *bus, - GstMessage *message, - gpointer data) -{ - MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data; - return impl->processGSTEvents(bus, message); -} -} // extern "C" - - - -bool -MediaPluginGStreamer010::navigateTo ( const std::string urlIn ) -{ - if (!mDoneInit) - return false; // error - - setStatus(STATUS_LOADING); - - DEBUGMSG("Setting media URI: %s", urlIn.c_str()); - - mSeekWanted = false; - - if (NULL == mPump || - NULL == mPlaybin) - { - setStatus(STATUS_ERROR); - return false; // error - } - - // set URI - g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); - //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); - - // navigateTo implicitly plays, too. - play(1.0); - - return true; -} - - -bool -MediaPluginGStreamer010::update(int milliseconds) -{ - if (!mDoneInit) - return false; // error - - DEBUGMSG("updating media..."); - - // sanity check - if (NULL == mPump || - NULL == mPlaybin) - { - DEBUGMSG("dead media..."); - return false; - } - - // see if there's an outstanding seek wanted - if (mSeekWanted && - // bleh, GST has to be happy that the movie is really truly playing - // or it may quietly ignore the seek (with rtsp:// at least). - (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) - { - seek(mSeekDestination); - mSeekWanted = false; - } - - // *TODO: time-limit - but there isn't a lot we can do here, most - // time is spent in gstreamer's own opaque worker-threads. maybe - // we can do something sneaky like only unlock the video object - // for 'milliseconds' and otherwise hold the lock. - while (g_main_context_pending(g_main_loop_get_context(mPump))) - { - g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); - } - - // check for availability of a new frame - - if (mVideoSink) - { - GST_OBJECT_LOCK(mVideoSink); - if (mVideoSink->retained_frame_ready) - { - DEBUGMSG("NEW FRAME READY"); - - if (mVideoSink->retained_frame_width != mCurrentWidth || - mVideoSink->retained_frame_height != mCurrentHeight) - // *TODO: also check for change in format - { - // just resize container, don't consume frame - int neww = mVideoSink->retained_frame_width; - int newh = mVideoSink->retained_frame_height; - - int newd = 4; - mTextureFormatPrimary = GL_RGBA; - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; - - /* - int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; - if (SLV_PF_BGRX == mVideoSink->retained_frame_format) - { - mTextureFormatPrimary = GL_BGRA; - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; - } - else - { - mTextureFormatPrimary = GL_RGBA; - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; - } - */ - - GST_OBJECT_UNLOCK(mVideoSink); - - mCurrentRowbytes = neww * newd; - DEBUGMSG("video container resized to %dx%d", - neww, newh); - - mDepth = newd; - mCurrentWidth = neww; - mCurrentHeight = newh; - sizeChanged(); - return true; - } - - if (mPixels && - mCurrentHeight <= mHeight && - mCurrentWidth <= mWidth && - !mTextureSegmentName.empty()) - { - // we're gonna totally consume this frame - reset 'ready' flag - mVideoSink->retained_frame_ready = FALSE; - int destination_rowbytes = mWidth * mDepth; - for (int row=0; row<mCurrentHeight; ++row) - { - memcpy(&mPixels - [destination_rowbytes * row], - &mVideoSink->retained_frame_data - [mCurrentRowbytes * row], - mCurrentRowbytes); - } - - GST_OBJECT_UNLOCK(mVideoSink); - DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); - - setDirty(0,0,mCurrentWidth,mCurrentHeight); - } - else - { - // new frame ready, but we're not ready to - // consume it. - - GST_OBJECT_UNLOCK(mVideoSink); - - DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize"); - } - - return true; - } - else - { - // nothing to do yet. - GST_OBJECT_UNLOCK(mVideoSink); - return true; - } - } - - return true; -} - - -void -MediaPluginGStreamer010::mouseDown( int x, int y ) -{ - // do nothing -} - -void -MediaPluginGStreamer010::mouseUp( int x, int y ) -{ - // do nothing -} - -void -MediaPluginGStreamer010::mouseMove( int x, int y ) -{ - // do nothing -} - - -bool -MediaPluginGStreamer010::pause() -{ - DEBUGMSG("pausing media..."); - // todo: error-check this? - llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); - return true; -} - -bool -MediaPluginGStreamer010::stop() -{ - DEBUGMSG("stopping media..."); - // todo: error-check this? - llgst_element_set_state(mPlaybin, GST_STATE_READY); - return true; -} - -bool -MediaPluginGStreamer010::play(double rate) -{ - // NOTE: we don't actually support non-natural rate. - - DEBUGMSG("playing media... rate=%f", rate); - // todo: error-check this? - llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); - return true; -} - -bool -MediaPluginGStreamer010::setVolume( float volume ) -{ - // we try to only update volume as conservatively as - // possible, as many gst-plugins-base versions up to at least - // November 2008 have critical race-conditions in setting volume - sigh - if (mVolume == volume) - return true; // nothing to do, everything's fine - - mVolume = volume; - if (mDoneInit && mPlaybin) - { - g_object_set(mPlaybin, "volume", mVolume, NULL); - return true; - } - - return false; -} - -bool -MediaPluginGStreamer010::seek(double time_sec) -{ - bool success = false; - if (mDoneInit && mPlaybin) - { - success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, - GstSeekFlags(GST_SEEK_FLAG_FLUSH | - GST_SEEK_FLAG_KEY_UNIT), - GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), - GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); - } - DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", - float(time_sec), int(success)); - return success; -} - -bool -MediaPluginGStreamer010::getTimePos(double &sec_out) -{ - bool got_position = false; - if (mPlaybin) - { - gint64 pos; - GstFormat timefmt = GST_FORMAT_TIME; - got_position = - llgst_element_query_position && - llgst_element_query_position(mPlaybin, - &timefmt, - &pos); - got_position = got_position - && (timefmt == GST_FORMAT_TIME); - // GStreamer may have other ideas, but we consider the current position - // undefined if not PLAYING or PAUSED - got_position = got_position && - (GST_STATE(mPlaybin) == GST_STATE_PLAYING || - GST_STATE(mPlaybin) == GST_STATE_PAUSED); - if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) - { - if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) - { - // if we're playing then we treat an invalid clock time - // as 0, for complicated reasons (insert reason here) - pos = 0; - } - else - { - got_position = false; - } - - } - // If all the preconditions succeeded... we can trust the result. - if (got_position) - { - sec_out = double(pos) / double(GST_SECOND); // gst to sec - } - } - return got_position; -} - -bool -MediaPluginGStreamer010::load() -{ - if (!mDoneInit) - return false; // error - - setStatus(STATUS_LOADING); - - DEBUGMSG("setting up media..."); - - mIsLooping = false; - mVolume = 0.1234567; // minor hack to force an initial volume update - - // Create a pumpable main-loop for this media - mPump = g_main_loop_new (NULL, FALSE); - if (!mPump) - { - setStatus(STATUS_ERROR); - return false; // error - } - - // instantiate a playbin element to do the hard work - mPlaybin = llgst_element_factory_make ("playbin", "play"); - if (!mPlaybin) - { - setStatus(STATUS_ERROR); - return false; // error - } - - // get playbin's bus - GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); - if (!bus) - { - setStatus(STATUS_ERROR); - return false; // error - } - mBusWatchID = llgst_bus_add_watch (bus, - llmediaimplgstreamer_bus_callback, - this); - llgst_object_unref (bus); - - if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { - // instantiate a custom video sink - mVideoSink = - GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); - if (!mVideoSink) - { - WARNMSG("Could not instantiate private-slvideo element."); - // todo: cleanup. - setStatus(STATUS_ERROR); - return false; // error - } - - // connect the pieces - g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); - } - - return true; -} - -bool -MediaPluginGStreamer010::unload () -{ - if (!mDoneInit) - return false; // error - - DEBUGMSG("unloading media..."); - - // stop getting callbacks for this bus - g_source_remove(mBusWatchID); - mBusWatchID = 0; - - if (mPlaybin) - { - llgst_element_set_state (mPlaybin, GST_STATE_NULL); - llgst_object_unref (GST_OBJECT (mPlaybin)); - mPlaybin = NULL; - } - - if (mPump) - { - g_main_loop_quit(mPump); - mPump = NULL; - } - - mVideoSink = NULL; - - setStatus(STATUS_NONE); - - return true; -} - - -//static -bool -MediaPluginGStreamer010::startup() -{ - // first - check if GStreamer is explicitly disabled - if (NULL != getenv("LL_DISABLE_GSTREAMER")) - return false; - - // only do global GStreamer initialization once. - if (!mDoneInit) - { - g_thread_init(NULL); - - // Init the glib type system - we need it. - g_type_init(); - - // Get symbols! -#if LL_DARWIN - if (! grab_gst_syms("libgstreamer-0.10.dylib", - "libgstvideo-0.10.dylib") ) -#elseif LL_WINDOWS - if (! grab_gst_syms("libgstreamer-0.10.dll", - "libgstvideo-0.10.dll") ) -#else // linux or other ELFy unixoid - if (! grab_gst_syms("libgstreamer-0.10.so.0", - "libgstvideo-0.10.so.0") ) -#endif - { - WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); - return false; - } - - if (llgst_segtrap_set_enabled) - { - llgst_segtrap_set_enabled(FALSE); - } - else - { - WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); - } - -#if LL_LINUX - // Gstreamer tries a fork during init, waitpid-ing on it, - // which conflicts with any installed SIGCHLD handler... - struct sigaction tmpact, oldact; - if (llgst_registry_fork_set_enabled) { - // if we can disable SIGCHLD-using forking behaviour, - // do it. - llgst_registry_fork_set_enabled(false); - } - else { - // else temporarily install default SIGCHLD handler - // while GStreamer initialises - tmpact.sa_handler = SIG_DFL; - sigemptyset( &tmpact.sa_mask ); - tmpact.sa_flags = SA_SIGINFO; - sigaction(SIGCHLD, &tmpact, &oldact); - } -#endif // LL_LINUX - - // Protect against GStreamer resetting the locale, yuck. - static std::string saved_locale; - saved_locale = setlocale(LC_ALL, NULL); - - // finally, try to initialize GStreamer! - GError *err = NULL; - gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); - - // restore old locale - setlocale(LC_ALL, saved_locale.c_str() ); - -#if LL_LINUX - // restore old SIGCHLD handler - if (!llgst_registry_fork_set_enabled) - sigaction(SIGCHLD, &oldact, NULL); -#endif // LL_LINUX - - if (!init_gst_success) // fail - { - if (err) - { - WARNMSG("GST init failed: %s", err->message); - g_error_free(err); - } - else - { - WARNMSG("GST init failed for unspecified reason."); - } - return false; - } - - // Init our custom plugins - only really need do this once. - gst_slvideo_init_class(); - - mDoneInit = true; - } - - return true; -} - - -void -MediaPluginGStreamer010::sizeChanged() -{ - // the shared writing space has possibly changed size/location/whatever - - // Check to see whether the movie's NATURAL size has been set yet - if (1 == mNaturalWidth && - 1 == mNaturalHeight) - { - mNaturalWidth = mCurrentWidth; - mNaturalHeight = mCurrentHeight; - DEBUGMSG("Media NATURAL size better detected as %dx%d", - mNaturalWidth, mNaturalHeight); - } - - // if the size has changed then the shm has changed and the app needs telling - if (mCurrentWidth != mPreviousWidth || - mCurrentHeight != mPreviousHeight) - { - mPreviousWidth = mCurrentWidth; - mPreviousHeight = mCurrentHeight; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); - message.setValue("name", mTextureSegmentName); - message.setValueS32("width", mNaturalWidth); - message.setValueS32("height", mNaturalHeight); - DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); - sendMessage(message); - } -} - - - -//static -bool -MediaPluginGStreamer010::closedown() -{ - if (!mDoneInit) - return false; // error - - ungrab_gst_syms(); - - mDoneInit = false; - - return true; -} - -MediaPluginGStreamer010::~MediaPluginGStreamer010() -{ - DEBUGMSG("MediaPluginGStreamer010 destructor"); - - closedown(); - - DEBUGMSG("GStreamer010 closing down"); -} - - -std::string -MediaPluginGStreamer010::getVersion() -{ - std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; - if (mDoneInit && - llgst_version) - { - guint major, minor, micro, nano; - llgst_version(&major, &minor, µ, &nano); - plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); - } - else - { - plugin_version += "(unknown)"; - } - return plugin_version; -} - -void MediaPluginGStreamer010::receiveMessage(const char *message_string) -{ - //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - - LLPluginMessage message_in; - - if(message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if(message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; - message.setValueLLSD("versions", versions); - - if ( load() ) - { - DEBUGMSG("GStreamer010 media instance set up"); - } - else - { - WARNMSG("GStreamer010 media instance failed to set up"); - } - - message.setValue("plugin_version", getVersion()); - sendMessage(message); - } - else if(message_name == "idle") - { - // no response is necessary here. - double time = message_in.getValueReal("time"); - - // Convert time to milliseconds for update() - update((int)(time * 1000.0f)); - } - else if(message_name == "cleanup") - { - unload(); - closedown(); - } - else if(message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); - - std::ostringstream str; - INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - } - else if(message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - - DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str()); - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - if(mPixels == iter->second.mAddress) - { - // This is the currently active pixel buffer. Make sure we stop drawing to it. - mPixels = NULL; - mTextureSegmentName.clear(); - - // Make sure the movie decoder is no longer pointed at the shared segment. - sizeChanged(); - } - mSharedSegments.erase(iter); - } - else - { - WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!"); - } - - // Send the response so it can be cleaned up. - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { - std::ostringstream str; - INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str()); - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if(message_name == "init") - { - // Plugin gets to decide the texture parameters to use. - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - // lame to have to decide this now, it depends on the movie. Oh well. - mDepth = 4; - - mCurrentWidth = 1; - mCurrentHeight = 1; - mPreviousWidth = 1; - mPreviousHeight = 1; - mNaturalWidth = 1; - mNaturalHeight = 1; - mWidth = 1; - mHeight = 1; - mTextureWidth = 1; - mTextureHeight = 1; - - message.setValueU32("format", GL_RGBA); - message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); - - message.setValueS32("depth", mDepth); - message.setValueS32("default_width", mWidth); - message.setValueS32("default_height", mHeight); - message.setValueU32("internalformat", GL_RGBA8); - message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. - message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale - sendMessage(message); - } - else if(message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - - std::ostringstream str; - INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height); - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - if(!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height); - INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height); - - mPixels = (unsigned char*)iter->second.mAddress; - mTextureSegmentName = name; - mWidth = width; - mHeight = height; - - if (texture_width > 1 || - texture_height > 1) // not a dummy size from the app, a real explicit forced size - { - INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); - - GST_OBJECT_LOCK(mVideoSink); - mVideoSink->resize_forced_always = true; - mVideoSink->resize_try_width = texture_width; - mVideoSink->resize_try_height = texture_height; - GST_OBJECT_UNLOCK(mVideoSink); - } - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - } - } - } - else if(message_name == "load_uri") - { - std::string uri = message_in.getValue("uri"); - navigateTo( uri ); - sendStatus(); - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - S32 x = message_in.getValueS32("x"); - S32 y = message_in.getValueS32("y"); - - if(event == "down") - { - mouseDown(x, y); - } - else if(event == "up") - { - mouseUp(x, y); - } - else if(event == "move") - { - mouseMove(x, y); - }; - }; - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) - { - if(message_name == "stop") - { - stop(); - } - else if(message_name == "start") - { - double rate = 0.0; - if(message_in.hasValue("rate")) - { - rate = message_in.getValueReal("rate"); - } - // NOTE: we don't actually support rate. - play(rate); - } - else if(message_name == "pause") - { - pause(); - } - else if(message_name == "seek") - { - double time = message_in.getValueReal("time"); - // defer the actual seek in case we haven't - // really truly started yet in which case there - // is nothing to seek upon - mSeekWanted = true; - mSeekDestination = time; - } - else if(message_name == "set_loop") - { - bool loop = message_in.getValueBoolean("loop"); - mIsLooping = loop; - } - else if(message_name == "set_volume") - { - double volume = message_in.getValueReal("volume"); - setVolume(volume); - } - } - else - { - INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str()); - } - } -} - -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - if (MediaPluginGStreamer010::startup()) - { - MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data); - *plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; // okay - } - else - { - return -1; // failed to init - } -} - -#else // LL_GSTREAMER010_ENABLED - -// Stubbed-out class with constructor/destructor (necessary or windows linker -// will just think its dead code and optimize it all out) -class MediaPluginGStreamer010 : public MediaPluginBase -{ -public: - MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginGStreamer010(); - /* virtual */ void receiveMessage(const char *message_string); -}; - -MediaPluginGStreamer010::MediaPluginGStreamer010( - LLPluginInstance::sendMessageFunction host_send_func, - void *host_user_data ) : - MediaPluginBase(host_send_func, host_user_data) -{ - // no-op -} - -MediaPluginGStreamer010::~MediaPluginGStreamer010() -{ - // no-op -} - -void MediaPluginGStreamer010::receiveMessage(const char *message_string) -{ - // no-op -} - -// We're building without GStreamer enabled. Just refuse to initialize. -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - return -1; -} - -#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/newview/linux_tools/getvoice.sh b/linden/indra/newview/linux_tools/getvoice.sh index 13b632f36..afebda9b2 100755 --- a/linden/indra/newview/linux_tools/getvoice.sh +++ b/linden/indra/newview/linux_tools/getvoice.sh @@ -3,8 +3,9 @@ SCRIPTSRC=`readlink -f "$0" || echo "$0"` RUN_PATH=`dirname "${SCRIPTSRC}" || echo .` -#if mozilla-runtime-linux-x86_64 is present we are using 64bit Imprudence on 64bit Linux -if [ -d "${RUN_PATH}/app_settings/mozilla-runtime-linux-x86_64/" ]; then +BINARY_SYSTEM=$(expr match "$(file -b /bin/uname)" '\(.*executable\)') +BINARY_VIEWER=$(expr match "$(file -b ${RUN_PATH}/bin/do-not-directly-run-imprudence-bin)" '\(.*executable\)') +if ( [ "$BINARY_SYSTEM" == "ELF 64-bit LSB executable" ] && [ "$BINARY_VIEWER" == "ELF 64-bit LSB executable" ] ); then LIB_INSTALLDIR="lib32/" # It's 32bit voice on 64bit Linux and 64bit viewer. Not using lib/ for avoiding ambiguity. else LIB_INSTALLDIR="lib/" # It's 32bit voice on 32 or 64bit Linux and 32bit viewer. diff --git a/linden/indra/newview/linux_tools/wrapper.sh b/linden/indra/newview/linux_tools/wrapper.sh index bc2c127a4..8c47434c5 100755 --- a/linden/indra/newview/linux_tools/wrapper.sh +++ b/linden/indra/newview/linux_tools/wrapper.sh @@ -106,13 +106,13 @@ if [ -n "$LL_TCMALLOC" ]; then fi fi fi - -if([ "`uname -m`" = "x86_64" ] && [ -d "${RUN_PATH}/app_settings/mozilla-runtime-linux-x86_64/" ]); then - export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}:${RUN_PATH}/lib64/gstreamer-plugins/" +BINARY_SYSTEM=$(expr match "$(file -b /bin/uname)" '\(.*executable\)') +BINARY_VIEWER=$(expr match "$(file -b ${RUN_PATH}/bin/do-not-directly-run-imprudence-bin)" '\(.*executable\)') +echo "viewer: $BINARY_VIEWER system: $BINARY_SYSTEM" +if ( [ "$BINARY_SYSTEM" == "ELF 64-bit LSB executable" ] && [ "$BINARY_VIEWER" == "ELF 64-bit LSB executable" ] ); then export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib64:"`pwd`"/lib32:"`pwd`"/app_settings/mozilla-runtime-linux-x86_64:"${LD_LIBRARY_PATH}"' else - export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}:${RUN_PATH}/lib/gstreamer-plugins/" export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-linux-i686:"${LD_LIBRARY_PATH}"' fi diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 0c0099578..4c95f00dc 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -973,68 +973,69 @@ def construct(self): # self.path("libpangoxft-1.0.so.0") self.path("libpixman-1.so.0") +#KILL IT WITH FIRE # Gstreamer libs - self.path("libgstbase-0.10.so.0") - self.path("libgstreamer-0.10.so.0") - self.path("libgstaudio-0.10.so.0") - self.path("libgstbase-0.10.so.0") - self.path("libgstcontroller-0.10.so.0") - self.path("libgstdataprotocol-0.10.so.0") - self.path("libgstinterfaces-0.10.so.0") - self.path("libgstnetbuffer-0.10.so.0") - self.path("libgstpbutils-0.10.so.0") - self.path("libgstriff-0.10.so.0") - self.path("libgstrtp-0.10.so.0") - self.path("libgstrtsp-0.10.so.0") - self.path("libgstsdp-0.10.so.0") - self.path("libgsttag-0.10.so.0") - self.path("libgstvideo-0.10.so.0") - - # Gstreamer plugin dependencies - self.path("libfaad.so.0") - self.path("libogg.so.0") - self.path("libtheora.so.0") - self.path("libvorbis.so.0") - self.path("libvorbisenc.so.2") - self.path("liboil-0.3.so.0") - - # Gstreamer plugins - if self.prefix("gstreamer-plugins"): - self.path("libgstalsa.so") - self.path("libgstasf.so") - self.path("libgstaudioconvert.so") - self.path("libgstaudioresample.so") - self.path("libgstautodetect.so") - self.path("libgstavi.so") - self.path("libgstcoreelements.so") - self.path("libgstcoreindexers.so") - self.path("libgstdecodebin2.so") - self.path("libgstdecodebin.so") - self.path("libgstesd.so") - self.path("libgstfaad.so") - self.path("libgstffmpeg.so") - self.path("libgstgnomevfs.so") - self.path("libgsticydemux.so") - self.path("libgstid3demux.so") - self.path("libgstmpegdemux.so") - self.path("libgstmultifile.so") - self.path("libgstmultipart.so") - self.path("libgstogg.so") - self.path("libgstossaudio.so") - self.path("libgstplaybin.so") - self.path("libgstpulse.so") - self.path("libgstqtdemux.so") - self.path("libgstqueue2.so") - self.path("libgsttcp.so") - self.path("libgsttheora.so") - self.path("libgsttypefindfunctions.so") - self.path("libgstudp.so") - self.path("libgstvideoscale.so") - self.path("libgstvolume.so") - self.path("libgstvorbis.so") - self.path("libgstwavparse.so") + #self.path("libgstbase-0.10.so.0") + #self.path("libgstreamer-0.10.so.0") + #self.path("libgstaudio-0.10.so.0") + #self.path("libgstbase-0.10.so.0") + #self.path("libgstcontroller-0.10.so.0") + #self.path("libgstdataprotocol-0.10.so.0") + #self.path("libgstinterfaces-0.10.so.0") + #self.path("libgstnetbuffer-0.10.so.0") + #self.path("libgstpbutils-0.10.so.0") + #self.path("libgstriff-0.10.so.0") + #self.path("libgstrtp-0.10.so.0") + #self.path("libgstrtsp-0.10.so.0") + #self.path("libgstsdp-0.10.so.0") + #self.path("libgsttag-0.10.so.0") + #self.path("libgstvideo-0.10.so.0") + + ## Gstreamer plugin dependencies + #self.path("libfaad.so.0") + #self.path("libogg.so.0") + #self.path("libtheora.so.0") + #self.path("libvorbis.so.0") + #self.path("libvorbisenc.so.2") + #self.path("liboil-0.3.so.0") + + ## Gstreamer plugins + #if self.prefix("gstreamer-plugins"): + #self.path("libgstalsa.so") + #self.path("libgstasf.so") + #self.path("libgstaudioconvert.so") + #self.path("libgstaudioresample.so") + #self.path("libgstautodetect.so") + #self.path("libgstavi.so") + #self.path("libgstcoreelements.so") + #self.path("libgstcoreindexers.so") + #self.path("libgstdecodebin2.so") + #self.path("libgstdecodebin.so") + #self.path("libgstesd.so") + #self.path("libgstfaad.so") + #self.path("libgstffmpeg.so") + #self.path("libgstgnomevfs.so") + #self.path("libgsticydemux.so") + #self.path("libgstid3demux.so") + #self.path("libgstmpegdemux.so") + #self.path("libgstmultifile.so") + #self.path("libgstmultipart.so") + #self.path("libgstogg.so") + #self.path("libgstossaudio.so") + #self.path("libgstplaybin.so") + #self.path("libgstpulse.so") + #self.path("libgstqtdemux.so") + #self.path("libgstqueue2.so") + #self.path("libgsttcp.so") + #self.path("libgsttheora.so") + #self.path("libgsttypefindfunctions.so") + #self.path("libgstudp.so") + #self.path("libgstvideoscale.so") + #self.path("libgstvolume.so") + #self.path("libgstvorbis.so") + #self.path("libgstwavparse.so") - self.end_prefix("gstreamer-plugins") + #self.end_prefix("gstreamer-plugins") self.end_prefix("lib") @@ -1064,8 +1065,6 @@ def construct(self): self.path("featuretable_linux.txt") #self.path("secondlife-x86_64.supp") - self.path("app_settings/mozilla-runtime-linux-x86_64") - if self.prefix("../../libraries/x86_64-linux/lib_release_client", dst="lib64"): self.path("libapr-1.so.0") self.path("libaprutil-1.so.0") @@ -1102,69 +1101,70 @@ def construct(self): # self.path("libpangoxft-1.0.so.0") # So we depend system gdk pixbufs and pango anyway. self.path("libpixman-1.so.0") - # Gstreamer libs - self.path("libgstbase-0.10.so.0") - self.path("libgstreamer-0.10.so.0") - self.path("libgstaudio-0.10.so.0") - self.path("libgstbase-0.10.so.0") - self.path("libgstcontroller-0.10.so.0") - self.path("libgstdataprotocol-0.10.so.0") - self.path("libgstinterfaces-0.10.so.0") - self.path("libgstnetbuffer-0.10.so.0") - self.path("libgstpbutils-0.10.so.0") - self.path("libgstriff-0.10.so.0") - self.path("libgstrtp-0.10.so.0") - self.path("libgstrtsp-0.10.so.0") - self.path("libgstsdp-0.10.so.0") - self.path("libgsttag-0.10.so.0") - self.path("libgstvideo-0.10.so.0") - - # Gstreamer plugin dependencies - self.path("libfaad.so.0") - self.path("libogg.so.0") - self.path("libtheora.so.0") - self.path("libvorbis.so.0") - self.path("libvorbisenc.so.2") - self.path("liboil-0.3.so.0") - - # Gstreamer plugins - if self.prefix("gstreamer-plugins"): - self.path("libgstalsa.so") - self.path("libgstasf.so") - self.path("libgstaudioconvert.so") - self.path("libgstaudioresample.so") - self.path("libgstautodetect.so") - self.path("libgstavi.so") - self.path("libgstcoreelements.so") - self.path("libgstcoreindexers.so") - self.path("libgstdecodebin2.so") - self.path("libgstdecodebin.so") - self.path("libgstesd.so") - self.path("libgstfaad.so") - self.path("libgstffmpeg.so") - self.path("libgstffmpegcolorspace.so") - self.path("libgstgnomevfs.so") - self.path("libgsticydemux.so") - self.path("libgstid3demux.so") - self.path("libgstmpegdemux.so") - self.path("libgstmultifile.so") - self.path("libgstmultipart.so") - self.path("libgstogg.so") - self.path("libgstossaudio.so") - self.path("libgstplaybin.so") - self.path("libgstpulse.so") - self.path("libgstqtdemux.so") - self.path("libgstqueue2.so") - self.path("libgsttcp.so") - self.path("libgsttheora.so") - self.path("libgsttypefindfunctions.so") - self.path("libgstudp.so") - self.path("libgstvideoscale.so") - self.path("libgstvolume.so") - self.path("libgstvorbis.so") - self.path("libgstwavparse.so") +#KILL IT WITH FIRE + ## Gstreamer libs + #self.path("libgstbase-0.10.so.0") + #self.path("libgstreamer-0.10.so.0") + #self.path("libgstaudio-0.10.so.0") + #self.path("libgstbase-0.10.so.0") + #self.path("libgstcontroller-0.10.so.0") + #self.path("libgstdataprotocol-0.10.so.0") + #self.path("libgstinterfaces-0.10.so.0") + #self.path("libgstnetbuffer-0.10.so.0") + #self.path("libgstpbutils-0.10.so.0") + #self.path("libgstriff-0.10.so.0") + #self.path("libgstrtp-0.10.so.0") + #self.path("libgstrtsp-0.10.so.0") + #self.path("libgstsdp-0.10.so.0") + #self.path("libgsttag-0.10.so.0") + #self.path("libgstvideo-0.10.so.0") + + ## Gstreamer plugin dependencies + #self.path("libfaad.so.0") + #self.path("libogg.so.0") + #self.path("libtheora.so.0") + #self.path("libvorbis.so.0") + #self.path("libvorbisenc.so.2") + #self.path("liboil-0.3.so.0") + + ## Gstreamer plugins + #if self.prefix("gstreamer-plugins"): + #self.path("libgstalsa.so") + #self.path("libgstasf.so") + #self.path("libgstaudioconvert.so") + #self.path("libgstaudioresample.so") + #self.path("libgstautodetect.so") + #self.path("libgstavi.so") + #self.path("libgstcoreelements.so") + #self.path("libgstcoreindexers.so") + #self.path("libgstdecodebin2.so") + #self.path("libgstdecodebin.so") + #self.path("libgstesd.so") + #self.path("libgstfaad.so") + #self.path("libgstffmpeg.so") + #self.path("libgstffmpegcolorspace.so") + #self.path("libgstgnomevfs.so") + #self.path("libgsticydemux.so") + #self.path("libgstid3demux.so") + #self.path("libgstmpegdemux.so") + #self.path("libgstmultifile.so") + #self.path("libgstmultipart.so") + #self.path("libgstogg.so") + #self.path("libgstossaudio.so") + #self.path("libgstplaybin.so") + #self.path("libgstpulse.so") + #self.path("libgstqtdemux.so") + #self.path("libgstqueue2.so") + #self.path("libgsttcp.so") + #self.path("libgsttheora.so") + #self.path("libgsttypefindfunctions.so") + #self.path("libgstudp.so") + #self.path("libgstvideoscale.so") + #self.path("libgstvolume.so") + #self.path("libgstvorbis.so") + #self.path("libgstwavparse.so") - self.end_prefix("gstreamer-plugins") + #self.end_prefix("gstreamer-plugins") self.end_prefix("lib64") diff --git a/linden/indra/newview/viewer_manifest.py~ b/linden/indra/newview/viewer_manifest.py~ deleted file mode 100755 index 452b1658d..000000000 --- a/linden/indra/newview/viewer_manifest.py~ +++ /dev/null @@ -1,1176 +0,0 @@ -#!/usr/bin/python -# @file viewer_manifest.py -# @author Ryan Williams -# @brief Description of all installer viewer files, and methods for packaging -# them into installers for all supported platforms. -# -# $LicenseInfo:firstyear=2006&license=viewergpl$ -# -# Copyright (c) 2006-2009, Linden Research, Inc. -# -# Second Life Viewer Source Code -# The source code in this file ("Source Code") is provided by Linden Lab -# to you under the terms of the GNU General Public License, version 2.0 -# ("GPL"), unless you have obtained a separate licensing agreement -# ("Other License"), formally executed by you and Linden Lab. Terms of -# the GPL can be found in doc/GPL-license.txt in this distribution, or -# online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 -# -# There are special exceptions to the terms and conditions of the GPL as -# it is applied to this Source Code. View the full text of the exception -# in the file doc/FLOSS-exception.txt in this software distribution, or -# online at -# http://secondlifegrid.net/programs/open_source/licensing/flossexception -# -# By copying, modifying or distributing this software, you acknowledge -# that you have read and understood your obligations described above, -# and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ - -# DO NOT RUN THIS FILE DIRECTLY -# Instead, run develop.py with "configure -DPACKAGE:BOOL=ON" e.g.: -# develop.py -G vc80 configure -DPACKAGE:BOOL=ON -# to generate the "package" project in Visual Studio 2005 -# Note: as of Imprudence 1.3, this defaults to on for Windows - -import sys -import os.path -import re -import tarfile -viewer_dir = os.path.dirname(__file__) -# add llmanifest library to our path so we don't have to muck with PYTHONPATH -sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util')) -from llmanifest import LLManifest, main, proper_windows_path, path_ancestors - -class ViewerManifest(LLManifest): - def construct(self): - super(ViewerManifest, self).construct() - self.exclude("*.svn*") - self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg") - self.path(src="../../etc/message.xml", dst="app_settings/message.xml") - - if self.prefix(src="app_settings"): - self.exclude("logcontrol.xml") - self.exclude("logcontrol-dev.xml") - self.path("*.pem") - self.path("*.ini") - self.path("*.xml") - self.path("*.db2") - - # include the entire shaders directory recursively - self.path("shaders") - # ... and the entire windlight directory - self.path("windlight") - self.end_prefix("app_settings") - - if self.prefix(src="character"): - self.path("*.llm") - self.path("*.xml") - self.path("*.tga") - self.end_prefix("character") - - # Include our fonts - if self.prefix(src="fonts"): - self.path("LiberationSans-Bold.ttf") - self.path("LiberationSans-Regular.ttf") - self.path("VeraMono.ttf") - self.path("DejaVuSansCondensed-BoldOblique.ttf") - self.path("DejaVuSansCondensed-Bold.ttf") - self.path("DejaVuSansCondensed-Oblique.ttf") - self.path("DejaVuSansCondensed.ttf") - self.path("GPL.txt") - self.path("Liberation-License.txt") - self.path("Vera-License.txt") - self.end_prefix("fonts") - - # skins - if self.prefix(src="skins"): - self.path("paths.xml") - # include the entire textures directory recursively - if self.prefix(src="*/textures"): - self.path("*.tga") - self.path("*.j2c") - self.path("*.jpg") - self.path("*.png") - self.path("textures.xml") - self.end_prefix("*/textures") - self.path("*/xui/*/*.xml") - self.path("*/*.xml") - - # Local HTML files (e.g. loading screen) - if self.prefix(src="*/html"): - self.path("*.png") - self.path("*/*/*.html") - self.path("*/*/*.gif") - self.path("*/*/*.png") - self.end_prefix("*/html") - self.end_prefix("skins") - - # Files in the newview/ directory - self.path("gpu_table.txt") - - - # Gather up the README file, etc. - def gather_documents(self): - # From the top level directory (imprudence) - if self.prefix("../../..", dst=""): - self.path("README.txt") - self.path("MANIFESTO.txt") - self.path("CONTRIBUTE.txt") - self.path("RELEASE_NOTES.txt") - self.path("ChangeLog.txt", required=False) - self.end_prefix("../../..") - - # From the linden directory - if self.prefix("../..", dst="doc"): - self.path("LICENSE-source.txt") - self.path("LICENSE-logos.txt", "LICENSE-artwork.txt") - self.end_prefix("../..") - - # From the linden/doc directory - if self.prefix("../../doc", dst="doc"): - self.path("contributions.txt") - self.path("GPL-license.txt", "GPL.txt") - self.path("FLOSS-exception.txt") - self.end_prefix("../../doc") - - - def login_channel(self): - """Channel reported for login and upgrade purposes ONLY; - used for A/B testing""" - # NOTE: Do not return the normal channel if login_channel - # is not specified, as some code may branch depending on - # whether or not this is present - return self.args.get('login_channel') - - def grid(self): - return self.args['grid'] - def channel(self): - return self.args['channel'] - def channel_unique(self): - return self.channel().replace("Imprudence", "").strip() - def channel_oneword(self): - return "".join(self.channel_unique().split()) - def channel_lowerword(self): - return self.channel_oneword().lower() - - def flags_list(self): - """ Convenience function that returns the command-line flags - for the grid""" - - # Set command line flags relating to the target grid - grid_flags = '' - if not self.default_grid(): - grid_flags = "--grid %(grid)s "\ - "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\ - {'grid':self.grid()} - - # set command line flags for channel - channel_flags = '' - if self.login_channel() and self.login_channel() != self.channel(): - # Report a special channel during login, but use default - channel_flags = '--channel "%s"' % (self.login_channel()) - elif not self.default_channel(): - channel_flags = '--channel "%s"' % self.channel() - - # Deal with settings - setting_flags = '' - if not self.default_channel() or not self.default_grid(): - if self.default_grid(): - setting_flags = '--settings settings_%s.xml'\ - % self.channel_lowerword() - else: - setting_flags = '--settings settings_%s_%s.xml'\ - % (self.grid(), self.channel_lowerword()) - - return " ".join((channel_flags, grid_flags, setting_flags)).strip() - - -class WindowsManifest(ViewerManifest): - def final_exe(self): - if self.default_channel(): - if self.default_grid(): - return "imprudence.exe" - else: - return "imprudencepreview.exe" - else: - return ''.join(self.channel().split()) + '.exe' - - - def construct(self): - super(WindowsManifest, self).construct() - # the final exe is complicated because we're not sure where it's coming from, - # nor do we have a fixed name for the executable - self.path(self.find_existing_file('debug/imprudence-bin.exe', 'release/imprudence-bin.exe', 'relwithdebinfo/imprudence-bin.exe'), dst=self.final_exe()) - - self.gather_documents() - - if self.prefix("../..", dst="doc"): - self.path("LICENSE-libraries.txt") - self.end_prefix("../..") - - - self.path("imprudence.url") - - # Plugin host application - self.path(os.path.join(os.pardir, - 'llplugin', 'slplugin', self.args['configuration'], "SLPlugin.exe"), - "SLPlugin.exe") - - - self.path("featuretable.txt") - - # For use in crash reporting (generates minidumps) - self.path("dbghelp.dll") - - # For using FMOD for sound... DJS - #self.path("fmod.dll") - - # For spellchecking - self.path("libhunspell.dll") - - # For textures - if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): - self.path("openjpeg.dll") - self.end_prefix() - - # For sound - if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): - self.path("openal32.dll") - self.path("alut.dll") - self.end_prefix() - - - # Media plugins - QuickTime - if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"): - self.path("media_plugin_quicktime.dll") - self.end_prefix() - - # Media plugins - WebKit/Qt - if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"): - self.path("media_plugin_webkit.dll") - self.end_prefix() - - # For WebKit/Qt plugin runtimes - if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"): - self.path("libeay32.dll") - self.path("qtcore4.dll") - self.path("qtgui4.dll") - self.path("qtnetwork4.dll") - self.path("qtopengl4.dll") - self.path("qtwebkit4.dll") - self.path("ssleay32.dll") - self.end_prefix() - - # For WebKit/Qt plugin runtimes (image format plugins) - if self.prefix(src="../../libraries/i686-win32/lib/release/imageformats", dst="llplugin/imageformats"): - self.path("qgif4.dll") - self.path("qico4.dll") - self.path("qjpeg4.dll") - self.path("qmng4.dll") - self.path("qsvg4.dll") - self.path("qtiff4.dll") - self.end_prefix() - - # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 - self.path("skins/default/xui/en-us/mime_types_windows.xml", "skins/default/xui/en-us/mime_types.xml") - - # These need to be installed as a SxS assembly, currently a 'private' assembly. - # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx - if self.prefix(src=self.args['configuration'], dst=""): - if self.args['configuration'] == 'Debug': - self.path("msvcr80d.dll") - self.path("msvcp80d.dll") - self.path("Microsoft.VC80.DebugCRT.manifest") - else: - self.path("msvcr80.dll") - self.path("msvcp80.dll") - self.path("Microsoft.VC80.CRT.manifest") - self.end_prefix() - - # The config file name needs to match the exe's name. - self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst=self.final_exe() + ".config") - - # We need this one too, so that llkdu loads at runtime - DEV-41194 - #self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst="llkdu.dll.2.config") - self.path("llkdu.dll.2.config") - - # We need this one too, so that win_crash_logger.exe loads at runtime - DEV-19004 - #self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst="win_crash_logger.exe.config") - - # same thing for auto-updater. - #self.path(src="%s/imprudence-bin.exe.config" % self.args['configuration'], dst="updater.exe.config") - - # Vivox runtimes - if self.prefix(src="vivox-runtime/i686-win32", dst=""): - # self.path("alut.dll") - self.path("wrap_oal.dll") - self.path("SLVoice.exe") - # self.path("SLVoiceAgent.exe") - # self.path("libeay32.dll") - # self.path("srtp.dll") - # self.path("ssleay32.dll") - # self.path("tntk.dll") - self.path("vivoxsdk.dll") - self.path("ortp.dll") - - self.end_prefix() - - # Gstreamer plugins - if self.prefix(src="lib/gstreamer-plugins", dst=""): - self.path("*.dll", dst="lib/gstreamer-plugins/*.dll") - self.end_prefix() - - # Gstreamer libs - if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): - self.path("iconv.dll") - self.path("libxml2.dll") - self.path("libcairo-2.dll") - self.path("libgio-2.0-0.dll") - self.path("libglib-2.0-0.dll") - self.path("libgmodule-2.0-0.dll") - self.path("libgobject-2.0-0.dll") - self.path("libgthread-2.0-0.dll") - self.path("charset.dll") - self.path("intl.dll") - self.path("libgcrypt-11.dll") - self.path("libgnutls-26.dll") - self.path("libgpg-error-0.dll") - self.path("libgstapp.dll") - self.path("libgstaudio.dll") - self.path("libgstbase-0.10.dll") - self.path("libgstcdda.dll") - self.path("libgstcontroller-0.10.dll") - self.path("libgstdataprotocol-0.10.dll") - self.path("libgstdshow.dll") - self.path("libgstfft.dll") - self.path("libgstinterfaces.dll") - self.path("libgstnet-0.10.dll") - self.path("libgstnetbuffer.dll") - self.path("libgstpbutils.dll") - self.path("libgstreamer-0.10.dll") - self.path("libgstriff.dll") - self.path("libgstrtp.dll") - self.path("libgstrtsp.dll") - self.path("libgstsdp.dll") - self.path("libgsttag.dll") - self.path("libgstvideo.dll") - self.path("libjpeg.dll") - self.path("libmp3lame-0.dll") - self.path("libneon-27.dll") - self.path("libogg-0.dll") - self.path("liboil-0.3-0.dll") - self.path("libopenjpeg-2.dll") - self.path("libpng12-0.dll") - self.path("libschroedinger-1.0-0.dll") - self.path("libspeex-1.dll") - self.path("libtheora-0.dll") - self.path("libvorbis-0.dll") - self.path("libvorbisenc-2.dll") - self.path("libxml2-2.dll") - self.path("glew32.dll") - self.path("xvidcore.dll") - self.path("zlib1.dll") - self.end_prefix() - -# # pull in the crash logger and updater from other projects -# self.path(src=self.find_existing_file( # tag:"crash-logger" here as a cue to the exporter -# "../win_crash_logger/debug/windows-crash-logger.exe", -# "../win_crash_logger/release/windows-crash-logger.exe", -# "../win_crash_logger/relwithdebinfo/windows-crash-logger.exe"), -# dst="win_crash_logger.exe") - self.path(src=self.find_existing_file( - "../win_updater/debug/windows-updater.exe", - "../win_updater/release/windows-updater.exe", - "../win_updater/relwithdebinfo/windows-updater.exe"), - dst="updater.exe") - - # For google-perftools tcmalloc allocator. - #if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): - # self.path("libtcmalloc_minimal.dll") - # self.end_prefix() - - - def nsi_file_commands(self, install=True): - def wpath(path): - if path.endswith('/') or path.endswith(os.path.sep): - path = path[:-1] - path = path.replace('/', '\\') - return path - - result = "" - dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])] - # sort deepest hierarchy first - dest_files.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b)) - dest_files.reverse() - out_path = None - for pkg_file in dest_files: - rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,'')) - installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file))) - pkg_file = wpath(os.path.normpath(pkg_file)) - if installed_dir != out_path: - if install: - out_path = installed_dir - result += 'SetOutPath ' + out_path + '\n' - if install: - result += 'File ' + pkg_file + '\n' - else: - result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n' - # at the end of a delete, just rmdir all the directories - if not install: - deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list] - # find all ancestors so that we don't skip any dirs that happened to have no non-dir children - deleted_dirs = [] - for d in deleted_file_dirs: - deleted_dirs.extend(path_ancestors(d)) - # sort deepest hierarchy first - deleted_dirs.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b)) - deleted_dirs.reverse() - prev = None - for d in deleted_dirs: - if d != prev: # skip duplicates - result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n' - prev = d - - return result - - def package_finish(self): - # a standard map of strings for replacing in the templates - substitution_strings = { - 'version' : '.'.join(self.args['version']).replace(' ', '_'), - 'version_short' : '.'.join(self.args['version'][:-1]).replace(' ', '_'), - 'version_dashes' : '-'.join(self.args['version']).replace(' ', '_'), - 'final_exe' : self.final_exe(), - 'grid':self.args['grid'], - 'grid_caps':self.args['grid'].upper(), - # escape quotes becase NSIS doesn't handle them well - 'flags':self.flags_list().replace('"', '$\\"'), - 'channel':self.channel(), - 'channel_oneword':self.channel_oneword(), - 'channel_unique':self.channel_unique(), - } - - version_vars = """ - !define INSTEXE "%(final_exe)s" - !define VERSION "%(version_short)s" - !define VERSION_LONG "%(version)s" - !define VERSION_DASHES "%(version_dashes)s" - """ % substitution_strings - if self.default_channel(): - if self.default_grid(): - # release viewer - installer_file = "Imprudence_%(version_dashes)s_Setup.exe" - grid_vars_template = """ - OutFile "%(installer_file)s" - !define INSTFLAGS "%(flags)s" - !define INSTNAME "Imprudence" - !define SHORTCUT "Imprudence" - !define URLNAME "imprudence" - Caption "Imprudence ${VERSION}" - """ - else: - # beta grid viewer - installer_file = "Imprudence_%(version_dashes)s_(%(grid_caps)s)_Setup.exe" - grid_vars_template = """ - OutFile "%(installer_file)s" - !define INSTFLAGS "%(flags)s" - !define INSTNAME "Imprudence%(grid_caps)s" - !define SHORTCUT "Imprudence (%(grid_caps)s)" - !define URLNAME "imprudence%(grid)s" - !define UNINSTALL_SETTINGS 1 - Caption "Imprudence %(grid)s ${VERSION}" - """ - else: - # some other channel on some grid - installer_file = "Imprudence_%(version_dashes)s_%(channel_oneword)s_Setup.exe" - grid_vars_template = """ - OutFile "%(installer_file)s" - !define INSTFLAGS "%(flags)s" - !define INSTNAME "Imprudence%(channel_oneword)s" - !define SHORTCUT "%(channel)s" - !define URLNAME "imprudence" - !define UNINSTALL_SETTINGS 1 - Caption "%(channel)s ${VERSION}" - """ - if 'installer_name' in self.args: - installer_file = self.args['installer_name'] - else: - installer_file = installer_file % substitution_strings - substitution_strings['installer_file'] = installer_file - - tempfile = "imprudence_setup_tmp.nsi" - # the following replaces strings in the nsi template - # it also does python-style % substitution - self.replace_in("installers/windows/installer_template.nsi", tempfile, { - "%%VERSION%%":version_vars, - "%%SOURCE%%":self.get_src_prefix(), - "%%GRID_VARS%%":grid_vars_template % substitution_strings, - "%%INSTALL_FILES%%":self.nsi_file_commands(True), - "%%DELETE_FILES%%":self.nsi_file_commands(False)}) - - # We use the Unicode version of NSIS, available from - # http://www.scratchpaper.com/ - NSIS_path = 'C:\\Program Files\\NSIS\\Unicode\\makensis.exe' - self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile)) - # self.remove(self.dst_path_of(tempfile)) - # If we're on a build machine, sign the code using our Authenticode certificate. JC - sign_py = 'C:\\buildscripts\\code-signing\\sign.py' - if os.path.exists(sign_py): - self.run_command(sign_py + ' ' + self.dst_path_of(installer_file)) - else: - print "Skipping code signing,", sign_py, "does not exist" - self.created_path(self.dst_path_of(installer_file)) - self.package_file = installer_file - - -class DarwinManifest(ViewerManifest): - def construct(self): - # copy over the build result (this is a no-op if run within the xcode script) - self.path(self.args['configuration'] + "/Imprudence.app", dst="") - - if self.prefix(src="", dst="Contents"): # everything goes in Contents - - self.path("Info-Imprudence.plist", dst="Info.plist") - - # copy additional libs in <bundle>/Contents/MacOS/ - if self.prefix(src="../../libraries/universal-darwin/lib_release", dst="MacOS/"): - - self.path("libndofdev.dylib") - - self.path("libopenal.1.dylib") - self.path("libalut.0.dylib") - - self.path("libglib-2.0.dylib") - self.path("libgmodule-2.0.dylib") - self.path("libgobject-2.0.dylib") - self.path("libgthread-2.0.dylib") - - self.path("libgstreamer-0.10.dylib") - self.path("libgstapp-0.10.dylib") - self.path("libgstaudio-0.10.dylib") - self.path("libgstbase-0.10.dylib") - self.path("libgstcdda-0.10.dylib") - self.path("libgstcontroller-0.10.dylib") - self.path("libgstdataprotocol-0.10.dylib") - self.path("libgstfft-0.10.dylib") - self.path("libgstinterfaces-0.10.dylib") - self.path("libgstnet-0.10.dylib") - self.path("libgstnetbuffer-0.10.dylib") - self.path("libgstpbutils-0.10.dylib") - self.path("libgstriff-0.10.dylib") - self.path("libgstrtp-0.10.dylib") - self.path("libgstrtsp-0.10.dylib") - self.path("libgstsdp-0.10.dylib") - self.path("libgsttag-0.10.dylib") - self.path("libgstvideo-0.10.dylib") - - self.path("libxml2.2.dylib") - self.path("libfaad.2.dylib") - self.path("libFLAC.8.dylib") - self.path("libintl.3.dylib") - self.path("libjpeg.62.dylib") - self.path("libpng12.0.dylib") - self.path("libneon.27.dylib") - self.path("libogg.0.dylib") - self.path("liboil-0.3.0.dylib") - self.path("libopenjpeg.1.4.dylib") - self.path("libtheora.0.dylib") - self.path("libvorbis.0.dylib") - self.path("libvorbisenc.2.dylib") - self.path("libvorbisfile.3.dylib") - - self.end_prefix("../../libraries/universal-darwin/lib_release") - - # most everything goes in the Resources directory - if self.prefix(src="", dst="Resources"): - super(DarwinManifest, self).construct() - - if self.prefix("cursors_mac"): - self.path("*.tif") - self.end_prefix("cursors_mac") - - # From the linden directory - if self.prefix("../..", dst="doc"): - self.path("LICENSE-libraries.txt") - self.end_prefix("../..") - - self.gather_documents() - - self.path("featuretable_mac.txt") - self.path("SecondLife.nib") - - self.path("viewer.icns") - - # Translations - self.path("English.lproj") - self.path("German.lproj") - self.path("Japanese.lproj") - self.path("Korean.lproj") - self.path("da.lproj") - self.path("es.lproj") - self.path("fr.lproj") - self.path("hu.lproj") - self.path("it.lproj") - self.path("nl.lproj") - self.path("pl.lproj") - self.path("pt.lproj") - self.path("ru.lproj") - self.path("tr.lproj") - self.path("uk.lproj") - self.path("zh-Hans.lproj") - - - if self.prefix(src="../../libraries/universal-darwin/lib_release/gstreamer-plugins", dst="lib/gstreamer-plugins"): - self.path("libgstaacparse.so") - self.path("libgstadder.so") - self.path("libgstaiffparse.so") - self.path("libgstamrparse.so") - self.path("libgstapp.so") - self.path("libgstaudioconvert.so") - self.path("libgstaudiorate.so") - self.path("libgstaudioresample.so") - self.path("libgstautodetect.so") - self.path("libgstavi.so") - self.path("libgstcoreelements.so") - self.path("libgstcoreindexers.so") - self.path("libgstdebug.so") - self.path("libgstdecodebin.so") - self.path("libgstdecodebin2.so") - self.path("libgstdeinterlace2.so") - self.path("libgstequalizer.so") - self.path("libgstfaad.so") - self.path("libgstffmpeg.so") - self.path("libgstffmpegcolorspace.so") - self.path("libgstffmpegscale.so") - self.path("libgstfilter.so") - self.path("libgstflac.so") - self.path("libgstflv.so") - self.path("libgstgdp.so") - self.path("libgsth264parse.so") - self.path("libgsticydemux.so") - self.path("libgstid3demux.so") - self.path("libgstinterleave.so") - self.path("libgstjpeg.so") - self.path("libgstlevel.so") - self.path("libgstmetadata.so") - self.path("libgstmpeg4videoparse.so") - self.path("libgstmpegdemux.so") - self.path("libgstmpegvideoparse.so") - self.path("libgstmultifile.so") - self.path("libgstmultipart.so") - self.path("libgstneonhttpsrc.so") - self.path("libgstogg.so") - self.path("libgstosxaudio.so") - self.path("libgstosxvideosink.so") - self.path("libgstplaybin.so") - self.path("libgstpng.so") - self.path("libgstpostproc.so") - self.path("libgstqtdemux.so") - #self.path("libgstqtwrapper.so") - self.path("libgstqueue2.so") - self.path("libgstreal.so") - self.path("libgstrtp.so") - self.path("libgstrtpmanager.so") - self.path("libgstrtsp.so") - self.path("libgstsdpelem.so") - self.path("libgstselector.so") - self.path("libgststereo.so") - self.path("libgsttcp.so") - self.path("libgsttheora.so") - self.path("libgsttypefindfunctions.so") - self.path("libgstudp.so") - self.path("libgstvideobalance.so") - self.path("libgstvideobox.so") - self.path("libgstvideocrop.so") - self.path("libgstvideoflip.so") - self.path("libgstvideomixer.so") - self.path("libgstvideorate.so") - self.path("libgstvideoscale.so") - self.path("libgstvideosignal.so") - self.path("libgstvolume.so") - self.path("libgstvorbis.so") - self.path("libgstwavparse.so") - - self.end_prefix("../../libraries/universal-darwin/lib_release/gstreamer-plugins") - - - # SLVoice and vivox lols - self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib") - self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib") - self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib") - self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib") - self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice") - #self.path("vivox-runtime/universal-darwin/SLVoiceAgent.app", "SLVoiceAgent.app") - - #libfmodwrapper.dylib - #self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib") - - # our apps -# self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") - self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") - - # plugin launcher - self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin") - - # plugins - if self.prefix(src="", dst="llplugin"): - self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib") - self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib") - self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib") - - self.end_prefix("llplugin") - - # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 - self.path("skins/default/xui/en-us/mime_types_mac.xml", "skins/default/xui/en-us/mime_types.xml") - - # command line arguments for connecting to the proper grid - self.put_in_file(self.flags_list(), 'arguments.txt') - - self.end_prefix("Resources") - - self.end_prefix("Contents") - - # NOTE: the -S argument to strip causes it to keep enough info for - # annotated backtraces (i.e. function names in the crash log). 'strip' with no - # arguments yields a slightly smaller binary but makes crash logs mostly useless. - # This may be desirable for the final release. Or not. - if ("package" in self.args['actions'] or - "unpacked" in self.args['actions']): - self.run_command('strip -S "%(viewer_binary)s"' % - { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')}) - - - def package_finish(self): - channel_standin = 'Imprudence' # hah, our default channel is not usable on its own - if not self.default_channel(): - channel_standin = self.channel() - - imagename="Imprudence_" + '_'.join(self.args['version']) - - # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning. - # If we really need differently named volumes, we'll need to create multiple DS_Store file images, or use some other trick. - - volname="Imprudence Installer" # DO NOT CHANGE without understanding comment above - - if self.default_channel(): - if not self.default_grid(): - # beta case - imagename = imagename + '_' + self.args['grid'].upper() - else: - # first look, etc - imagename = imagename + '_' + self.channel_oneword().upper() - - sparsename = imagename + ".sparseimage" - finalname = imagename + ".dmg" - # make sure we don't have stale files laying about - self.remove(sparsename, finalname) - - self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 400 -layout SPUD' % { - 'sparse':sparsename, - 'vol':volname}) - - # mount the image and get the name of the mount point and device node - hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"') - devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip() - volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip() - - # Copy everything in to the mounted .dmg - - if self.default_channel() and not self.default_grid(): - app_name = "Imprudence " + self.args['grid'] - else: - app_name = channel_standin.strip() - - # Hack: - # Because there is no easy way to coerce the Finder into positioning - # the app bundle in the same place with different app names, we are - # adding multiple .DS_Store files to svn. There is one for release, - # one for release candidate and one for first look. Any other channels - # will use the release .DS_Store, and will look broken. - # - Ambroff 2008-08-20 - dmg_template = os.path.join( - 'installers', - 'darwin', - '%s-dmg' % "".join(self.channel_unique().split()).lower()) - - if not os.path.exists (self.src_path_of(dmg_template)): - dmg_template = os.path.join ('installers', 'darwin', 'release-dmg') - - for s,d in {self.get_dst_prefix():app_name + ".app", - os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns", - os.path.join(dmg_template, "background.jpg"): "background.jpg", - os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items(): - print "Copying to dmg", s, d - self.copy_action(self.src_path_of(s), os.path.join(volpath, d)) - - # Hide the background image, DS_Store file, and volume icon file (set their "visible" bit) - self.run_command('SetFile -a V "' + os.path.join(volpath, ".VolumeIcon.icns") + '"') - self.run_command('SetFile -a V "' + os.path.join(volpath, "background.jpg") + '"') - self.run_command('SetFile -a V "' + os.path.join(volpath, ".DS_Store") + '"') - - # Create the alias file (which is a resource file) from the .r - self.run_command('rez "' + self.src_path_of("installers/darwin/release-dmg/Applications-alias.r") + '" -o "' + os.path.join(volpath, "Applications") + '"') - - # Set the alias file's alias and custom icon bits - self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"') - - # Set the disk image root's custom icon bit - self.run_command('SetFile -a C "' + volpath + '"') - - # Unmount the image - self.run_command('hdiutil detach -force "' + devfile + '"') - - print "Converting temp disk image to final disk image" - self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname}) - # get rid of the temp file - self.package_file = finalname - self.remove(sparsename) - -class LinuxManifest(ViewerManifest): - def construct(self): - super(LinuxManifest, self).construct() - - self.path("res/imprudence_icon.png","imprudence_icon.png") - if self.prefix("linux_tools", dst=""): - #self.path("client-readme.txt","README-linux.txt") - self.path("client-readme-voice.txt","README-linux-voice.txt") - #self.path("client-readme-joystick.txt","README-linux-joystick.txt") - self.path("wrapper.sh","imprudence") - self.path("handle_secondlifeprotocol.sh") - self.path("register_secondlifeprotocol.sh") - self.path("getvoice.sh") - self.end_prefix("linux_tools") - - self.gather_documents() - - # From the linden directory - if self.prefix("../..", dst="doc"): - self.path("LICENSE-libraries.txt") - self.end_prefix("../..") - - # Create an appropriate gridargs.dat for this package, denoting required grid. - self.put_in_file(self.flags_list(), 'gridargs.dat') - self.path("linux_tools/launch_url.sh","launch_url.sh") - self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin") - if self.prefix("res-sdl"): - self.path("*") - # recurse - self.end_prefix("res-sdl") - - # plugins - if self.prefix(src="", dst="bin/llplugin"): - self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") - self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") - self.end_prefix("bin/llplugin") - - # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 - self.path("skins/default/xui/en-us/mime_types_linux.xml", "skins/default/xui/en-us/mime_types.xml") - - self.path("featuretable_linux.txt") - - - def package_finish(self): - if 'installer_name' in self.args: - installer_name = self.args['installer_name'] - else: - installer_name_components = ['Imprudence_', self.args.get('arch')] - installer_name_components.extend(self.args['version']) - installer_name = "_".join(installer_name_components) - if self.default_channel(): - if not self.default_grid(): - installer_name += '_' + self.args['grid'].upper() - else: - installer_name += '_' + self.channel_oneword().upper() - - # Fix access permissions - self.run_command(""" - find %(dst)s -type d | xargs --no-run-if-empty chmod 755; - find %(dst)s -type f -perm 0700 | xargs --no-run-if-empty chmod 0755; - find %(dst)s -type f -perm 0500 | xargs --no-run-if-empty chmod 0555; - find %(dst)s -type f -perm 0600 | xargs --no-run-if-empty chmod 0644; - find %(dst)s -type f -perm 0400 | xargs --no-run-if-empty chmod 0444; - true""" % {'dst':self.get_dst_prefix() }) - - self.package_file = installer_name + '.tar.bz2' - - # Disabled for now. It's a waste of time to package every compile. - - # if("package" in self.args['actions'] or - # "unpacked" in self.args['actions']): - # - # # temporarily move directory tree so that it has the right - # # name in the tarfile - # self.run_command("mv %(dst)s %(inst)s" % { - # 'dst': self.get_dst_prefix(), - # 'inst': self.build_path_of(installer_name)}) - # try: - # # --numeric-owner hides the username of the builder for - # # security etc. - # self.run_command('tar -C %(dir)s --numeric-owner -cjf ' - # '%(inst_path)s.tar.bz2 %(inst_name)s' % { - # 'dir': self.get_build_prefix(), - # 'inst_name': installer_name, - # 'inst_path':self.build_path_of(installer_name)}) - # finally: - # self.run_command("mv %(inst)s %(dst)s" % { - # 'dst': self.get_dst_prefix(), - # 'inst': self.build_path_of(installer_name)}) - -class Linux_i686Manifest(LinuxManifest): - def construct(self): - super(Linux_i686Manifest, self).construct() - self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") - - - if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"): - self.path("libapr-1.so.0") - self.path("libaprutil-1.so.0") - self.path("libdb-4.2.so") - self.path("libcrypto.so.0.9.7") - self.path("libexpat.so.1") - self.path("libssl.so.0.9.7") - self.path("libuuid.so", "libuuid.so.1") - self.path("libSDL-1.2.so.0") - self.path("libELFIO.so") - self.path("libopenjpeg.so.2") - self.path("libxml2.so.2") - self.path("libz.so.1") - - # OpenAL - self.path("libopenal.so.1") - self.path("libalut.so.0") - - # GTK+ and dependencies - self.path("libatk-1.0.so.0") - self.path("libcairo.so.2") - self.path("libfontconfig.so.1") - self.path("libfreetype.so.6") - # self.path("libgdk_pixbuf-2.0.so.0") # see linux64 why - self.path("libgdk-x11-2.0.so.0") - self.path("libgtk-x11-2.0.so.0") - # self.path("libpango-1.0.so.0") # dto. - # self.path("libpangoft2-1.0.so.0") - # self.path("libpangox-1.0.so.0") - # self.path("libpangoxft-1.0.so.0") - self.path("libpixman-1.so.0") - - # Gstreamer libs - self.path("libgstbase-0.10.so.0") - self.path("libgstreamer-0.10.so.0") - self.path("libgstaudio-0.10.so.0") - self.path("libgstbase-0.10.so.0") - self.path("libgstcontroller-0.10.so.0") - self.path("libgstdataprotocol-0.10.so.0") - self.path("libgstinterfaces-0.10.so.0") - self.path("libgstnetbuffer-0.10.so.0") - self.path("libgstpbutils-0.10.so.0") - self.path("libgstriff-0.10.so.0") - self.path("libgstrtp-0.10.so.0") - self.path("libgstrtsp-0.10.so.0") - self.path("libgstsdp-0.10.so.0") - self.path("libgsttag-0.10.so.0") - self.path("libgstvideo-0.10.so.0") - - # Gstreamer plugin dependencies - self.path("libfaad.so.0") - self.path("libogg.so.0") - self.path("libtheora.so.0") - self.path("libvorbis.so.0") - self.path("libvorbisenc.so.2") - self.path("liboil-0.3.so.0") - - # Gstreamer plugins - if self.prefix("gstreamer-plugins"): - self.path("libgstalsa.so") - self.path("libgstasf.so") - self.path("libgstaudioconvert.so") - self.path("libgstaudioresample.so") - self.path("libgstautodetect.so") - self.path("libgstavi.so") - self.path("libgstcoreelements.so") - self.path("libgstcoreindexers.so") - self.path("libgstdecodebin2.so") - self.path("libgstdecodebin.so") - self.path("libgstesd.so") - self.path("libgstfaad.so") - self.path("libgstffmpeg.so") - self.path("libgstgnomevfs.so") - self.path("libgsticydemux.so") - self.path("libgstid3demux.so") - self.path("libgstmpegdemux.so") - self.path("libgstmultifile.so") - self.path("libgstmultipart.so") - self.path("libgstogg.so") - self.path("libgstossaudio.so") - self.path("libgstplaybin.so") - self.path("libgstpulse.so") - self.path("libgstqtdemux.so") - self.path("libgstqueue2.so") - self.path("libgsttcp.so") - self.path("libgsttheora.so") - self.path("libgsttypefindfunctions.so") - self.path("libgstudp.so") - self.path("libgstvideoscale.so") - self.path("libgstvolume.so") - self.path("libgstvorbis.so") - self.path("libgstwavparse.so") - - self.end_prefix("gstreamer-plugins") - - self.end_prefix("lib") - - # Vivox runtimes and libs - if self.prefix(src="vivox-runtime/i686-linux", dst="bin"): - self.path("SLVoice") - self.end_prefix("bin") - - if self.prefix(src="vivox-runtime/i686-linux", dst="lib"): - self.path("libalut.so") - self.path("libortp.so") - self.path("libvivoxsdk.so") - self.end_prefix("lib") - -class Linux_x86_64Manifest(LinuxManifest): - def construct(self): - super(Linux_x86_64Manifest, self).construct() - self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") -# self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin") - - self.path("linux_tools/launch_url.sh","launch_url.sh") - if self.prefix("res-sdl"): - self.path("*") - # recurse - self.end_prefix("res-sdl") - - self.path("featuretable_linux.txt") - #self.path("secondlife-x86_64.supp") - - self.path("app_settings/mozilla-runtime-linux-x86_64") - - if self.prefix("../../libraries/x86_64-linux/lib_release_client", dst="lib64"): - self.path("libapr-1.so.0") - self.path("libaprutil-1.so.0") - self.path("libdb-4.2.so") - self.path("libcrypto.so.0.9.8") - self.path("libexpat.so.1") - self.path("libssl.so.0.9.8") - self.path("libuuid.so", "libuuid.so.1") - self.path("libSDL-1.2.so.0") - self.path("libELFIO.so") - self.path("libjpeg.so.7") - self.path("libpng12.so.0") - self.path("libopenjpeg.so.2") - self.path("libxml2.so.2") - #self.path("libz.so.1") #not needed - - # OpenAL - self.path("libopenal.so.1") - self.path("libalut.so.0") - - # GTK+ and dependencies - self.path("libatk-1.0.so.0") - self.path("libcairo.so.2") - self.path("libfontconfig.so.1") - self.path("libfreetype.so.6") - self.path("libgdk_pixbuf-2.0.so.0") # was commented to use systems gdk pixbufs instead - - # but seems webkit needs it o_O . Packaging for testing now. - self.path("libgdk-x11-2.0.so.0") - self.path("libgtk-x11-2.0.so.0") -# self.path("libpango-1.0.so.0") # use systems pango instead -# self.path("libpangoft2-1.0.so.0") # Both gdk pixbufs and pango would load systems modules -# self.path("libpangox-1.0.so.0") # and crash if not compatible or present. -# self.path("libpangoxft-1.0.so.0") # So we depend system gdk pixbufs and pango anyway. - self.path("libpixman-1.so.0") - - # Gstreamer libs - self.path("libgstbase-0.10.so.0") - self.path("libgstreamer-0.10.so.0") - self.path("libgstaudio-0.10.so.0") - self.path("libgstbase-0.10.so.0") - self.path("libgstcontroller-0.10.so.0") - self.path("libgstdataprotocol-0.10.so.0") - self.path("libgstinterfaces-0.10.so.0") - self.path("libgstnetbuffer-0.10.so.0") - self.path("libgstpbutils-0.10.so.0") - self.path("libgstriff-0.10.so.0") - self.path("libgstrtp-0.10.so.0") - self.path("libgstrtsp-0.10.so.0") - self.path("libgstsdp-0.10.so.0") - self.path("libgsttag-0.10.so.0") - self.path("libgstvideo-0.10.so.0") - - # Gstreamer plugin dependencies - self.path("libfaad.so.0") - self.path("libogg.so.0") - self.path("libtheora.so.0") - self.path("libvorbis.so.0") - self.path("libvorbisenc.so.2") - self.path("liboil-0.3.so.0") - - # Gstreamer plugins - if self.prefix("gstreamer-plugins"): - self.path("libgstalsa.so") - self.path("libgstasf.so") - self.path("libgstaudioconvert.so") - self.path("libgstaudioresample.so") - self.path("libgstautodetect.so") - self.path("libgstavi.so") - self.path("libgstcoreelements.so") - self.path("libgstcoreindexers.so") - self.path("libgstdecodebin2.so") - self.path("libgstdecodebin.so") - self.path("libgstesd.so") - self.path("libgstfaad.so") - self.path("libgstffmpeg.so") - self.path("libgstffmpegcolorspace.so") - self.path("libgstgnomevfs.so") - self.path("libgsticydemux.so") - self.path("libgstid3demux.so") - self.path("libgstmpegdemux.so") - self.path("libgstmultifile.so") - self.path("libgstmultipart.so") - self.path("libgstogg.so") - self.path("libgstossaudio.so") - self.path("libgstplaybin.so") - self.path("libgstpulse.so") - self.path("libgstqtdemux.so") - self.path("libgstqueue2.so") - self.path("libgsttcp.so") - self.path("libgsttheora.so") - self.path("libgsttypefindfunctions.so") - self.path("libgstudp.so") - self.path("libgstvideoscale.so") - self.path("libgstvolume.so") - self.path("libgstvorbis.so") - self.path("libgstwavparse.so") - - self.end_prefix("gstreamer-plugins") - self.end_prefix("lib64") - - - # Vivox runtimes and libs - if self.prefix(src="vivox-runtime/i686-linux", dst="bin"): - self.path("SLVoice") - self.end_prefix("bin") - - if self.prefix(src="vivox-runtime/i686-linux", dst="lib32"): - #self.path("libalut.so") - self.path("libortp.so") - self.path("libvivoxsdk.so") - self.end_prefix("lib32") - - # 32bit libs needed for voice - if self.prefix("../../libraries/x86_64-linux/lib_release_client/32bit-compat", dst="lib32"): - self.path("libalut.so") - self.path("libidn.so.11") - self.path("libopenal.so.1") - # self.path("libortp.so") - self.path("libuuid.so.1") - self.end_prefix("lib32") - -if __name__ == "__main__": - main() diff --git a/linden/install.xml b/linden/install.xml index 402ce00ef..5154fe047 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -735,20 +735,6 @@ <key>url</key> <uri>http://imprudenceviewer.org/download/libs/gstreamer-plugins-darwin-20100826.tar.bz2</uri> </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>973aabcba37f6ee0ceab2e3d063eea84</string> - <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/gstreamer-plugins-linux-20100827.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>663c29f3885ab8429ad6841d80181c31</string> - <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/gstreamer-plugins-linux64-20100827.tar.bz2</uri> - </map> </map> </map> <key>gtk-etc</key> From e596df5f4e84229f0c7edf02490197e3cef33f70 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Fri, 10 Sep 2010 11:11:16 +0200 Subject: [PATCH 033/239] fix conversion that is ambiguous for linux64 gcc; introduced in 11e4c300 maybe squash with 11e4c300 --- linden/indra/newview/llfloaterassetbrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llfloaterassetbrowser.cpp b/linden/indra/newview/llfloaterassetbrowser.cpp index 9b4139066..ca0e8d17d 100644 --- a/linden/indra/newview/llfloaterassetbrowser.cpp +++ b/linden/indra/newview/llfloaterassetbrowser.cpp @@ -122,7 +122,7 @@ void LLFloaterAssetBrowser::createThumbnails() temp.mUUID = itemp->getUUID(); temp.mName = itemp->getName(); temp.mTexturep = NULL; - temp.mAssetRect = NULL; + temp.mAssetRect = LLRect::null; mTextureAssets.push_back(temp); } From 2e63340ddd69bfd41930e52dcb97912f282c8a32 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Fri, 10 Sep 2010 21:01:31 +0200 Subject: [PATCH 034/239] fix minimap surface not rendered --- linden/indra/newview/llsurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index 2e20aced1..700ff8ee9 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp @@ -278,7 +278,7 @@ void LLSurface::createWaterTexture() } } - mWaterTexturep = new LLViewerImage(sTextureSize/2, sTextureSize/2, 4, FALSE); + mWaterTexturep = new LLViewerImage(raw, FALSE); mWaterTexturep->dontDiscard(); gGL.getTexUnit(0)->bind(mWaterTexturep); mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); From 341f3416d4108f625f1591ed7afe78324e560480 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Sun, 19 Sep 2010 21:51:40 +0200 Subject: [PATCH 035/239] fix: cached trees + grass white on opensim issues remaining: windlight water is "flat" --- linden/indra/newview/llvograss.cpp | 5 +++-- linden/indra/newview/llvograss.h | 2 +- linden/indra/newview/llvotree.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index c56d676a7..e516aebba 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -108,7 +108,9 @@ void LLVOGrass::updateSpecies() SpeciesMap::const_iterator it = sSpeciesTable.begin(); mSpecies = (*it).first; } - setTEImage(0, gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName)); + + mGrassImage = gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName, TRUE, TRUE); + setTEImage(0, mGrassImage); } @@ -162,7 +164,6 @@ void LLVOGrass::initClass() GrassSpeciesData* newGrass = new GrassSpeciesData(); - std::string textureName; static LLStdStringHandle texture_name_string = LLXmlTree::addAttributeString("texture_name"); diff --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index c55c59b73..c05908bbb 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -128,7 +128,7 @@ class LLVOGrass : public LLAlphaObject void updateSpecies(); F32 mLastHeight; // For cheap update hack S32 mNumBlades; - + LLPointer<LLViewerImage> mGrassImage; static SpeciesMap sSpeciesTable; }; #endif // LL_VO_GRASS_ diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index 89d649121..53cfbdb5d 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -324,7 +324,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, // // Load Species-Specific data // - mTreeImagep = gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName); + mTreeImagep = gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName, TRUE, TRUE); if (mTreeImagep) { gGL.getTexUnit(0)->bind(mTreeImagep.get()); From 994de98c7bf0461a5e1c1ea6aea517d9437ea4fd Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Mon, 20 Sep 2010 11:48:27 +0200 Subject: [PATCH 036/239] one more poke on trees+grass + fix the windlight water --- linden/indra/newview/llviewerimagelist.cpp | 2 +- linden/indra/newview/llvograss.cpp | 9 +++++++-- linden/indra/newview/llvograss.h | 2 +- linden/indra/newview/llvotree.cpp | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp index f795de61f..7642e8079 100644 --- a/linden/indra/newview/llviewerimagelist.cpp +++ b/linden/indra/newview/llviewerimagelist.cpp @@ -156,7 +156,7 @@ void LLViewerImageList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } - image = getImage(DEFAULT_WATER_NORMAL, MIPMAP_YES, IMMEDIATE_YES); + image = getImageFromFile(DEFAULT_WATER_NORMAL.asString()+".j2c", MIPMAP_YES, IMMEDIATE_YES,0,0,DEFAULT_WATER_NORMAL); if (image) { image->setAddressMode(LLTexUnit::TAM_WRAP); diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index e516aebba..8f4c0de4f 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -109,8 +109,8 @@ void LLVOGrass::updateSpecies() mSpecies = (*it).first; } - mGrassImage = gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName, TRUE, TRUE); - setTEImage(0, mGrassImage); + LLViewerImage* grass_image = gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName, TRUE, TRUE, 0, 0, sSpeciesTable[mSpecies]->mTextureID); + setTEImage(0, grass_image); } @@ -170,6 +170,11 @@ void LLVOGrass::initClass() success &= grass_def->getFastAttributeString(texture_name_string, textureName); newGrass->mTextureName = textureName; + std::string textureID; + static LLStdStringHandle texture_id = LLXmlTree::addAttributeString("texture_id"); + success &= grass_def->getFastAttributeString(texture_id, textureID); + newGrass->mTextureID = LLUUID(textureID); + static LLStdStringHandle blade_sizex_string = LLXmlTree::addAttributeString("blade_size_x"); success &= grass_def->getFastAttributeF32(blade_sizex_string, F32_val); newGrass->mBladeSizeX = F32_val; diff --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index c05908bbb..86e4b954a 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -128,7 +128,7 @@ class LLVOGrass : public LLAlphaObject void updateSpecies(); F32 mLastHeight; // For cheap update hack S32 mNumBlades; - LLPointer<LLViewerImage> mGrassImage; +// LLPointer<LLViewerImage> mGrassImage; static SpeciesMap sSpeciesTable; }; #endif // LL_VO_GRASS_ diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index 53cfbdb5d..fc38a5f55 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -324,7 +324,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, // // Load Species-Specific data // - mTreeImagep = gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName, TRUE, TRUE); + mTreeImagep = gImageList.getImageFromFile(sSpeciesTable[mSpecies]->mTextureName, TRUE, TRUE, 0, 0, sSpeciesTable[mSpecies]->mTextureID); if (mTreeImagep) { gGL.getTexUnit(0)->bind(mTreeImagep.get()); From b6ca1620c712288268913dfb616fbd3d96c1fcf5 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sat, 9 Oct 2010 10:20:10 +0100 Subject: [PATCH 037/239] Fix some STL errors highlighted by MSVC debug --- linden/indra/llrender/llfontregistry.cpp | 2 +- linden/indra/llui/lllineeditor.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/linden/indra/llrender/llfontregistry.cpp b/linden/indra/llrender/llfontregistry.cpp index 2140dbd4b..9792a91de 100644 --- a/linden/indra/llrender/llfontregistry.cpp +++ b/linden/indra/llrender/llfontregistry.cpp @@ -107,7 +107,7 @@ bool removeSubString(std::string& str, const std::string& substr) size_t pos = str.find(substr); if (pos != string::npos) { - str.replace(pos,substr.length(),(const char *)NULL, 0); + str.erase(pos,substr.length()); return true; } return false; diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index e73b287fb..a3785e46d 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -416,7 +416,16 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) setCursor(llmin((S32)mText.length(), getCursor())); // Set current history line to end of history. - mCurrentHistoryLine = mLineHistory.end() - 1; + // RC Fix, its really not safe to just take 1 of the end itterator, if end==begin + // that leaves an invalid state upseting the secure STL checks + if(mLineHistory.empty()) + { + mCurrentHistoryLine = mLineHistory.begin(); + } + else + { + mCurrentHistoryLine = mLineHistory.end() - 1; + } mPrevText = mText; } From 1924ac57d991dc00ef7eb7c121ac7e7064b29717 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sat, 9 Oct 2010 10:22:23 +0100 Subject: [PATCH 038/239] Add a fall back to find NSIS on win64 --- linden/indra/newview/viewer_manifest.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 7563268b6..f01cd7a5a 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -517,8 +517,12 @@ def package_finish(self): # We use the Unicode version of NSIS, available from # http://www.scratchpaper.com/ - NSIS_path = 'C:\\Program Files\\NSIS\\Unicode\\makensis.exe' - self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile)) + try: + NSIS_path = 'C:\\Program Files\\NSIS\\Unicode\\makensis.exe' + self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile)) + except: + NSIS_path = 'C:\\Program Files (x86)\\NSIS\\Unicode\\makensis.exe' + self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile)) # self.remove(self.dst_path_of(tempfile)) # If we're on a build machine, sign the code using our Authenticode certificate. JC sign_py = 'C:\\buildscripts\\code-signing\\sign.py' From db79d815c873d3c2c408e4f0e10ace4a345ddf99 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sat, 9 Oct 2010 10:23:52 +0100 Subject: [PATCH 039/239] Fix tab/space issues in viewer_manifest.py --- linden/indra/newview/viewer_manifest.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index f01cd7a5a..ff59aec75 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -845,7 +845,7 @@ def construct(self): self.path("wrapper.sh","imprudence") self.path("handle_secondlifeprotocol.sh") self.path("register_secondlifeprotocol.sh") - self.path("getvoice.sh") + self.path("getvoice.sh") self.end_prefix("linux_tools") self.gather_documents() @@ -974,7 +974,7 @@ def construct(self): self.path("libgstvideo-0.10.so.0") # Gstreamer plugin dependencies - self.path("libfaad.so.0") + self.path("libfaad.so.0") self.path("libogg.so.0") self.path("libtheora.so.0") self.path("libvorbis.so.0") @@ -1124,7 +1124,7 @@ def construct(self): self.path("libgstdecodebin2.so") self.path("libgstdecodebin.so") self.path("libgstesd.so") - self.path("libgstfaad.so") + self.path("libgstfaad.so") self.path("libgstffmpeg.so") self.path("libgstffmpegcolorspace.so") self.path("libgstgnomevfs.so") @@ -1162,14 +1162,14 @@ def construct(self): self.path("libortp.so") self.path("libvivoxsdk.so") self.end_prefix("lib32") - - # 32bit libs needed for voice - if self.prefix("../../libraries/x86_64-linux/lib_release_client/32bit-compat", dst="lib32"): - self.path("libalut.so") - self.path("libidn.so.11") - self.path("libopenal.so.1") - # self.path("libortp.so") - self.path("libuuid.so.1") + + # 32bit libs needed for voice + if self.prefix("../../libraries/x86_64-linux/lib_release_client/32bit-compat", dst="lib32"): + self.path("libalut.so") + self.path("libidn.so.11") + self.path("libopenal.so.1") + # self.path("libortp.so") + self.path("libuuid.so.1") self.end_prefix("lib32") if __name__ == "__main__": From 13e0e20e1be8a3437c8672369e25dec8e38ea983 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sat, 9 Oct 2010 10:30:11 +0100 Subject: [PATCH 040/239] Use all those cores for compile --- linden/indra/cmake/00-Common.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/linden/indra/cmake/00-Common.cmake b/linden/indra/cmake/00-Common.cmake index 3497ec996..032a3cf13 100644 --- a/linden/indra/cmake/00-Common.cmake +++ b/linden/indra/cmake/00-Common.cmake @@ -55,6 +55,7 @@ if (WINDOWS) /Zc:forScope /nologo /Oy- + /MP ) if(MSVC80 OR MSVC90) From f001c10b78553fe3a59a2a71c223d094118bf8a8 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 10 Oct 2010 15:48:32 +0100 Subject: [PATCH 041/239] Let the gstreamer plugin build on windows --- linden/indra/cmake/GStreamer010Plugin.cmake | 29 +++++++++++++++---- .../llmediaimplgstreamertriviallogging.h | 15 ++++++++-- .../media_plugin_gstreamer010.cpp | 11 +++++-- linden/indra/newview/CMakeLists.txt | 20 ++++++++++--- linden/indra/newview/viewer_manifest.py | 6 +++- 5 files changed, 67 insertions(+), 14 deletions(-) diff --git a/linden/indra/cmake/GStreamer010Plugin.cmake b/linden/indra/cmake/GStreamer010Plugin.cmake index 78ffd941a..cafcd4c6a 100644 --- a/linden/indra/cmake/GStreamer010Plugin.cmake +++ b/linden/indra/cmake/GStreamer010Plugin.cmake @@ -6,7 +6,8 @@ if (STANDALONE) pkg_check_modules(GSTREAMER010 REQUIRED gstreamer-0.10) pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10) -elseif (LINUX) +endif (STANDALONE) + use_prebuilt_binary(gstreamer) # possible libxml should have its own .cmake file instead use_prebuilt_binary(libxml) @@ -17,6 +18,21 @@ elseif (LINUX) ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 ) + +if (WINDOWS) + # We don't need to explicitly link against gstreamer itself, because + # LLMediaImplGStreamer probes for the system's copy at runtime. + set(GSTREAMER010_LIBRARIES + libgstvideo + libgstaudio + libgstbase-0.10 + libgstreamer-0.10 + gobject-2.0 + gmodule-2.0 + gthread-2.0 + glib-2.0 + ) +else (WINDOWS) # We don't need to explicitly link against gstreamer itself, because # LLMediaImplGStreamer probes for the system's copy at runtime. set(GSTREAMER010_LIBRARIES @@ -31,13 +47,16 @@ elseif (LINUX) rt glib-2.0 ) -endif (STANDALONE) + + +endif (WINDOWS) + if (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND) set(GSTREAMER010 ON CACHE BOOL "Build with GStreamer-0.10 streaming media support.") + add_definitions(-DLL_GSTREAMER010_ENABLED=1) endif (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND) -if (GSTREAMER010) - add_definitions(-DLL_GSTREAMER010_ENABLED=1) -endif (GSTREAMER010) + + diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h index f5da63720..0ea096aab 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h @@ -40,18 +40,29 @@ extern "C" { #include <sys/types.h> -#include <unistd.h> +//#include <unistd.h> //fiuxme } +#define MSGMODULEFOO "(media plugin)" + +#ifdef LL_LINUX ///////////////////////////////////////////////////////////////////////// // Debug/Info/Warning macros. -#define MSGMODULEFOO "(media plugin)" + #define STDERRMSG(...) do{\ fprintf(stderr, " pid:%d: ", (int)getpid());\ fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\ fprintf(stderr, __VA_ARGS__);\ fputc('\n',stderr);\ }while(0) +#else +#define STDERRMSG(...) do{\ + fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\ + fprintf(stderr, __VA_ARGS__);\ + fputc('\n',stderr);\ + }while(0) +#endif + #define NULLMSG(...) do{}while(0) #define DEBUGMSG NULLMSG diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 4dd182eb7..44bc32eef 100755 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -35,6 +35,13 @@ #include "linden_common.h" +// Needed for _getcwd() RC +#ifdef LL_WINDOWS +#include <direct.h> +#include <stdlib.h> +#include <stdio.h> +#endif + #include "llgl.h" #include "llplugininstance.h" @@ -84,7 +91,7 @@ class MediaPluginGStreamer010 : public MediaPluginBase bool play(double rate); bool getTimePos(double &sec_out); - static const double MIN_LOOP_SEC = 1.0F; + #define MIN_LOOP_SEC 1.0F bool mIsLooping; @@ -689,7 +696,7 @@ MediaPluginGStreamer010::load() DEBUGMSG("setting up media..."); mIsLooping = false; - mVolume = 0.1234567; // minor hack to force an initial volume update + mVolume = (float) 0.1234567; // minor hack to force an initial volume update // Create a pumpable main-loop for this media mPump = g_main_loop_new (NULL, FALSE); diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 3dabb3bb1..8b1d59af8 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1336,7 +1336,7 @@ if (WINDOWS) DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit media_plugin_gstreamer) if (PACKAGE) add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat) @@ -1456,7 +1456,7 @@ if (DARWIN) DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit media_plugin_gstreamer010) if (PACKAGE) add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME}) @@ -1481,7 +1481,7 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit media_plugin_gstreamer010) add_custom_command( TARGET package POST_BUILD COMMAND ${PYTHON_EXECUTABLE} @@ -1534,7 +1534,19 @@ if (WINDOWS) ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin COMMENT "Copying WebKit Plugin to the runtime folder." ) - + + get_target_property(BUILT_GSTREAMER_PLUGIN media_plugin_gstreamer010 LOCATION) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${BUILT_GSTREAMER_PLUGIN} + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin + COMMENT "Copying Gstreamer Plugin to the runtime folder." + ) + get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION) add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 4c95f00dc..9c2dbed1d 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -257,7 +257,6 @@ def construct(self): self.path("alut.dll") self.end_prefix() - # Media plugins - QuickTime if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"): self.path("media_plugin_quicktime.dll") @@ -268,6 +267,11 @@ def construct(self): self.path("media_plugin_webkit.dll") self.end_prefix() + # Media plugins - Gstreamer + if self.prefix(src='../media_plugins/gstreamer/%s' % self.args['configuration'], dst="llplugin"): + self.path("media_plugin_gstreamer010.dll") + self.end_prefix() + # For WebKit/Qt plugin runtimes if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"): self.path("libeay32.dll") From 1d3e052f723df0c3670e271a792a3bd84d6d1ca5 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 10 Oct 2010 15:52:28 +0100 Subject: [PATCH 042/239] Force mime_types.xml to use gstreamer as default --- .../skins/default/xui/en-us/mime_types.xml | 38 +++++++++---------- .../default/xui/en-us/mime_types_windows.xml | 36 +++++++++--------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml index a585069fa..360438a51 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml @@ -109,7 +109,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </scheme> <mimetype name="blank"> @@ -142,7 +142,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="video/*"> @@ -153,7 +153,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="image/*"> @@ -169,13 +169,13 @@ </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> - Movie (QuickTime) + Movie (gstreamer) </label> <widgettype> movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="application/javascript"> @@ -197,7 +197,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="application/pdf"> @@ -274,7 +274,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="audio/mpeg"> @@ -285,7 +285,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="audio/x-aiff"> @@ -296,7 +296,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="audio/x-wav"> @@ -307,7 +307,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype menu="1" name="image/bmp"> @@ -417,7 +417,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="video/mp4"> @@ -428,18 +428,18 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> - <mimetype menu="1" name="video/quicktime"> - <label name="video/quicktime_label"> - Movie (QuickTime) + <mimetype menu="1" name="video/gstreamer"> + <label name="video/gstreamer_label"> + Movie (gstreamer) </label> <widgettype> movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="video/x-ms-asf"> @@ -450,7 +450,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype name="video/x-ms-wmv"> @@ -461,7 +461,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> @@ -472,7 +472,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> </mimetypes> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml index 4a7a6e17a..d4d47cb45 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml @@ -109,7 +109,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer </impl> </scheme> <mimetype name="blank"> @@ -120,7 +120,7 @@ none </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer </impl> </mimetype> <mimetype name="none/none"> @@ -157,13 +157,13 @@ </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> - Movie (QuickTime) + Movie (gstreamer) </label> <widgettype> movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer </impl> </mimetype> <mimetype name="application/javascript"> @@ -214,7 +214,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -241,7 +241,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer </impl> </mimetype> <mimetype name="audio/mpeg"> @@ -252,7 +252,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer </impl> </mimetype> <mimetype name="audio/x-aiff"> @@ -263,7 +263,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer </impl> </mimetype> <mimetype name="audio/x-wav"> @@ -274,7 +274,7 @@ audio </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010 </impl> </mimetype> <mimetype menu="1" name="image/bmp"> @@ -384,7 +384,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010010 </impl> </mimetype> <mimetype name="video/mp4"> @@ -395,18 +395,18 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010010 </impl> </mimetype> - <mimetype menu="1" name="video/quicktime"> - <label name="video/quicktime_label"> - Movie (QuickTime) + <mimetype menu="1" name="video/gstreamer"> + <label name="video/gstreamer_label"> + Movie (gstreamer) </label> <widgettype> movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010010 </impl> </mimetype> <mimetype name="video/x-ms-asf"> @@ -417,7 +417,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010010 </impl> </mimetype> <mimetype name="video/x-ms-wmv"> @@ -428,7 +428,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010010 </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> @@ -439,7 +439,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_gstreamer010010 </impl> </mimetype> </mimetypes> From b5f6f8919b99e897ea4616e8df4a10b281f51826 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Sat, 25 Sep 2010 00:49:50 +0200 Subject: [PATCH 043/239] Thickbrick Sleaford, Soft Linden: STORM-164 make gcc-4.4 happy about llvosky.h --- linden/indra/newview/llvosky.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llvosky.h b/linden/indra/newview/llvosky.h index 5e2306515..08038a5a2 100644 --- a/linden/indra/newview/llvosky.h +++ b/linden/indra/newview/llvosky.h @@ -147,7 +147,7 @@ class LLSkyTex static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } - static S32 stepCurrent() { return (sCurrent = ++sCurrent % 2); } + static S32 stepCurrent() { sCurrent++; sCurrent&=1; return sCurrent; } static S32 getNext() { return ((sCurrent+1) % 2); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } From b3b30285126289f54b57bd42569bb0721e40e088 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 10 Oct 2010 22:10:33 +0100 Subject: [PATCH 044/239] Revert "port of LL renderpipeline/Kirstens S19 pipeline for bridging to Viewer 2 texture system" This reverts commit 087e15e89930d51c3964329befb273ae3b2d330d. Conflicts: linden/indra/newview/llsurface.cpp linden/indra/newview/llviewerwindow.cpp linden/indra/newview/llvoavatar.cpp linden/indra/newview/pipeline.cpp linden/indra/newview/pipeline.h --- linden/indra/llmath/llbbox.cpp | 162 - linden/indra/llmath/llbbox.h | 103 - linden/indra/llmath/llcamera.cpp | 24 - linden/indra/llmath/llcamera.h | 16 +- linden/indra/llmath/llmath.h | 2 +- linden/indra/llmath/llmodularmath.cpp | 36 - linden/indra/llmath/llvolume.cpp | 14 +- linden/indra/llrender/CMakeLists.txt | 5 +- linden/indra/llrender/llcubemap.cpp | 17 +- linden/indra/llrender/llfont.cpp | 2 +- linden/indra/llrender/llfontgl.cpp | 6 +- linden/indra/llrender/llgl.cpp | 8 +- linden/indra/llrender/llgl.h | 31 - linden/indra/llrender/llglslshader.cpp | 2 +- linden/indra/llrender/llimagegl.cpp | 451 ++- linden/indra/llrender/llimagegl.h | 117 +- linden/indra/llrender/llrender.cpp | 64 +- linden/indra/llrender/llrendertarget.cpp | 57 +- linden/indra/llrender/llrendertarget.h | 1 - linden/indra/llrender/lltextureatlas.cpp | 411 --- linden/indra/llrender/lltextureatlas.h | 92 - linden/indra/llrender/llvertexbuffer.cpp | 72 +- linden/indra/newview/CMakeLists.txt | 4 - .../indra/newview/app_settings/settings.xml | 701 +---- .../shaders/class1/deferred/alphaF.glsl | 24 +- .../shaders/class1/deferred/alphaV.glsl | 10 +- .../shaders/class1/deferred/avatarAlphaF.glsl | 2 +- .../shaders/class1/deferred/avatarF.glsl | 13 +- .../class1/deferred/avatarShadowF.glsl | 3 +- .../class1/deferred/avatarShadowV.glsl | 3 +- .../shaders/class1/deferred/avatarV.glsl | 2 + .../shaders/class1/deferred/blurLightF.glsl | 41 +- .../shaders/class1/deferred/bumpF.glsl | 8 +- .../shaders/class1/deferred/bumpV.glsl | 3 + .../shaders/class1/deferred/diffuseF.glsl | 6 +- .../shaders/class1/deferred/diffuseV.glsl | 5 +- .../shaders/class1/deferred/fullbrightF.glsl | 28 +- .../shaders/class1/deferred/fullbrightV.glsl | 2 +- .../shaders/class1/deferred/giF.glsl | 165 - .../shaders/class1/deferred/giV.glsl | 22 - .../shaders/class1/deferred/luminanceF.glsl | 15 - .../shaders/class1/deferred/luminanceV.glsl | 20 - .../class1/deferred/multiPointLightF.glsl | 62 +- .../class1/deferred/multiSpotLightF.glsl | 184 -- .../shaders/class1/deferred/pointLightF.glsl | 61 +- .../shaders/class1/deferred/pointLightV.glsl | 6 +- .../class1/deferred/postDeferredF.glsl | 57 - .../class1/deferred/postDeferredV.glsl | 17 - .../shaders/class1/deferred/postgiF.glsl | 107 - .../shaders/class1/deferred/postgiV.glsl | 16 - .../shaders/class1/deferred/shadowF.glsl | 3 - .../shaders/class1/deferred/shadowV.glsl | 10 +- .../shaders/class1/deferred/softenLightF.glsl | 4 + .../shaders/class1/deferred/spotLightF.glsl | 199 -- .../shaders/class1/deferred/sunLightF.glsl | 111 +- .../shaders/class1/deferred/terrainF.glsl | 6 +- .../shaders/class1/deferred/terrainV.glsl | 2 + .../shaders/class1/deferred/treeF.glsl | 4 +- .../shaders/class1/deferred/treeV.glsl | 3 + .../shaders/class1/deferred/waterF.glsl | 2 +- .../shaders/class1/effects/colorFilterF.glsl | 31 - .../shaders/class1/effects/drawQuadV.glsl | 14 - .../shaders/class1/effects/nightVisionF.glsl | 42 - .../shaders/class2/deferred/alphaF.glsl | 112 - .../shaders/class2/deferred/alphaV.glsl | 75 - .../shaders/class2/deferred/avatarAlphaF.glsl | 77 - .../shaders/class2/deferred/avatarAlphaV.glsl | 78 - .../shaders/class2/deferred/blurLightF.glsl | 71 - .../shaders/class2/deferred/blurLightV.glsl | 17 - .../class2/deferred/multiSpotLightF.glsl | 188 -- .../class2/deferred/postDeferredF.glsl | 59 - .../class2/deferred/postDeferredV.glsl | 17 - .../shaders/class2/deferred/softenLightF.glsl | 294 -- .../shaders/class2/deferred/softenLightV.glsl | 24 - .../shaders/class2/deferred/spotLightF.glsl | 199 -- .../shaders/class2/deferred/sunLightF.glsl | 203 -- .../shaders/class2/deferred/sunLightV.glsl | 25 - .../shaders/class2/deferred/waterF.glsl | 139 - .../shaders/class2/deferred/waterV.glsl | 76 - .../shaders/class3/deferred/avatarF.glsl | 18 - .../shaders/class3/deferred/bumpF.glsl | 27 - .../shaders/class3/deferred/diffuseF.glsl | 18 - .../class3/deferred/giDownsampleF.glsl | 84 - .../class3/deferred/giDownsampleV.glsl | 17 - .../shaders/class3/deferred/giF.glsl | 219 -- .../shaders/class3/deferred/giV.glsl | 22 - .../shaders/class3/deferred/luminanceF.glsl | 16 - .../shaders/class3/deferred/luminanceV.glsl | 20 - .../class3/deferred/postDeferredF.glsl | 76 - .../class3/deferred/postDeferredV.glsl | 17 - .../shaders/class3/deferred/postgiF.glsl | 87 - .../shaders/class3/deferred/postgiV.glsl | 17 - .../shaders/class3/deferred/softenLightF.glsl | 312 -- .../shaders/class3/deferred/softenLightV.glsl | 24 - .../shaders/class3/deferred/treeF.glsl | 18 - .../shaders/class3/deferred/waterF.glsl | 139 - .../shaders/class3/effects/blurF.glsl | 31 - .../shaders/class3/effects/blurV.glsl | 35 - .../shaders/class3/effects/colorFilterF.glsl | 31 - .../shaders/class3/effects/drawQuadV.glsl | 14 - .../shaders/class3/effects/extractF.glsl | 22 - .../shaders/class3/effects/nightVisionF.glsl | 42 - .../shaders/class3/effects/simpleF.glsl | 14 - linden/indra/newview/llagent.cpp | 3 +- linden/indra/newview/llagent.h | 1 - linden/indra/newview/llappviewer.cpp | 2 +- linden/indra/newview/llcolorswatch.cpp | 3 +- linden/indra/newview/llcompilequeue.cpp | 1 + linden/indra/newview/llconsole.cpp | 166 +- linden/indra/newview/llconsole.h | 47 +- linden/indra/newview/lldebugview.cpp | 24 +- linden/indra/newview/lldrawable.cpp | 76 +- linden/indra/newview/lldrawable.h | 3 +- linden/indra/newview/lldrawpool.h | 5 - linden/indra/newview/lldrawpoolalpha.cpp | 59 +- linden/indra/newview/lldrawpoolavatar.cpp | 69 +- linden/indra/newview/lldrawpoolbump.cpp | 25 +- linden/indra/newview/lldrawpoolsky.cpp | 68 +- linden/indra/newview/lldrawpoolsky.h | 4 - linden/indra/newview/lldrawpoolterrain.cpp | 6 +- linden/indra/newview/lldrawpooltree.cpp | 15 +- linden/indra/newview/lldrawpoolwater.cpp | 20 +- linden/indra/newview/lldynamictexture.cpp | 21 +- linden/indra/newview/lldynamictexture.h | 4 +- linden/indra/newview/llface.cpp | 445 +-- linden/indra/newview/llface.h | 38 +- .../indra/newview/llfloaterassetbrowser.cpp | 16 +- linden/indra/newview/llfloaterchat.cpp | 3 +- .../newview/llfloaterhardwaresettings.cpp | 27 +- .../indra/newview/llfloaterhardwaresettings.h | 4 - linden/indra/newview/llfloaterlagmeter.cpp | 2 +- linden/indra/newview/llfloaterpostprocess.cpp | 66 +- linden/indra/newview/llfloaterreporter.cpp | 3 +- linden/indra/newview/llhudeffect.cpp | 2 +- linden/indra/newview/llhudtext.cpp | 2 - linden/indra/newview/llmanip.cpp | 2 +- linden/indra/newview/llmaniptranslate.h | 2 +- linden/indra/newview/llmediactrl.cpp | 3 +- linden/indra/newview/lloverlaybar.cpp | 1 + linden/indra/newview/llpanelvolume.cpp | 117 - linden/indra/newview/llpanelvolume.h | 5 - linden/indra/newview/llpostprocess.cpp | 594 ---- linden/indra/newview/llpostprocess.h | 274 -- linden/indra/newview/llpreview.cpp | 1 - linden/indra/newview/llselectmgr.cpp | 22 +- linden/indra/newview/llselectmgr.h | 2 +- linden/indra/newview/llsky.cpp | 14 - linden/indra/newview/llspatialpartition.cpp | 390 +-- linden/indra/newview/llspatialpartition.h | 62 +- linden/indra/newview/llstartup.cpp | 2 +- linden/indra/newview/llsurface.cpp | 17 +- linden/indra/newview/llsurfacepatch.cpp | 34 +- linden/indra/newview/llsurfacepatch.h | 1 - linden/indra/newview/lltexlayer.cpp | 26 +- linden/indra/newview/lltexlayer.h | 4 +- .../indra/newview/lltextureatlasmanager.cpp | 274 -- linden/indra/newview/lltextureatlasmanager.h | 112 - linden/indra/newview/lltextureview.cpp | 238 +- linden/indra/newview/lltoolpie.h | 1 + linden/indra/newview/llviewercamera.cpp | 4 +- linden/indra/newview/llviewercontrol.cpp | 16 +- linden/indra/newview/llviewerdisplay.cpp | 27 +- linden/indra/newview/llviewerimage.cpp | 367 +-- linden/indra/newview/llviewerimage.h | 31 +- linden/indra/newview/llviewerimagelist.cpp | 50 +- linden/indra/newview/llviewerimagelist.h | 4 +- linden/indra/newview/llviewerjointmesh.cpp | 10 +- linden/indra/newview/llviewermedia.cpp | 4 +- linden/indra/newview/llviewermenu.cpp | 20 +- linden/indra/newview/llviewerobject.cpp | 35 +- linden/indra/newview/llviewerobject.h | 11 +- linden/indra/newview/llviewerobjectlist.cpp | 2 +- linden/indra/newview/llviewerobjectlist.h | 1 + .../indra/newview/llviewerparceloverlay.cpp | 4 +- linden/indra/newview/llviewershadermgr.cpp | 106 +- linden/indra/newview/llviewershadermgr.h | 25 - linden/indra/newview/llviewerstats.h | 2 +- linden/indra/newview/llviewerwindow.cpp | 60 +- linden/indra/newview/llvlcomposition.cpp | 4 - linden/indra/newview/llvoavatar.cpp | 98 +- linden/indra/newview/llvoavatar.h | 10 +- linden/indra/newview/llvoclouds.cpp | 7 +- linden/indra/newview/llvoclouds.h | 2 +- linden/indra/newview/llvograss.cpp | 2 +- linden/indra/newview/llvograss.h | 2 +- linden/indra/newview/llvoground.cpp | 2 +- linden/indra/newview/llvoground.h | 2 +- linden/indra/newview/llvopartgroup.cpp | 20 +- linden/indra/newview/llvopartgroup.h | 2 +- linden/indra/newview/llvosky.cpp | 8 +- linden/indra/newview/llvosky.h | 2 +- linden/indra/newview/llvosurfacepatch.cpp | 18 +- linden/indra/newview/llvosurfacepatch.h | 3 +- linden/indra/newview/llvotextbubble.cpp | 2 +- linden/indra/newview/llvotextbubble.h | 2 +- linden/indra/newview/llvotree.cpp | 6 +- linden/indra/newview/llvotree.h | 2 +- linden/indra/newview/llvotreenew.h | 2 +- linden/indra/newview/llvovolume.cpp | 422 +-- linden/indra/newview/llvovolume.h | 23 +- linden/indra/newview/llvowater.cpp | 6 +- linden/indra/newview/llvowater.h | 2 +- linden/indra/newview/llwaterparammanager.cpp | 3 +- linden/indra/newview/llwlparammanager.cpp | 3 +- linden/indra/newview/llworld.h | 6 +- linden/indra/newview/pipeline.cpp | 2779 +++-------------- linden/indra/newview/pipeline.h | 100 +- .../xui/en-us/floater_hardware_settings.xml | 30 +- .../skins/default/xui/en-us/floater_tools.xml | 44 +- 209 files changed, 2040 insertions(+), 12466 deletions(-) delete mode 100644 linden/indra/llmath/llbbox.cpp delete mode 100644 linden/indra/llmath/llbbox.h delete mode 100644 linden/indra/llmath/llmodularmath.cpp delete mode 100644 linden/indra/llrender/lltextureatlas.cpp delete mode 100644 linden/indra/llrender/lltextureatlas.h delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl delete mode 100644 linden/indra/newview/llpostprocess.cpp delete mode 100644 linden/indra/newview/llpostprocess.h delete mode 100644 linden/indra/newview/lltextureatlasmanager.cpp delete mode 100644 linden/indra/newview/lltextureatlasmanager.h diff --git a/linden/indra/llmath/llbbox.cpp b/linden/indra/llmath/llbbox.cpp deleted file mode 100644 index f0ec010c0..000000000 --- a/linden/indra/llmath/llbbox.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/** - * @file llbbox.cpp - * @brief General purpose bounding box class (Not axis aligned) - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, /linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by /linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and /linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -// self include -#include "llbbox.h" - -// library includes -#include "m4math.h" - -void LLBBox::addPointLocal(const LLVector3& p) -{ - if (mEmpty) - { - mMinLocal = p; - mMaxLocal = p; - mEmpty = FALSE; - } - else - { - mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] ); - mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] ); - mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] ); - mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] ); - mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] ); - mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] ); - } -} - -void LLBBox::addPointAgent( LLVector3 p) -{ - p -= mPosAgent; - p.rotVec( ~mRotation ); - addPointLocal( p ); -} - - -void LLBBox::addBBoxAgent(const LLBBox& b) -{ - if (mEmpty) - { - mPosAgent = b.mPosAgent; - mRotation = b.mRotation; - mMinLocal.clearVec(); - mMaxLocal.clearVec(); - } - LLVector3 vertex[8]; - vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); - vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); - vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); - vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); - vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); - vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); - vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); - vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); - - LLMatrix4 m( b.mRotation ); - m.translate( b.mPosAgent ); - m.translate( -mPosAgent ); - m.rotate( ~mRotation ); - - for( S32 i=0; i<8; i++ ) - { - addPointLocal( vertex[i] * m ); - } -} - - -void LLBBox::expand( F32 delta ) -{ - mMinLocal.mV[VX] -= delta; - mMinLocal.mV[VY] -= delta; - mMinLocal.mV[VZ] -= delta; - mMaxLocal.mV[VX] += delta; - mMaxLocal.mV[VY] += delta; - mMaxLocal.mV[VZ] += delta; -} - -LLVector3 LLBBox::localToAgent(const LLVector3& v) const -{ - LLMatrix4 m( mRotation ); - m.translate( mPosAgent ); - return v * m; -} - -LLVector3 LLBBox::agentToLocal(const LLVector3& v) const -{ - LLMatrix4 m; - m.translate( -mPosAgent ); - m.rotate( ~mRotation ); // inverse rotation - return v * m; -} - -LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const -{ - LLMatrix4 m( mRotation ); - return v * m; -} - -LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const -{ - LLMatrix4 m( ~mRotation ); // inverse rotation - return v * m; -} - -BOOL LLBBox::containsPointLocal(const LLVector3& p) const -{ - if ( (p.mV[VX] < mMinLocal.mV[VX]) - ||(p.mV[VX] > mMaxLocal.mV[VX]) - ||(p.mV[VY] < mMinLocal.mV[VY]) - ||(p.mV[VY] > mMaxLocal.mV[VY]) - ||(p.mV[VZ] < mMinLocal.mV[VZ]) - ||(p.mV[VZ] > mMaxLocal.mV[VZ])) - { - return FALSE; - } - return TRUE; -} - -BOOL LLBBox::containsPointAgent(const LLVector3& p) const -{ - LLVector3 point_local = agentToLocal(p); - return containsPointLocal(point_local); -} - - -/* -LLBBox operator*(const LLBBox &a, const LLMatrix4 &b) -{ - return LLBBox( a.mMin * b, a.mMax * b ); -} -*/ diff --git a/linden/indra/llmath/llbbox.h b/linden/indra/llmath/llbbox.h deleted file mode 100644 index 355928406..000000000 --- a/linden/indra/llmath/llbbox.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file llbbox.h - * @brief General purpose bounding box class - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, /linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by /linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and /linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_BBOX_H -#define LL_BBOX_H - -#include "v3math.h" -#include "llquaternion.h" - -// Note: "local space" for an LLBBox is defined relative to agent space in terms of -// a translation followed by a rotation. There is no scale term since the LLBBox's min and -// max are not necessarily symetrical and define their own extents. - -class LLBBox -{ -public: - LLBBox() {mEmpty = TRUE;} - LLBBox( const LLVector3& pos_agent, - const LLQuaternion& rot, - const LLVector3& min_local, - const LLVector3& max_local ) - : - mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE ) - {} - - // Default copy constructor is OK. - - const LLVector3& getPositionAgent() const { return mPosAgent; } - const LLQuaternion& getRotation() const { return mRotation; } - - const LLVector3& getMinLocal() const { return mMinLocal; } - void setMinLocal( const LLVector3& min ) { mMinLocal = min; } - - const LLVector3& getMaxLocal() const { return mMaxLocal; } - void setMaxLocal( const LLVector3& max ) { mMaxLocal = max; } - - LLVector3 getCenterLocal() const { return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; } - LLVector3 getCenterAgent() const { return localToAgent( getCenterLocal() ); } - - LLVector3 getExtentLocal() const { return mMaxLocal - mMinLocal; } - - BOOL containsPointLocal(const LLVector3& p) const; - BOOL containsPointAgent(const LLVector3& p) const; - - void addPointAgent(LLVector3 p); - void addBBoxAgent(const LLBBox& b); - - void addPointLocal(const LLVector3& p); - void addBBoxLocal(const LLBBox& b) { addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); } - - void expand( F32 delta ); - - LLVector3 localToAgent( const LLVector3& v ) const; - LLVector3 agentToLocal( const LLVector3& v ) const; - - // Changes rotation but not position - LLVector3 localToAgentBasis(const LLVector3& v) const; - LLVector3 agentToLocalBasis(const LLVector3& v) const; - - -// friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b); - -private: - LLVector3 mMinLocal; - LLVector3 mMaxLocal; - LLVector3 mPosAgent; // Position relative to Agent's Region - LLQuaternion mRotation; - BOOL mEmpty; // Nothing has been added to this bbox yet -}; - -//LLBBox operator*(const LLBBox &a, const LLMatrix4 &b); - - -#endif // LL_BBOX_H diff --git a/linden/indra/llmath/llcamera.cpp b/linden/indra/llmath/llcamera.cpp index 9c37fcf61..e6b6797c6 100644 --- a/linden/indra/llmath/llcamera.cpp +++ b/linden/indra/llmath/llcamera.cpp @@ -246,10 +246,6 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) for (U32 i = 0; i < mPlaneCount; i++) { mask = mAgentPlanes[i].mask; - if (mask == 0xff) - { - continue; - } LLPlane p = mAgentPlanes[i].p; LLVector3 n = LLVector3(p); float d = p.mV[3]; @@ -298,10 +294,6 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& r } mask = mAgentPlanes[i].mask; - if (mask == 0xff) - { - continue; - } LLPlane p = mAgentPlanes[i].p; LLVector3 n = LLVector3(p); float d = p.mV[3]; @@ -445,11 +437,6 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) int res = 2; for (int i = 0; i < 6; i++) { - if (mAgentPlanes[i].mask == 0xff) - { - continue; - } - float d = mAgentPlanes[i].p.dist(sphere_center); if (d > radius) @@ -635,17 +622,6 @@ U8 LLCamera::calcPlaneMask(const LLPlane& plane) return mask; } -void LLCamera::ignoreAgentFrustumPlane(S32 idx) -{ - if (idx < 0 || idx > (S32) mPlaneCount) - { - return; - } - - mAgentPlanes[idx].mask = 0xff; - mAgentPlanes[idx].p.clearVec(); -} - void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { diff --git a/linden/indra/llmath/llcamera.h b/linden/indra/llmath/llcamera.h index 8d3ad08ca..85b93dfc9 100644 --- a/linden/indra/llmath/llcamera.h +++ b/linden/indra/llmath/llcamera.h @@ -84,17 +84,6 @@ class LLCamera PLANE_TOP_MASK = (1<<PLANE_TOP), PLANE_ALL_MASK = 0xf }; - - enum - { - AGENT_PLANE_LEFT = 0, - AGENT_PLANE_RIGHT, - AGENT_PLANE_NEAR, - AGENT_PLANE_BOTTOM, - AGENT_PLANE_TOP, - AGENT_PLANE_FAR, - }; - enum { HORIZ_PLANE_LEFT = 0, HORIZ_PLANE_RIGHT = 1, @@ -134,8 +123,7 @@ class LLCamera public: LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane - LLPlane getAgentPlane(U32 idx) { return mAgentPlanes[idx].p; } - + public: LLCamera(); LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); @@ -182,8 +170,6 @@ class LLCamera // Return number of bytes copied. size_t readFrustumFromBuffer(const char *buffer); void calcAgentFrustumPlanes(LLVector3* frust); - void ignoreAgentFrustumPlane(S32 idx); - // Returns 1 if partly in, 2 if fully in. // NOTE: 'center' is in absolute frame. S32 sphereInFrustumOld(const LLVector3 ¢er, const F32 radius) const; diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h index ec1076d84..0de568cbd 100644 --- a/linden/indra/llmath/llmath.h +++ b/linden/indra/llmath/llmath.h @@ -203,7 +203,7 @@ inline S32 llfloor( F32 f ) } return result; #else - return (S32)floorf(f); + return (S32)floor(f); #endif } diff --git a/linden/indra/llmath/llmodularmath.cpp b/linden/indra/llmath/llmodularmath.cpp deleted file mode 100644 index f0afeb7bd..000000000 --- a/linden/indra/llmath/llmodularmath.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file llmodularmath.cpp - * @brief LLModularMath class implementation - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2010, /linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by /linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and /linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes. -#include "llmodularmath.h" diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index a1d891a26..b0b8a94e4 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp @@ -2208,10 +2208,16 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, S32 requested_sizeS = 0; S32 requested_sizeT = 0; - sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, mDetail, requested_sizeS, requested_sizeT); + // create oblong sculpties with high LOD always + F32 sculpt_detail = mDetail; + if (sculpt_width != sculpt_height && sculpt_detail < 4.0) + { + sculpt_detail = 4.0; + } + sculpt_calc_mesh_resolution(sculpt_width, sculpt_height, sculpt_type, sculpt_detail, requested_sizeS, requested_sizeT); - mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); - mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); + mPathp->generate(mParams.getPathParams(), sculpt_detail, 0, TRUE, requested_sizeS); + mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), sculpt_detail, 0, TRUE, requested_sizeT); S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got @@ -4268,7 +4274,7 @@ LLFaceID LLVolume::generateFaceMask() } break; default: - llerrs << "Unknown profile!" << llendl; + llerrs << "Unknown profile!" << llendl break; } diff --git a/linden/indra/llrender/CMakeLists.txt b/linden/indra/llrender/CMakeLists.txt index 3ba841e53..0bdb55f9d 100644 --- a/linden/indra/llrender/CMakeLists.txt +++ b/linden/indra/llrender/CMakeLists.txt @@ -32,9 +32,9 @@ set(llrender_SOURCE_FILES llgldbg.cpp llglslshader.cpp llimagegl.cpp + llpostprocess.cpp llrendersphere.cpp llshadermgr.cpp - lltextureatlas.cpp llvertexbuffer.cpp ) @@ -53,10 +53,10 @@ set(llrender_HEADER_FILES llglstates.h llgltypes.h llimagegl.h + llpostprocess.h llrender.h llrendersphere.h llshadermgr.h - lltextureatlas.h llvertexbuffer.h ) @@ -81,7 +81,6 @@ if (SERVER AND NOT WINDOWS AND NOT DARWIN) ${llrender_SOURCE_FILES} ${server_SOURCE_FILES} ) - add_dependencies(llrenderheadless prepare) else (SERVER AND NOT WINDOWS AND NOT DARWIN) list(APPEND llrender_SOURCE_FILES llgl.cpp diff --git a/linden/indra/llrender/llcubemap.cpp b/linden/indra/llrender/llcubemap.cpp index e0923e41d..a5c677dd4 100644 --- a/linden/indra/llrender/llcubemap.cpp +++ b/linden/indra/llrender/llcubemap.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewergpl$ * - * Copyright (c) 2002-2010, Linden Research, Inc. + * Copyright (c) 2002-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -63,12 +63,6 @@ LLCubeMap::LLCubeMap() mTextureCoordStage(0), mMatrixStage(0) { - mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; - mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; - mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; - mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; - mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; - mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; } LLCubeMap::~LLCubeMap() @@ -81,6 +75,13 @@ void LLCubeMap::initGL() if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) { + mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; + mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; + mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; + mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; + mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; + // Not initialized, do stuff. if (mImages[0].isNull()) { @@ -93,7 +94,7 @@ void LLCubeMap::initGL() mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE)); mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP); mRawImages[i] = new LLImageRaw(64, 64, 4); - mImages[i]->createGLTexture(0, mRawImages[i], texname); + mImages[i]->createGLTexture(0, mRawImages[i], texname, TRUE); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname); mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/linden/indra/llrender/llfont.cpp b/linden/indra/llrender/llfont.cpp index 946f52f2e..5ee39297f 100644 --- a/linden/indra/llrender/llfont.cpp +++ b/linden/indra/llrender/llfont.cpp @@ -81,7 +81,7 @@ LLFontManager::LLFontManager() if (error) { // Clean up freetype libs. - llwarns << "Freetype initialization failure!" << llendl; + llerrs << "Freetype initialization failure!" << llendl; FT_Done_FreeType(gFTLibrary); } } diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp index 9d1f1d453..5d3d6a7fd 100644 --- a/linden/indra/llrender/llfontgl.cpp +++ b/linden/indra/llrender/llfontgl.cpp @@ -121,7 +121,7 @@ LLFontGL::LLFontGL() LLFontGL::LLFontGL(const LLFontGL &source) { - llwarns << "Not implemented!" << llendl; + llerrs << "Not implemented!" << llendl; } LLFontGL::~LLFontGL() @@ -278,7 +278,7 @@ void LLFontGL::destroyGL() LLFontGL &LLFontGL::operator=(const LLFontGL &source) { - llwarns << "Not implemented" << llendl; + llerrs << "Not implemented" << llendl; return *this; } @@ -584,7 +584,7 @@ S32 LLFontGL::render(const LLWString &wstr, const LLFontGlyphInfo* fgi= getGlyphInfo(wch); if (!fgi) { - llwarns << "Missing Glyph Info" << llendl; + llerrs << "Missing Glyph Info" << llendl; break; } // Per-glyph bitmap texture. diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp index d73f7b687..2e9b2bdeb 100644 --- a/linden/indra/llrender/llgl.cpp +++ b/linden/indra/llrender/llgl.cpp @@ -59,13 +59,11 @@ BOOL gDebugGL = FALSE; BOOL gClothRipple = FALSE; BOOL gNoRender = FALSE; -BOOL gGLActive = FALSE; LLMatrix4 gGLObliqueProjectionInverse; #define LL_GL_NAME_POOLING 0 LLGLNamePool::pool_list_t LLGLNamePool::sInstances; -std::list<LLGLUpdate*> LLGLUpdate::sGLQ; #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS // ATI prototypes @@ -1011,7 +1009,7 @@ void assert_glerror() if (quit) { - llwarns << "One or more unhandled GL errors." << llendl; + llerrs << "One or more unhandled GL errors." << llendl; } } @@ -1705,11 +1703,11 @@ void LLGLNamePool::release(GLuint name) } else { - llwarns << "Attempted to release a pooled name that is not in use!" << llendl; + llerrs << "Attempted to release a pooled name that is not in use!" << llendl; } } } - llwarns << "Attempted to release a non pooled name!" << llendl; + llerrs << "Attempted to release a non pooled name!" << llendl; #else releaseName(name); #endif diff --git a/linden/indra/llrender/llgl.h b/linden/indra/llrender/llgl.h index 90642b3f8..cc7ebffd2 100644 --- a/linden/indra/llrender/llgl.h +++ b/linden/indra/llrender/llgl.h @@ -359,35 +359,6 @@ class LLGLNamePool virtual void releaseName(GLuint name) = 0; }; -/* - Interface for objects that need periodic GL updates applied to them. - Used to synchronize GL updates with GL thread. -*/ -class LLGLUpdate -{ -public: - - static std::list<LLGLUpdate*> sGLQ; - - BOOL mInQ; - LLGLUpdate() - : mInQ(FALSE) - { - } - virtual ~LLGLUpdate() - { - if (mInQ) - { - std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this); - if (iter != sGLQ.end()) - { - sGLQ.erase(iter); - } - } - } - virtual void updateGL() = 0; -}; - extern LLMatrix4 gGLObliqueProjectionInverse; #include "llglstates.h" @@ -406,6 +377,4 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor extern BOOL gClothRipple; extern BOOL gNoRender; -extern BOOL gGLActive; - #endif // LL_LLGL_H diff --git a/linden/indra/llrender/llglslshader.cpp b/linden/indra/llrender/llglslshader.cpp index 18974a7e0..08d654805 100644 --- a/linden/indra/llrender/llglslshader.cpp +++ b/linden/indra/llrender/llglslshader.cpp @@ -408,7 +408,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode) { if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) { - llwarns << "Texture channel " << index << " texture type corrupted." << llendl; + llerrs << "Texture channel " << index << " texture type corrupted." << llendl; } gGL.getTexUnit(index)->disable(); } diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp index 1bddd49aa..7cd4dd7f2 100644 --- a/linden/indra/llrender/llimagegl.cpp +++ b/linden/indra/llrender/llimagegl.cpp @@ -43,8 +43,6 @@ #include "llmath.h" #include "llgl.h" #include "llrender.h" -#include "lltextureatlas.h" - //---------------------------------------------------------------------------- const F32 MIN_TEXTURE_LIFETIME = 10.f; @@ -58,17 +56,19 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0; S32 LLImageGL::sBoundTextureMemoryInBytes = 0; S32 LLImageGL::sCurBoundTextureMemory = 0; S32 LLImageGL::sCount = 0; -std::list<U32> LLImageGL::sDeadTextureList; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; F32 LLImageGL::sLastFrameTime = 0.f; -BOOL LLImageGL::sUseTextureAtlas = FALSE ; // render-pipeline KL +BOOL LLImageGL::sAllowReadBackRaw = FALSE ; std::set<LLImageGL*> LLImageGL::sImageList; -#if !LL_RELEASE_FOR_DOWNLOAD +//**************************************************************************************************** +//The below for texture auditing use only +//**************************************************************************************************** //----------------------- //debug use +BOOL gAuditTexture = FALSE ; #define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048 std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ; std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ; @@ -76,8 +76,15 @@ std::vector<S32> LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ; S32 LLImageGL::sCurTexSizeBar = -1 ; S32 LLImageGL::sCurTexPickSize = -1 ; LLPointer<LLImageGL> LLImageGL::sDefaultTexturep = NULL; +S32 LLImageGL::sMaxCatagories = 1 ; + +std::vector<S32> LLImageGL::sTextureMemByCategory; +std::vector<S32> LLImageGL::sTextureMemByCategoryBound ; +std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ; //------------------------ -#endif +//**************************************************************************************************** +//End for texture auditing use only +//**************************************************************************************************** //************************************************************************************** //below are functions for debug use @@ -103,12 +110,9 @@ void LLImageGL::checkTexSize() const { GLint texname; glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname); - BOOL error = FALSE; if (texname != mTexName) { - - llwarns << "Invalid texture bound!" << llendl; - + llerrs << "Invalid texture bound!" << llendl; } stop_glerror() ; LLGLint x = 0, y = 0 ; @@ -121,15 +125,7 @@ void LLImageGL::checkTexSize() const } if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel)) { - error = TRUE; - - llwarns << "wrong texture size and discard level!" << llendl; - - } - - if (error) - { - llwarns << "LLImageGL::checkTexSize failed." << llendl; + llerrs << "wrong texture size and discard level!" << llendl ; } } } @@ -137,6 +133,20 @@ void LLImageGL::checkTexSize() const //************************************************************************************** //---------------------------------------------------------------------------- +//static +void LLImageGL::initClass(S32 num_catagories) +{ + sMaxCatagories = num_catagories ; + + sTextureMemByCategory.resize(sMaxCatagories); + sTextureMemByCategoryBound.resize(sMaxCatagories) ; + sTextureCurMemByCategoryBound.resize(sMaxCatagories) ; +} + +//static +void LLImageGL::cleanupClass() +{ +} //static S32 LLImageGL::dataFormatBits(S32 dataformat) @@ -155,7 +165,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) case GL_RGBA: return 32; case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac default: - llwarns << "LLImageGL::Unknown format: " << dataformat << llendl; + llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; return 0; } } @@ -190,7 +200,7 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) case GL_RGBA: return 4; case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac default: - llwarns << "LLImageGL::Unknown format: " << dataformat << llendl; + llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; return 0; } } @@ -204,25 +214,43 @@ void LLImageGL::updateStats(F32 current_time) sBoundTextureMemoryInBytes = sCurBoundTextureMemory; sCurBoundTextureMemory = 0; -#if !LL_RELEASE_FOR_DOWNLOAD - for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++) + if(gAuditTexture) { - sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ; - sTextureCurBoundCounter[i] = 0 ; + for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++) + { + sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ; + sTextureCurBoundCounter[i] = 0 ; + } + for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++) + { + sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ; + sTextureCurMemByCategoryBound[i] = 0 ; + } } -#endif } //static -//#if !LL_RELEASE_FOR_DOWNLOAD -//S32 LLImageGL::updateBoundTexMem(const S32 delta, const S32 size) -//{ -// sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ; -//#else -S32 LLImageGL::updateBoundTexMem(const S32 delta) -{ -//#endif - LLImageGL::sCurBoundTextureMemory += delta; +S32 LLImageGL::updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) +{ + if(gAuditTexture) + { + sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ; + sTextureCurMemByCategoryBound[category] += delta ; + } + + LLImageGL::sCurBoundTextureMemory += delta ; + return LLImageGL::sCurBoundTextureMemory; +} + +S32 LLImageGL::updateBoundTexMem()const +{ + if(gAuditTexture) + { + sTextureCurBoundCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ; + sTextureCurMemByCategoryBound[mCategory] += mTextureMemory ; + } + + LLImageGL::sCurBoundTextureMemory += mTextureMemory ; return LLImageGL::sCurBoundTextureMemory; } @@ -236,6 +264,7 @@ void LLImageGL::destroyGL(BOOL save_state) gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } + sAllowReadBackRaw = true ; for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); iter != sImageList.end(); iter++) { @@ -255,7 +284,7 @@ void LLImageGL::destroyGL(BOOL save_state) stop_glerror(); } } -// sAllowReadBackRaw = false ; + sAllowReadBackRaw = false ; } //static @@ -267,13 +296,13 @@ void LLImageGL::restoreGL() LLImageGL* glimage = *iter; if(glimage->getTexName()) { - llwarns << "tex name is not 0." << llendl ; + llerrs << "tex name is not 0." << llendl ; } if (glimage->mSaveData.notNull()) { if (glimage->getComponents() && glimage->mSaveData->getComponents()) { - glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData); + glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory()); stop_glerror(); } glimage->mSaveData = NULL; // deletes data @@ -355,7 +384,7 @@ void LLImageGL::init(BOOL usemipmaps) mTextureState = NO_DELETE ; mTextureMemory = 0; mLastBindTime = 0.f; - + mTarget = GL_TEXTURE_2D; mBindTarget = LLTexUnit::TT_TEXTURE; mUseMipMaps = usemipmaps; @@ -382,12 +411,9 @@ void LLImageGL::init(BOOL usemipmaps) mHasExplicitFormat = FALSE; mGLTextureCreated = FALSE ; + mIsMask = FALSE; -// mCategory = -1 ; - mCanAddToAtlas = TRUE ; - mDiscardLevelInAtlas = -1 ; - mTexelsInAtlas = 0 ; - mTexelsInGLTexture = 0 ; + mCategory = -1 ; } void LLImageGL::cleanup() @@ -429,7 +455,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents) // Check if dimensions are a power of two! if (!checkSize(width,height)) { - llwarns << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; + llerrs << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; } if (mTexName) @@ -487,6 +513,10 @@ void LLImageGL::dump() } //---------------------------------------------------------------------------- +void LLImageGL::forceUpdateBindStats(void) const +{ + mLastBindTime = sLastFrameTime; +} void LLImageGL::updateBindStats(void) const { @@ -500,12 +530,8 @@ void LLImageGL::updateBindStats(void) const { // we haven't accounted for this texture yet this frame sUniqueCount++; - -//#if !LL_RELEASE_FOR_DOWNLOAD -// updateBoundTexMem(mTextureMemory, getWidth(mCurrentDiscardLevel) * getHeight(mCurrentDiscardLevel)) ; -//#else - updateBoundTexMem(mTextureMemory); -//#endif + + updateBoundTexMem(); mLastBindTime = sLastFrameTime; } } @@ -518,7 +544,7 @@ bool LLImageGL::bindError(const S32 stage) const } //virtual -bool LLImageGL::bindDefaultImage(const S32 stage) const +bool LLImageGL::bindDefaultImage(const S32 stage) { return false; } @@ -557,7 +583,6 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { // LLFastTimer t1(LLFastTimer::FTM_TEMP1); - llpushcallstacks ; bool is_compressed = false; if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) { @@ -565,7 +590,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } // LLFastTimer t2(LLFastTimer::FTM_TEMP2); - llverify(gGL.getTexUnit(0)->bind(this, false, true)); + gGL.getTexUnit(0)->bind(this); if (mUseMipMaps) { @@ -728,7 +753,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } else { - llwarns << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; + llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; } mHasMipMaps = true; } @@ -770,63 +795,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } stop_glerror(); mGLTextureCreated = true; - llpushcallstacks ; -} - -BOOL LLImageGL::canAddToAtlas() -{ - return sUseTextureAtlas && mCanAddToAtlas ; -} - -BOOL LLImageGL::addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) -{ - if(!atlasp) - { - return FALSE ; - } - - preAddToAtlas(raw_image->getWidth()) ; - LLGLuint tex_name = atlasp->insertSubTexture(raw_image, slot_col, slot_row); - postAddToAtlas() ; - - if(tex_name > 0) //successfully added to atlas - { - //gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); - //gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); - gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); - return TRUE ; - } - - return FALSE ; -} - -void LLImageGL::preAddToAtlas(S32 data_width) -{ - glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width); - stop_glerror(); - - if(mFormatSwapBytes) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); - stop_glerror(); - } } -void LLImageGL::postAddToAtlas() +BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) { - if(mFormatSwapBytes) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); - stop_glerror(); - } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - stop_glerror(); -} - -BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) -{ - llpushcallstacks ; if (!width || !height) { return TRUE; @@ -842,7 +814,8 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 return FALSE; } - if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) + // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture. + if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) { setImage(datap, FALSE); } @@ -851,7 +824,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 if (mUseMipMaps) { dump(); - llwarns << "setSubImage called with mipmapped image (not supported)" << llendl; + llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; } llassert_always(mCurrentDiscardLevel == 0); llassert_always(x_pos >= 0 && y_pos >= 0); @@ -860,7 +833,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 (y_pos + height) > getHeight()) { dump(); - llwarns << "Subimage not wholly in target image!" + llerrs << "Subimage not wholly in target image!" << " x_pos " << x_pos << " y_pos " << y_pos << " width " << width @@ -874,7 +847,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 (y_pos + height) > data_height) { dump(); - llwarns << "Subimage not wholly in source image!" + llerrs << "Subimage not wholly in source image!" << " x_pos " << x_pos << " y_pos " << y_pos << " width " << width @@ -897,7 +870,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 datap += (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName); - if (!res) llwarns << "LLImageGL::setSubImage(): bindTexture failed" << llendl; + if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; stop_glerror(); glTexSubImage2D(mTarget, 0, x_pos, y_pos, @@ -915,13 +888,12 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 stop_glerror(); mGLTextureCreated = true; } - llpushcallstacks ; return TRUE; } -BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) +BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) { - return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height); + return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update); } // Copy sub image from frame buffer @@ -929,6 +901,7 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ { if (gGL.getTexUnit(0)->bind(this, false, true)) { + //checkTexSize() ; glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); mGLTextureCreated = true; stop_glerror(); @@ -949,17 +922,13 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures) // static void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) { - for (S32 i = 0; i < numTextures; i++) - { - sDeadTextureList.push_back(textures[i]); - } + glDeleteTextures(numTextures, (GLuint*)textures); } // static void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels) { glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); - stop_glerror(); } //create an empty GL texture: just create a texture name @@ -986,26 +955,21 @@ BOOL LLImageGL::createGLTexture() stop_glerror(); if (!mTexName) { - llwarns << "LLImageGL::createGLTexture failed to make an empty texture" << llendl; + llerrs << "LLImageGL::createGLTexture failed to make an empty texture" << llendl; } return TRUE ; } -BOOL LLImageGL::createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) +BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category) { - if(!sUseTextureAtlas) - { - return FALSE ; - } - if (gGLManager.mIsDisabled) { llwarns << "Trying to create a texture while GL is disabled!" << llendl; return FALSE; } - // mGLTextureCreated = false ; // KL not in SD + mGLTextureCreated = false ; llassert(gGLManager.mInited); stop_glerror(); @@ -1017,8 +981,10 @@ BOOL LLImageGL::createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imag discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); // Actual image width/height = raw image width/height * 2^discard_level - S32 w = imageraw->getWidth() << discard_level; - S32 h = imageraw->getHeight() << discard_level; + S32 raw_w = imageraw->getWidth() ; + S32 raw_h = imageraw->getHeight() ; + S32 w = raw_w << discard_level; + S32 h = raw_h << discard_level; // setSize may call destroyGLTexture if the size does not match setSize(w, h, imageraw->getComponents()); @@ -1050,87 +1016,27 @@ BOOL LLImageGL::createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imag mFormatType = GL_UNSIGNED_BYTE; break; default: - llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl; + LL_DEBUGS("Openjpeg") << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL; + to_create = false; + break; } } - if(addToAtlas(imageraw, atlasp, slot_col, slot_row)) + if(!to_create) //not create a gl texture { - // destroyGLTexture(); + destroyGLTexture(); mCurrentDiscardLevel = discard_level; - mDiscardLevelInAtlas = discard_level; - mTexelsInAtlas = imageraw->getWidth() * imageraw->getHeight() ; mLastBindTime = sLastFrameTime; - mGLTextureCreated = false ; return TRUE ; } - return FALSE ; -} - -BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/) -{ - if (gGLManager.mIsDisabled) - { - llwarns << "Trying to create a texture while GL is disabled!" << llendl; - return FALSE; - } - - mGLTextureCreated = false ; - llassert(gGLManager.mInited); - stop_glerror(); - - if (discard_level < 0) - { - llassert(mCurrentDiscardLevel >= 0); - discard_level = mCurrentDiscardLevel; - } - discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - - // Actual image width/height = raw image width/height * 2^discard_level - S32 w = imageraw->getWidth() << discard_level; - S32 h = imageraw->getHeight() << discard_level; - - // setSize may call destroyGLTexture if the size does not match - setSize(w, h, imageraw->getComponents()); - - if( !mHasExplicitFormat ) - { - switch (mComponents) - { - case 1: - // Use luminance alpha (for fonts) - mFormatInternal = GL_LUMINANCE8; - mFormatPrimary = GL_LUMINANCE; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 2: - // Use luminance alpha (for fonts) - mFormatInternal = GL_LUMINANCE8_ALPHA8; - mFormatPrimary = GL_LUMINANCE_ALPHA; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 3: - mFormatInternal = GL_RGB8; - mFormatPrimary = GL_RGB; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 4: - mFormatInternal = GL_RGBA8; - mFormatPrimary = GL_RGBA; - mFormatType = GL_UNSIGNED_BYTE; - break; - default: - llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl; - } - } + mCategory = category ; const U8* rawdata = imageraw->getData(); return createGLTexture(discard_level, rawdata, FALSE, usename); } BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) { - llpushcallstacks ; llassert(data_in); if (discard_level < 0) @@ -1167,7 +1073,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ } if (!mTexName) { - llwarns << "LLImageGL::createGLTexture failed to make texture" << llendl; + llerrs << "LLImageGL::createGLTexture failed to make texture" << llendl; } if (mUseMipMaps) @@ -1198,30 +1104,30 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ if (old_name != 0) { sGlobalTextureMemoryInBytes -= mTextureMemory; -#if !LL_RELEASE_FOR_DOWNLOAD - decTextureCounter(mTextureMemory / mComponents) ; -#endif + + if(gAuditTexture) + { + decTextureCounter() ; + } LLImageGL::deleteTextures(1, &old_name); + stop_glerror(); } mTextureMemory = getMipBytes(discard_level); sGlobalTextureMemoryInBytes += mTextureMemory; - mTexelsInGLTexture = getWidth() * getHeight() ; - -#if !LL_RELEASE_FOR_DOWNLOAD - incTextureCounter(mTextureMemory / mComponents) ; -#endif setActive() ; + if(gAuditTexture) + { + incTextureCounter() ; + } // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; - - llpushcallstacks ; return TRUE; } - +#if 0 BOOL LLImageGL::setDiscardLevel(S32 discard_level) { llassert(discard_level >= 0); @@ -1243,7 +1149,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) { // larger image dump(); - llwarns << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl; + llerrs << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl; return FALSE; } else if (mUseMipMaps) @@ -1268,30 +1174,19 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) { #if !LL_LINUX && !LL_SOLARIS // *FIX: This should not be skipped for the linux client. - llwarns << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; + llerrs << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; #endif return FALSE; } } - -BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) -{ - assert_glerror(); - S32 gl_discard = discard_level - mCurrentDiscardLevel; - LLGLint glwidth = 0; - glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth); - LLGLint glheight = 0; - glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_HEIGHT, (GLint*)&glheight); - LLGLint glcomponents = 0 ; - glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&glcomponents); - assert_glerror(); - - return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ; -} +#endif BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) { - llpushcallstacks ; + // VWR-13505 : Merov : Allow gl texture read back so save texture works again (temporary) + //llassert_always(sAllowReadBackRaw) ; + //llerrs << "should not call this function!" << llendl ; + if (discard_level < 0) { discard_level = mCurrentDiscardLevel; @@ -1396,48 +1291,41 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre return FALSE ; } //----------------------------------------------------------------------------------------------- - llpushcallstacks ; + return TRUE ; } -void LLImageGL::deleteDeadTextures() +void LLImageGL::destroyGLTexture() { - while (!sDeadTextureList.empty()) + if (mTexName != 0) { - GLuint tex = sDeadTextureList.front(); - sDeadTextureList.pop_front(); + stop_glerror(); + for (int i = 0; i < gGLManager.mNumTextureUnits; i++) { - if (sCurrentBoundTextures[i] == tex) + if (sCurrentBoundTextures[i] == mTexName) { gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); } } - - glDeleteTextures(1, &tex); - stop_glerror(); - } -} - -void LLImageGL::destroyGLTexture() -{ - if (mTexName != 0) - { + if(mTextureMemory) { -#if !LL_RELEASE_FOR_DOWNLOAD - decTextureCounter(mTextureMemory / mComponents) ; -#endif + if(gAuditTexture) + { + decTextureCounter() ; + } sGlobalTextureMemoryInBytes -= mTextureMemory; mTextureMemory = 0; } - + LLImageGL::deleteTextures(1, &mTexName); - mTextureState = DELETED ; + mTextureState = DELETED ; mTexName = 0; mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mGLTextureCreated = FALSE ; + stop_glerror(); } } @@ -1466,12 +1354,12 @@ void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option) mFilterOption = option; } - if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) + if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) { gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option); mTexOptionsDirty = false; - stop_glerror(); } + stop_glerror(); } BOOL LLImageGL::getIsResident(BOOL test_now) @@ -1547,6 +1435,11 @@ S32 LLImageGL::getMipBytes(S32 discard_level) const return res; } +BOOL LLImageGL::isJustBound() const +{ + return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f); +} + BOOL LLImageGL::getBoundRecently() const { return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME); @@ -1708,7 +1601,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) U32 pick_offset = pick_bit%8; if (pick_idx >= mPickMaskSize) { - llwarns << "WTF?" << llendl; + llerrs << "WTF?" << llendl; } mPickMask[pick_idx] |= 1 << pick_offset; @@ -1734,7 +1627,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) if (u < 0.f || u > 1.f || v < 0.f || v > 1.f) { - llwarns << "WTF?" << llendl; // WTF really useful info NOT + llerrs << "WTF?" << llendl; } S32 x = (S32)(u * width); @@ -1757,8 +1650,24 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) return res; } -//---------------------------------------------------------------------------- -#if !LL_RELEASE_FOR_DOWNLOAD +void LLImageGL::setCategory(S32 category) +{ + if(!gAuditTexture) + { + return ; + } + if(mCategory != category) + { + if(mCategory > -1) + { + sTextureMemByCategory[mCategory] -= mTextureMemory ; + } + sTextureMemByCategory[category] += mTextureMemory ; + + mCategory = category; + } +} + //for debug use //val is a "power of two" number S32 LLImageGL::getTextureCounterIndex(U32 val) @@ -1782,18 +1691,38 @@ S32 LLImageGL::getTextureCounterIndex(U32 val) return ret ; } } -void LLImageGL::incTextureCounter(U32 val) +void LLImageGL::incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) { sTextureLoadedCounter[getTextureCounterIndex(val)]++ ; + sTextureMemByCategory[category] += (S32)val * ncomponents ; } -void LLImageGL::decTextureCounter(U32 val) +void LLImageGL::decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) { sTextureLoadedCounter[getTextureCounterIndex(val)]-- ; + sTextureMemByCategory[category] += (S32)val * ncomponents ; +} +void LLImageGL::incTextureCounter() +{ + sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ; + sTextureMemByCategory[mCategory] += mTextureMemory ; +} +void LLImageGL::decTextureCounter() +{ + sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]-- ; + sTextureMemByCategory[mCategory] -= mTextureMemory ; } -void LLImageGL::setCurTexSizebar(S32 index) +void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size) { sCurTexSizeBar = index ; - sCurTexPickSize = (1 << index) ; + + if(set_pick_size) + { + sCurTexPickSize = (1 << index) ; + } + else + { + sCurTexPickSize = -1 ; + } } void LLImageGL::resetCurTexSizebar() { @@ -1801,7 +1730,9 @@ void LLImageGL::resetCurTexSizebar() sCurTexPickSize = -1 ; } //---------------------------------------------------------------------------- -#endif + +//---------------------------------------------------------------------------- + // Manual Mip Generation /* diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h index 56f79ffb1..c7114c36a 100644 --- a/linden/indra/llrender/llimagegl.h +++ b/linden/indra/llrender/llimagegl.h @@ -45,23 +45,18 @@ #define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) #define MEGA_BYTES_TO_BYTES(x) ((x) << 20) -class LLTextureAtlas ; //============================================================================ - class LLImageGL : public LLRefCount { friend class LLTexUnit; public: - static std::list<U32> sDeadTextureList; - - static void deleteDeadTextures(); - // Size calculation static S32 dataFormatBits(S32 dataformat); static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); void updateBindStats(void) const; + void forceUpdateBindStats(void) const; // needs to be called every frame static void updateStats(F32 current_time); @@ -70,12 +65,10 @@ class LLImageGL : public LLRefCount static void destroyGL(BOOL save_state = TRUE); static void restoreGL(); - // Sometimes called externally for textures not using LLImageGL (should go away...) -//#if !LL_RELEASE_FOR_DOWNLOAD -// static S32 updateBoundTexMem(const S32 delta, const S32 size) ; -//#else - static S32 updateBoundTexMem(const S32 delta); -//#endif + // Sometimes called externally for textures not using LLImageGL (should go away...) + static S32 updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) ; + S32 updateBoundTexMem()const; + static bool checkSize(S32 width, S32 height); // Not currently necessary for LLImageGL, but required in some derived classes, @@ -97,7 +90,7 @@ class LLImageGL : public LLRefCount public: virtual void dump(); // debugging info to llinfos virtual bool bindError(const S32 stage = 0) const; - virtual bool bindDefaultImage(const S32 stage = 0) const; + virtual bool bindDefaultImage(const S32 stage = 0) ; virtual void forceImmediateUpdate() ; void setSize(S32 width, S32 height, S32 ncomponents); @@ -109,14 +102,15 @@ class LLImageGL : public LLRefCount static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels); BOOL createGLTexture() ; - BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0); + BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, + S32 category = sMaxCatagories - 1); BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0); void setImage(const LLImageRaw* imageraw); void setImage(const U8* data_in, BOOL data_hasmips = FALSE); - BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height); - BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); - BOOL setDiscardLevel(S32 discard_level); + // Read back a raw image for this discard level, if it exists BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); void destroyGLTexture(); @@ -136,7 +130,7 @@ class LLImageGL : public LLRefCount S32 getBytes(S32 discard_level = -1) const; S32 getMipBytes(S32 discard_level = -1) const; BOOL getBoundRecently() const; - //BOOL isJustBound() const; + BOOL isJustBound() const; LLGLenum getPrimaryFormat() const { return mFormatPrimary; } BOOL getHasGLTexture() const { return mTexName != 0; } @@ -157,8 +151,6 @@ class LLImageGL : public LLRefCount BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } BOOL getDontDiscard() const { return mDontDiscard; } - BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; - void updatePickMask(S32 width, S32 height, const U8* data_in); BOOL getMask(const LLVector2 &tc); @@ -184,20 +176,8 @@ class LLImageGL : public LLRefCount void setActive() ; void forceActive() ; void setNoDelete() ; - - BOOL canAddToAtlas() ; - BOOL createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row); - BOOL addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) ; - - LLGLenum getTexTarget()const { return mTarget ;} - S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;} - U32 getTexelsInAtlas()const { return mTexelsInAtlas ;} - U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;} -private: - void preAddToAtlas(S32 data_width) ; - void postAddToAtlas() ; - + void setTextureSize(S32 size) {mTextureMemory = size;} protected: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors @@ -206,7 +186,7 @@ class LLImageGL : public LLRefCount // Various GL/Rendering options S32 mTextureMemory; mutable F32 mLastBindTime; // last time this was bound, by discard level - + private: LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel @@ -222,15 +202,8 @@ class LLImageGL : public LLRefCount U16 mWidth; U16 mHeight; S8 mCurrentDiscardLevel; - - S8 mDiscardLevelInAtlas; - U32 mTexelsInAtlas ; - U32 mTexelsInGLTexture; - + protected: - - BOOL mCanAddToAtlas ; - LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps) LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps) bool mHasMipMaps; @@ -268,18 +241,42 @@ class LLImageGL : public LLRefCount static S32 sCount; static F32 sLastFrameTime; - + static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID // Global memory statistics static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem - static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame + static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame 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 BOOL sUseTextureAtlas ; -#if !LL_RELEASE_FOR_DOWNLOAD +#if DEBUG_MISS + BOOL mMissed; // Missed on last bind? + BOOL getMissed() const { return mMissed; }; +#else + BOOL getMissed() const { return FALSE; }; +#endif + +public: + static void initClass(S32 num_catagories) ; + static void cleanupClass() ; +private: + static S32 sMaxCatagories ; + + //the flag to allow to call readBackRaw(...). + //can be removed if we do not use that function at all. + static BOOL sAllowReadBackRaw ; +// +//**************************************************************************************************** +//The below for texture auditing use only +//**************************************************************************************************** +private: + S32 mCategory ; +public: + void setCategory(S32 category) ; + S32 getCategory()const {return mCategory ;} + //for debug use: show texture size distribution //---------------------------------------- static LLPointer<LLImageGL> sDefaultTexturep; //default texture to replace normal textures @@ -290,19 +287,27 @@ class LLImageGL : public LLRefCount static S32 sCurTexPickSize ; static S32 getTextureCounterIndex(U32 val) ; - static void incTextureCounter(U32 val) ; - static void decTextureCounter(U32 val) ; - static void setCurTexSizebar(S32 index) ; + static void incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; + static void decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; + static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ; static void resetCurTexSizebar(); + + void incTextureCounter() ; + void decTextureCounter() ; //---------------------------------------- -#endif -#if DEBUG_MISS - BOOL mMissed; // Missed on last bind? - BOOL getMissed() const { return mMissed; }; -#else - BOOL getMissed() const { return FALSE; }; -#endif + //for debug use: show texture category distribution + //---------------------------------------- + + static std::vector<S32> sTextureMemByCategory; + static std::vector<S32> sTextureMemByCategoryBound ; + static std::vector<S32> sTextureCurMemByCategoryBound ; + //---------------------------------------- +//**************************************************************************************************** +//End of definitions for texture auditing use only +//**************************************************************************************************** + }; +extern BOOL gAuditTexture; #endif // LL_LLIMAGEGL_H diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp index 07ba9f14c..b1fe15357 100644 --- a/linden/indra/llrender/llrender.cpp +++ b/linden/indra/llrender/llrender.cpp @@ -47,7 +47,7 @@ F64 gGLLastModelView[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; -static const U32 LL_NUM_TEXTURE_LAYERS = 16; // KL was 8 ( keep a track on this ) 16 in render-pipeline +static const U32 LL_NUM_TEXTURE_LAYERS = 8; static GLenum sGLTextureType[] = { @@ -192,25 +192,24 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) if (!texture->getTexName()) //if texture does not exist { - //if deleted, will re-generate it immediately - texture->forceImmediateUpdate() ; + if (texture->isDeleted()) + { + // This will re-generate the texture immediately. + texture->forceImmediateUpdate() ; + } + texture->forceUpdateBindStats() ; return texture->bindDefaultImage(mIndex); } -#if !LL_RELEASE_FOR_DOWNLOAD - if(for_rendering) + if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0) { - int w = texture->getWidth(texture->getDiscardLevel()) ; - int h = texture->getHeight(texture->getDiscardLevel()) ; - - if(w * h == LLImageGL::sCurTexPickSize) + if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize) { texture->updateBindStats(); return bind(LLImageGL::sDefaultTexturep.get()); } } -#endif if ((mCurrTexture != texture->getTexName()) || forceBind) { @@ -228,6 +227,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) setTextureFilteringOption(texture->mFilterOption); } } + return true; } @@ -280,11 +280,6 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) if (bindDepth) { - if (renderTarget->hasStencil()) - { - llwarns << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << llendl; - } - bindManual(renderTarget->getUsage(), renderTarget->getDepth()); } else @@ -298,18 +293,15 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { - if (mIndex < 0) return false; - - if(mCurrTexture != texture) - { - gGL.flush(); + if (mIndex < 0 || mCurrTexture == texture) return false; + + gGL.flush(); - activate(); - enable(type); - mCurrTexture = texture; - glBindTexture(sGLTextureType[type], texture); - mHasMipMaps = hasMips; - } + activate(); + enable(type); + mCurrTexture = texture; + glBindTexture(sGLTextureType[type], texture); + mHasMipMaps = hasMips; return true; } @@ -422,7 +414,7 @@ void LLTexUnit::setTextureBlendType(eTextureBlendType type) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); break; default: - llwarns << "Unknown Texture Blend Type: " << type << llendl; + llerrs << "Unknown Texture Blend Type: " << type << llendl; break; } setColorScale(scale_amount); @@ -817,7 +809,7 @@ void LLRender::setSceneBlendType(eBlendType type) glBlendFunc(GL_ONE, GL_ZERO); break; default: - llwarns << "Unknown Scene Blend Type: " << type << llendl; + llerrs << "Unknown Scene Blend Type: " << type << llendl; break; } } @@ -891,7 +883,7 @@ void LLRender::begin(const GLuint& mode) } else if (mCount != 0) { - llwarns << "gGL.begin() called redundantly." << llendl; + llerrs << "gGL.begin() called redundantly." << llendl; } mMode = mode; @@ -922,22 +914,22 @@ void LLRender::flush() #if 0 if (!glIsEnabled(GL_VERTEX_ARRAY)) { - llwarns << "foo 1" << llendl; + llerrs << "foo 1" << llendl; } if (!glIsEnabled(GL_COLOR_ARRAY)) { - llwarns << "foo 2" << llendl; + llerrs << "foo 2" << llendl; } if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY)) { - llwarns << "foo 3" << llendl; + llerrs << "foo 3" << llendl; } if (glIsEnabled(GL_NORMAL_ARRAY)) { - llwarns << "foo 7" << llendl; + llerrs << "foo 7" << llendl; } GLvoid* pointer; @@ -945,19 +937,19 @@ void LLRender::flush() glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].v)) { - llwarns << "foo 4" << llendl; + llerrs << "foo 4" << llendl; } glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].c)) { - llwarns << "foo 5" << llendl; + llerrs << "foo 5" << llendl; } glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].uv)) { - llwarns << "foo 6" << llendl; + llerrs << "foo 6" << llendl; } #endif diff --git a/linden/indra/llrender/llrendertarget.cpp b/linden/indra/llrender/llrendertarget.cpp index 151b761c7..4cf8451db 100644 --- a/linden/indra/llrender/llrendertarget.cpp +++ b/linden/indra/llrender/llrendertarget.cpp @@ -47,10 +47,10 @@ void check_framebuffer_status() case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llwarns << "WTF?" << llendl; + llerrs << "WTF?" << llendl; break; default: - llwarns << "WTF?" << llendl; + llerrs << "WTF?" << llendl; } } } @@ -139,9 +139,9 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt) U32 offset = mTex.size(); if (offset >= 4 || - offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)) + (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) { - llwarns << "Too many color attachments!" << llendl; // KL + llerrs << "Too many color attachments!" << llendl; } U32 tex; @@ -203,7 +203,7 @@ void LLRenderTarget::allocateDepth() gGL.getTexUnit(0)->bindManual(mUsage, mDepth); U32 internal_type = LLTexUnit::getInternalType(mUsage); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + LLImageGL::setManualImage(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL); } } @@ -211,7 +211,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) { if (!mFBO || !target.mFBO) { - llwarns << "Cannot share depth buffer between non FBO render targets." << llendl; + llerrs << "Cannot share depth buffer between non FBO render targets." << llendl; } if (mDepth) @@ -349,16 +349,16 @@ U32 LLRenderTarget::getTexture(U32 attachment) const { if (attachment > mTex.size()-1) { - llwarns << "Invalid attachment index [getTexture]." << llendl; // lets not crash KL its a pain in the ass! + llerrs << "Invalid attachment index." << llendl; } return mTex[attachment]; } void LLRenderTarget::bindTexture(U32 index, S32 channel) { - if (index > 6)//mTex.size()-1) // KL yeah i know its a bit arbitary but make the number big enough as some unused render defer elements cause this to go wild + if (index > mTex.size()-1) { - llwarns << "Invalid attachment index [bindtexture]." << llendl; + llerrs << "Invalid attachment index." << llendl; } gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]); } @@ -440,7 +440,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, #if !LL_DARWIN if (!source.mFBO || !mFBO) { - llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl; + llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } if (mSampleBuffer) @@ -449,27 +449,12 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, } else { - if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) - { - source.bindTarget(); - gGL.getTexUnit(0)->bind(this, true); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); - glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); - source.flush(); - } - else - { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); - stop_glerror(); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); - stop_glerror(); - check_framebuffer_status(); - stop_glerror(); - glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - stop_glerror(); - } + glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } #endif } @@ -568,14 +553,14 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth if (!gGLManager.mHasFramebufferMultisample) { - llwarns << "Attempting to allocate unsupported render target type!" << llendl; + llerrs << "Attempting to allocate unsupported render target type!" << llendl; } mSamples = samples; if (mSamples <= 1) { - llwarns << "Cannot create a multisample buffer with less than 2 samples." << llendl; + llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; } stop_glerror(); @@ -623,9 +608,9 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) U32 offset = mTex.size(); if (offset >= 4 || - offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)) + (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) { - llwarns << "Too many color attachments!" << llendl; + llerrs << "Too many color attachments!" << llendl; } U32 tex; @@ -646,10 +631,10 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llwarns << "WTF?" << llendl; + llerrs << "WTF?" << llendl; break; default: - llwarns << "WTF?" << llendl; + llerrs << "WTF?" << llendl; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); diff --git a/linden/indra/llrender/llrendertarget.h b/linden/indra/llrender/llrendertarget.h index 69af1ea85..d5d809b79 100644 --- a/linden/indra/llrender/llrendertarget.h +++ b/linden/indra/llrender/llrendertarget.h @@ -121,7 +121,6 @@ class LLRenderTarget U32 getTexture(U32 attachment = 0) const; U32 getDepth(void) const { return mDepth; } - BOOL hasStencil() const { return mStencil; } void bindTexture(U32 index, S32 channel); diff --git a/linden/indra/llrender/lltextureatlas.cpp b/linden/indra/llrender/lltextureatlas.cpp deleted file mode 100644 index c0f541982..000000000 --- a/linden/indra/llrender/lltextureatlas.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/** - * @file lltextureatlas.cpp - * @brief LLTextureAtlas class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ -#include "linden_common.h" -#include "llerror.h" -#include "llimage.h" -#include "llmath.h" -#include "llgl.h" -#include "llrender.h" -#include "lltextureatlas.h" - -//------------------- -S16 LLTextureAtlas::sMaxSubTextureSize = 64 ; -S16 LLTextureAtlas::sSlotSize = 32 ; - -#ifndef DEBUG_ATLAS -#define DEBUG_ATLAS 0 -#endif - -#ifndef DEBUG_USAGE_BITS -#define DEBUG_USAGE_BITS 0 -#endif -//************************************************************************************************************** -LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) : LLImageGL(), - mAtlasDim(atlas_dim) -{ - setComponents(ncomponents) ; - - mCanAddToAtlas = FALSE ;//do not add one atlas to another. - mNumSlotsReserved = 0 ; - mMaxSlotsInAtlas = mAtlasDim * mAtlasDim ; - - generateEmptyUsageBits() ; - - //generate an empty texture - S32 dim = mAtlasDim * sSlotSize ; //number of pixels per dimension - LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim, dim, getComponents()); - createGLTexture(0, image_raw, 0); - image_raw = NULL; - dontDiscard(); -} - -LLTextureAtlas::~LLTextureAtlas() -{ - if(mSpatialGroupList.size() > 0) - { - llwarns << "Not clean up the spatial groups!" << llendl ; - } - releaseUsageBits() ; -} - -void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) -{ -#if !DEBUG_ATLAS - xoffset = (F32)col / mAtlasDim ; - yoffset = (F32)row / mAtlasDim ; -#endif -} - -void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) -{ -#if !DEBUG_ATLAS - xscale = (F32)w / (mAtlasDim * sSlotSize) ; - yscale = (F32)h / (mAtlasDim * sSlotSize) ; -#endif -} - -//insert a texture piece into the atlas -LLGLuint LLTextureAtlas::insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) -{ - S32 w = raw_image->getWidth() ; - S32 h = raw_image->getHeight() ; - if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize) - { - //size overflow - return 0 ; - } - - BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName()); - if (!res) llwarns << "bindTexture failed" << llendl; - stop_glerror(); - - GLint xoffset = sSlotSize * slot_col ; - GLint yoffset = sSlotSize * slot_row ; - - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE); - glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, - w, h, mFormatPrimary, mFormatType, raw_image->getData()); - - return getTexName(); -} - -//release a sub-texture slot from the atlas -void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width) -{ - unmarkUsageBits(slot_width, slot_col, slot_row) ; - mNumSlotsReserved -= slot_width * slot_width ; -} - -BOOL LLTextureAtlas::isEmpty() const -{ - return !mNumSlotsReserved ; -} - -BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const -{ - return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ; -} -F32 LLTextureAtlas::getFullness() const -{ - return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ; -} - -void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp) -{ - if(groupp && !hasSpatialGroup(groupp)) - { - mSpatialGroupList.push_back(groupp); - } -} - -void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp) -{ - if(groupp) - { - mSpatialGroupList.remove(groupp); - } -} - -void LLTextureAtlas::clearSpatialGroup() -{ - mSpatialGroupList.clear(); -} -void LLTextureAtlas::removeLastSpatialGroup() -{ - mSpatialGroupList.pop_back() ; -} - -LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup() -{ - if(mSpatialGroupList.size() > 0) - { - return mSpatialGroupList.back() ; - } - return NULL ; -} - -BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp) -{ - for(std::list<LLSpatialGroup*>::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter) - { - if(*iter == groupp) - { - return TRUE ; - } - } - return FALSE ; -} - -//-------------------------------------------------------------------------------------- -//private -void LLTextureAtlas::generateEmptyUsageBits() -{ - S32 col_len = (mAtlasDim + 7) >> 3 ; - mUsageBits = new U8*[mAtlasDim] ; - *mUsageBits = new U8[mAtlasDim * col_len] ; - - mUsageBits[0] = *mUsageBits ; - for(S32 i = 1 ; i < mAtlasDim ; i++) - { - mUsageBits[i] = mUsageBits[i-1] + col_len ; - - for(S32 j = 0 ; j < col_len ; j++) - { - //init by 0 for all bits. - mUsageBits[i][j] = 0 ; - } - } - - //do not forget mUsageBits[0]! - for(S32 j = 0 ; j < col_len ; j++) - { - //init by 0 for all bits. - mUsageBits[0][j] = 0 ; - } - - mTestBits = NULL ; -#if DEBUG_USAGE_BITS - //------------ - //test - mTestBits = new U8*[mAtlasDim] ; - *mTestBits = new U8[mAtlasDim * mAtlasDim] ; - mTestBits[0] = *mTestBits ; - for(S32 i = 1 ; i < mAtlasDim ; i++) - { - mTestBits[i] = mTestBits[i-1] + mAtlasDim ; - - for(S32 j = 0 ; j < mAtlasDim ; j++) - { - //init by 0 for all bits. - mTestBits[i][j] = 0 ; - } - } - - for(S32 j = 0 ; j < mAtlasDim ; j++) - { - //init by 0 for all bits. - mTestBits[0][j] = 0 ; - } -#endif -} - -void LLTextureAtlas::releaseUsageBits() -{ - if(mUsageBits) - { - delete[] *mUsageBits ; - delete[] mUsageBits ; - } - mUsageBits = NULL ; - - //test - if( mTestBits) - { - delete[] *mTestBits; - delete[] mTestBits; - } - mTestBits = NULL ; -} - -void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) -{ - S16 x = col >> 3 ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - mUsageBits[row + i][x] |= mask ; - } - -#if DEBUG_USAGE_BITS - //test - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - mTestBits[i][j] = 1 ; - } - } -#endif -} - -void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row) -{ - S16 x = col >> 3 ; - U8 mask = 1 ; - for(S8 i = 1 ; i < bits_len ; i++) - { - mask |= (1 << i) ; - } - mask <<= (col & 7) ; - mask = ~mask ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - mUsageBits[row + i][x] &= mask ; - } - -#if DEBUG_USAGE_BITS - //test - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - mTestBits[i][j] = 0 ; - } - } -#endif -} - -//return true if any of bits in the range marked. -BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) -{ - BOOL ret = FALSE ; - S16 x = col >> 3 ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - if(mUsageBits[row + i][x] & mask) - { - ret = TRUE ; - break ; - //return TRUE ; - } - } - -#if DEBUG_USAGE_BITS - //test - BOOL ret2 = FALSE ; - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - if(mTestBits[i][j]) - { - ret2 = TRUE ; - } - } - } - - if(ret != ret2) - { - llwarns << "bits map corrupted." << llendl ; - } -#endif - return ret ;//FALSE ; -} - -//---------------------------------------------------------------------- -// -//index order: Z order, i.e.: -// |-----|-----|-----|-----| -// | 10 | 11 | 14 | 15 | -// |-----|-----|-----|-----| -// | 8 | 9 | 12 | 13 | -// |-----|-----|-----|-----| -// | 2 | 3 | 6 | 7 | -// |-----|-----|-----|-----| -// | 0 | 1 | 4 | 5 | -// |-----|-----|-----|-----| -void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row) -{ - col = 0 ; - row = 0 ; - - S16 index_copy = index ; - for(S16 i = 0 ; index_copy && i < 16 ; i += 2) - { - col |= ((index & (1 << i)) >> i) << (i >> 1) ; - row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ; - index_copy >>= 2 ; - } -} -void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index) -{ - index = 0 ; - S16 col_copy = col ; - S16 row_copy = row ; - for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++) - { - index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ; - col_copy >>= 1 ; - row_copy >>= 1 ; - } -} -//---------------------------------------------------------------------- -//return TRUE if succeeds. -BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row) -{ - S16 index_step = bits_len * bits_len ; - - U8 mask = 1 ; - for(S8 i = 1 ; i < bits_len ; i++) - { - mask |= (1 << i) ; - } - - U8 cur_mask ; - for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step) - { - getPositionFromIndex(index, col, row) ; - - cur_mask = mask << (col & 7) ; - if(!areUsageBitsMarked(bits_len, cur_mask, col, row)) - { - markUsageBits(bits_len, cur_mask, col, row) ; - mNumSlotsReserved += bits_len * bits_len ; - - return TRUE ; - } - } - - return FALSE ; -} diff --git a/linden/indra/llrender/lltextureatlas.h b/linden/indra/llrender/lltextureatlas.h deleted file mode 100644 index 4922175d4..000000000 --- a/linden/indra/llrender/lltextureatlas.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file lltextureatlas.h - * @brief LLTextureAtlas base class. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - - -#ifndef LL_TEXTUREATLAS_H -#define LL_TEXTUREATLAS_H - -#include "llimagegl.h" -class LLSpatialGroup ; - -class LLTextureAtlas : public LLImageGL -{ -public: - LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ; - ~LLTextureAtlas() ; - - LLGLuint insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ; - void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width); - - BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ; - void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ; - void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ; - - BOOL isEmpty() const ; - BOOL isFull(S8 to_be_reserved = 1) const ; - F32 getFullness() const ; - - void addSpatialGroup(LLSpatialGroup* groupp) ; - void removeSpatialGroup(LLSpatialGroup* groupp) ; - LLSpatialGroup* getLastSpatialGroup() ; - void removeLastSpatialGroup() ; - BOOL hasSpatialGroup(LLSpatialGroup* groupp) ; - void clearSpatialGroup() ; - std::list<LLSpatialGroup*>* getSpatialGroupList() {return &mSpatialGroupList;} -private: - void generateEmptyUsageBits() ; - void releaseUsageBits() ; - - void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ; - void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ; - - void getPositionFromIndex(S16 index, S16& col, S16& row) ; - void getIndexFromPosition(S16 col, S16 row, S16& index) ; - BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ; - -private: - S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas. - S16 mNumSlotsReserved ; - S16 mMaxSlotsInAtlas ; - U8 **mUsageBits ; - std::list<LLSpatialGroup*> mSpatialGroupList ; - -public: - //debug use only - U8 **mTestBits ; - -public: - static S16 sMaxSubTextureSize ; - static S16 sSlotSize ; -}; - -#endif - diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp index 31c2d75d8..461edbeec 100644 --- a/linden/indra/llrender/llvertexbuffer.cpp +++ b/linden/indra/llrender/llvertexbuffer.cpp @@ -96,7 +96,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) { /*if (LLGLImmediate::sStarted) { - llwarns << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; + llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; }*/ if (sLastMask != data_mask) @@ -129,7 +129,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) { //needs to be enabled, make sure it was (DEBUG TEMPORARY) if (i > 0 && !glIsEnabled(array[i])) { - llwarns << "Bad client state! " << array[i] << " disabled." << llendl; + llerrs << "Bad client state! " << array[i] << " disabled." << llendl; } } } @@ -141,7 +141,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } else if (gDebugGL && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) - llwarns << "Bad client state! " << array[i] << " enabled." << llendl; + llerrs << "Bad client state! " << array[i] << " enabled." << llendl; } } } @@ -197,28 +197,28 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi if (start >= (U32) mRequestedNumVerts || end >= (U32) mRequestedNumVerts) { - llwarns << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; + llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; } if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { - llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } if (mGLIndices != sGLRenderIndices) { - llwarns << "Wrong index buffer bound." << llendl; + llerrs << "Wrong index buffer bound." << llendl; } if (mGLBuffer != sGLRenderBuffer) { - llwarns << "Wrong vertex buffer bound." << llendl; + llerrs << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llwarns << "Invalid draw mode: " << mode << llendl; + llerrs << "Invalid draw mode: " << mode << llendl; return; } @@ -233,22 +233,22 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { - llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } if (mGLIndices != sGLRenderIndices) { - llwarns << "Wrong index buffer bound." << llendl; + llerrs << "Wrong index buffer bound." << llendl; } if (mGLBuffer != sGLRenderBuffer) { - llwarns << "Wrong vertex buffer bound." << llendl; + llerrs << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llwarns << "Invalid draw mode: " << mode << llendl; + llerrs << "Invalid draw mode: " << mode << llendl; return; } @@ -263,17 +263,17 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) { - llwarns << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; + llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; } if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) { - llwarns << "Wrong vertex buffer bound." << llendl; + llerrs << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llwarns << "Invalid draw mode: " << mode << llendl; + llerrs << "Invalid draw mode: " << mode << llendl; return; } @@ -530,7 +530,7 @@ void LLVertexBuffer::destroyGLBuffer() { if (mMappedData || mMappedIndexData) { - llwarns << "Vertex buffer destroyed while mapped!" << llendl; + llerrs << "Vertex buffer destroyed while mapped!" << llendl; } releaseBuffer(); } @@ -557,7 +557,7 @@ void LLVertexBuffer::destroyGLIndices() { if (mMappedData || mMappedIndexData) { - llwarns << "Vertex buffer destroyed while mapped." << llendl; + llerrs << "Vertex buffer destroyed while mapped." << llendl; } releaseIndices(); } @@ -634,7 +634,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) if (mMappedData) { - llwarns << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; + llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; } if (create && (nverts || nindices)) { @@ -782,11 +782,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access) LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mFinal) { - llwarns << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; + llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; } if (!useVBOs() && !mMappedData && !mMappedIndexData) { - llwarns << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; + llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; } if (!mLocked && useVBOs()) @@ -813,11 +813,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access) glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); if (buff != mGLBuffer) { - llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; } - llwarns << "glMapBuffer returned NULL (no vertex data)" << llendl; + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; } if (!mMappedIndexData) @@ -826,10 +826,10 @@ U8* LLVertexBuffer::mapBuffer(S32 access) glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); if (buff != mGLIndices) { - llwarns << "Invalid GL index buffer bound: " << buff << llendl; + llerrs << "Invalid GL index buffer bound: " << buff << llendl; } - llwarns << "glMapBuffer returned NULL (no index data)" << llendl; + llerrs << "glMapBuffer returned NULL (no index data)" << llendl; } sMappedCount++; @@ -908,7 +908,7 @@ template <class T,S32 type> struct VertexBufferStrider } else { - llwarns << "VertexBufferStrider could not find valid vertex data." << llendl; + llerrs << "VertexBufferStrider could not find valid vertex data." << llendl; } return FALSE; } @@ -965,7 +965,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride) LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mNumVerts) { - llwarns << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; + llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; } // This code assumes that setStride() will only be called once per VBO per type. S32 delta = new_stride - sTypeOffsets[type]; @@ -1020,15 +1020,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) + if (buff != mGLBuffer) { - llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; } glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) + if (buff != mGLIndices) { - llwarns << "Invalid GL index buffer bound: " << buff << llendl; + llerrs << "Invalid GL index buffer bound: " << buff << llendl; } } @@ -1038,15 +1038,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) + if (buff != mGLBuffer) { - llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; } glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) + if (buff != mGLIndices) { - llwarns << "Invalid GL index buffer bound: " << buff << llendl; + llerrs << "Invalid GL index buffer bound: " << buff << llendl; } } @@ -1068,7 +1068,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (data_mask != 0) { - llwarns << "Buffer set for rendering before being filled after resize." << llendl; + llerrs << "Buffer set for rendering before being filled after resize." << llendl; } } @@ -1129,7 +1129,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if ((data_mask & mTypeMask) != data_mask) { - llwarns << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; + llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } if (data_mask & MAP_NORMAL) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index fafcfa85e..04ed48653 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -330,7 +330,6 @@ set(viewer_SOURCE_FILES llpolymesh.cpp llpolymorph.cpp llprefsadvanced.cpp - llpostprocess.cpp llprefschat.cpp llprefsim.cpp llprefsvoice.cpp @@ -361,7 +360,6 @@ set(viewer_SOURCE_FILES llsurface.cpp llsurfacepatch.cpp lltexlayer.cpp - lltextureatlasmanager.cpp lltexturecache.cpp lltexturectrl.cpp lltexturefetch.cpp @@ -780,7 +778,6 @@ set(viewer_HEADER_FILES llpolymesh.h llpolymorph.h llprefsadvanced.h - llpostprocess.h llprefschat.h llprefsim.h llprefsvoice.h @@ -813,7 +810,6 @@ set(viewer_HEADER_FILES llsurfacepatch.h lltable.h lltexlayer.h - lltextureatlasmanager.h lltexturecache.h lltexturectrl.h lltexturefetch.h diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index d306f0deb..57ed4c0fc 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -5122,21 +5122,6 @@ <key>Value</key> <integer>1</integer> </map> - -<!--KL port --> - <key>EnableTextureAtlas</key> - <map> - <key>Comment</key> - <string>Whether to use texture atlas or not</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> -<!--/KL port --> - <key>EnableVoiceChat</key> <map> <key>Comment</key> @@ -8967,75 +8952,12 @@ <key>Type</key> <string>Vector3</string> <key>Value</key> - <array> - <real>1.0</real> - <real>12.0</real> - <real>32.0</real> - </array> - </map> - <key>RenderShadowSplitExponent</key> - <map> - <key>Comment</key> - <string>Near clip plane split distances for shadow map frusta (x=perspective, y=ortho, z=transition rate).</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>3.0</real> - <real>3.0</real> - <real>2.0</real> - </array> - </map> - <key>RenderShadowOrthoClipPlanes</key> - <map> - <key>Comment</key> - <string>Near clip plane split distances for orthographic shadow map frusta.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> <array> <real>4.0</real> <real>8.0</real> <real>24.0</real> </array> </map> - <key>RenderShadowProjOffset</key> - <map> - <key>Comment</key> - <string>Amount to scale distance to virtual origin of shadow perspective projection.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>2.0</real> - </map> - <key>RenderShadowSlopeThreshold</key> - <map> - <key>Comment</key> - <string>Cutoff slope value for points to affect perspective shadow generation</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.0</real> - </map> - <key>RenderShadowProjExponent</key> - <map> - <key>Comment</key> - <string>Exponent applied to transition between ortho and perspective shadow projections based on viewing angle and light vector.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.5</real> - </map> <key>RenderSSAOScale</key> <map> <key>Comment</key> @@ -9195,184 +9117,6 @@ <key>Value</key> <integer>0</integer> </map> - - <key>RenderGILightRadius</key> - <map> - <key>Comment</key> - <string>Distance of ambiant bounce lighting from sun.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>8</real> - </map> - - <key>RenderGISamples</key> - <map> - <key>Comment</key> - <string>Number of samples to take for GI.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <real>64</real> - </map> - - <key>RenderGIRange</key> - <map> - <key>Comment</key> - <string>Distance to cut off GI effect.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>128</real> - </map> - - - <key>RenderGIDirectionWeight</key> - <map> - <key>Comment</key> - <string>Weight of reflected light vector in GI angular attenuation.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.5</real> - </map> - - <key>RenderGILightOffset</key> - <map> - <key>Comment</key> - <string>Amount to offset light from point of impact in gi map (scaled by light radius).</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.0</real> - </map> - - <key>RenderGIColorCurve</key> - <map> - <key>Comment</key> - <string>Global illumination color correction curve parameters.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>0.0</real> - <real>0.2</real> - <real>0.02</real> - </array> - </map> - - <key>RenderLuminanceColorCurve</key> - <map> - <key>Comment</key> - <string>Luminance color correction curve parameters.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>0.30</real> - <real>0.0</real> - <real>0.04</real> - </array> - </map> - - <key>RenderGILuminanceColorCurve</key> - <map> - <key>Comment</key> - <string>Luminance color correction curve parameters.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>0.4</real> - <real>0.0</real> - <real>0.05</real> - </array> - </map> - - <key>RenderSunLuminanceColorCurve</key> - <map> - <key>Comment</key> - <string>Luminance color correction curve parameters.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>0.6</real> - <real>0.0</real> - <real>-0.3</real> - </array> - </map> - - <key>RenderLuminanceDetail</key> - <map> - <key>Comment</key> - <string>Mipmap level to use for luminance</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>8.0</real> - </map> - - <key>RenderLuminanceFade</key> - <map> - <key>Comment</key> - <string>Scaler for speed of luminance adjustment</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.05</real> - </map> - - <key>RenderGISpecularCurve</key> - <map> - <key>Comment</key> - <string>Global illumination specular color correction curve parameters.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>0.1</real> - <real>0.0</real> - <real>0.9</real> - </array> - </map> - - <key>RenderGIIntensity</key> - <map> - <key>Comment</key> - <string>Distance of ambiant bounce lighting from sun.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.2f</real> - </map> - <key>RenderDeferredAlphaSoften</key> <map> <key>Comment</key> @@ -9395,455 +9139,72 @@ <key>Value</key> <real>4</real> </map> - <key>RenderDeferredSpotShadowBias</key> - <map> - <key>Comment</key> - <string>Bias value for spot shadows (prevent shadow acne).</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>-64.0</real> - </map> - <key>RenderDeferredSpotShadowOffset</key> + <key>RenderDeferred</key> <map> <key>Comment</key> - <string>Offset value for spot shadows (prevent shadow acne).</string> + <string>Use deferred rendering pipeline.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>Boolean</string> <key>Value</key> - <real>0.8</real> + <integer>0</integer> </map> - - <key>RenderShadowBias</key> + <key>RenderDeferredSunShadow</key> <map> <key>Comment</key> - <string>Bias value for shadows (prevent shadow acne).</string> + <string>Generate shadows from the sun.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>Boolean</string> <key>Value</key> - <real>0.001</real> - </map> - <key>RenderShadowOffset</key> - <map> - <key>Comment</key> - <string>Offset value for shadows (prevent shadow acne).</string> - <key>Persist</key> <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.6</real> </map> - - <key>RenderShadowResolutionScale</key> + <key>RenderDeferredSunWash</key> <map> <key>Comment</key> - <string>Scale of shadow map resolution vs. screen resolution</string> + <string>Amount local lights are washed out by sun.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>1.0</real> + <real>0.5</real> </map> - - - - <key>RenderDeferredTreeShadowBias</key> + <key>RenderShadowNoise</key> <map> <key>Comment</key> - <string>Bias value for tree shadows (prevent shadow acne).</string> + <string>Magnitude of noise on shadow samples.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>1.0</real> + <real>-0.0001</real> </map> - <key>RenderDeferredTreeShadowOffset</key> + <key>RenderShadowBlurSize</key> <map> <key>Comment</key> - <string>Offset value for tree shadows (prevent shadow acne).</string> + <string>Scale of shadow softening kernel.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>1.0</real> + <real>0.7</real> </map> - - <key>RenderHighlightFadeTime</key> + <key>RenderShadowBlurSamples</key> <map> <key>Comment</key> - <string>Transition time for mouseover highlights.</string> + <string>Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>U32</string> <key>Value</key> - <real>0.2</real> + <real>5</real> </map> - - <key>RenderHighlightBrightness</key> - <map> - <key>Comment</key> - <string>Brightness of mouseover highlights.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>4.0</real> - </map> - - <key>RenderHighlightThickness</key> - <map> - <key>Comment</key> - <string>Thickness of mouseover highlights.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.6</real> - </map> - - <key>RenderHighlightColor</key> - <map> - <key>Comment</key> - <string>Brightness of mouseover highlights.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Color4</string> - <key>Value</key> - <array> - <real>0.4</real> - <real>0.98</real> - <real>0.93</real> - <real>1.0</real> - </array> - </map> - - <key>RenderSpecularResX</key> - <map> - <key>Comment</key> - <string>Spec map resolution.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <real>128</real> - </map> - - <key>RenderSpecularResY</key> - <map> - <key>Comment</key> - <string>Spec map resolution.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <real>128</real> - </map> - - <key>RenderSpecularExponent</key> - <map> - <key>Comment</key> - <string>Specular exponent for generating spec map</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1</real> - </map> - - <key>RenderDeferred</key> - <map> - <key>Comment</key> - <string>Use deferred rendering pipeline.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - - <key>RenderDeferredShadow</key> - <map> - <key>Comment</key> - <string>Enable shadows in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredGI</key> - <map> - <key>Comment</key> - <string>Enable GI in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - - <key>RenderDeferredSunShadow</key> - <map> - <key>Comment</key> - <string>Generate shadows from the sun.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredSun</key> - <map> - <key>Comment</key> - <string>Execute sunlight shader in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredAtmospheric</key> - <map> - <key>Comment</key> - <string>Execute atmospheric shader in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredBlurLight</key> - <map> - <key>Comment</key> - <string>Execute shadow softening shader in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredLocalLights</key> - <map> - <key>Comment</key> - <string>Execute local lighting shader in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredFullscreenLights</key> - <map> - <key>Comment</key> - <string>Execute local lighting shader in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredSunWash</key> - <map> - <key>Comment</key> - <string>Amount local lights are washed out by sun.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.5</real> - </map> - <key>RenderShadowNoise</key> - <map> - <key>Comment</key> - <string>Magnitude of noise on shadow samples.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>-0.0001</real> - </map> - <key>RenderShadowErrorCutoff</key> - <map> - <key>Comment</key> - <string>Cutoff error value to use ortho instead of perspective projection.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>5.0</real> - </map> - <key>RenderShadowFOVCutoff</key> - <map> - <key>Comment</key> - <string>Cutoff FOV to use ortho instead of perspective projection.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1.1</real> - </map> - - <key>RenderShadowGaussian</key> - <map> - <key>Comment</key> - <string>Gaussian coefficients for the two shadow/SSAO blurring passes (z component unused).</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>3.0</real> - <real>2.0</real> - <real>0.0</real> - </array> - </map> - - <key>RenderShadowBlurSize</key> - <map> - <key>Comment</key> - <string>Scale of shadow softening kernel.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.8</real> - </map> - <key>RenderShadowBlurSamples</key> - <map> - <key>Comment</key> - <string>Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <real>4</real> - </map> - <key>RenderShadowBlurDistFactor</key> - <map> - <key>Comment</key> - <string>Distance scaler for shadow blur.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.1</real> - </map> - - <key>RenderGIBlurColorCurve</key> - <map> - <key>Comment</key> - <string>Color curve for GI softening kernel</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>1.0</real> - <real>0.6</real> - <real>0.1</real> - </array> - </map> - - <key>RenderGIGaussian</key> - <map> - <key>Comment</key> - <string>Gaussian coefficient for the two GI blurring passes.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>64</real> - </map> - - <key>RenderGIBlurPasses</key> - <map> - <key>Comment</key> - <string>Scale of GI softening kernel.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <real>2</real> - </map> - - <key>RenderGIBlurSize</key> - <map> - <key>Comment</key> - <string>Scale of GI softening kernel.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>3.0</real> - </map> - <key>RenderGIBlurSamples</key> - <map> - <key>Comment</key> - <string>Number of samples to take for each pass of GI blur (value range 1-16). Actual number of samples is value * 2 - 1.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <real>6</real> - </map> - <key>RenderGIBlurDistFactor</key> - <map> - <key>Comment</key> - <string>Distance scaler for GI blur.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.0</real> - </map> - <key>RenderDynamicLOD</key> <map> <key>Comment</key> @@ -10094,17 +9455,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderHighlightSelections</key> - <map> - <key>Comment</key> - <string>Show selection outlines on objects</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>RenderHiddenSelections</key> <map> <key>Comment</key> @@ -10413,17 +9763,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderUIBuffer</key> - <map> - <key>Comment</key> - <string>Cache ui render in a screen aligned buffer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>RenderUnloadedAvatar</key> <map> <key>Comment</key> diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index f90d91faa..a91e9fa15 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -13,9 +13,9 @@ uniform sampler2DShadow shadowMap1; uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform sampler2DRect depthMap; +uniform sampler2DRect positionMap; -uniform mat4 shadow_matrix[6]; +uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -26,31 +26,15 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; -varying vec3 vary_light; uniform float alpha_soften; -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = getPosition(frag).xyz; + vec3 samp_pos = texture2DRect(positionMap, frag).xyz; float shadow = 1.0; vec4 pos = vec4(vary_position, 1.0); @@ -98,7 +82,7 @@ void main() //gl_FragColor = gl_Color; gl_FragColor = color; - //gl_FragColor = vec4(1,0,1,1)*shadow; + //gl_FragColor = vec4(1,0,1,1); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 48baf77d5..b496bd674 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -20,11 +20,8 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; -varying vec3 vary_light; uniform float near_clip; -uniform float shadow_offset; -uniform float shadow_bias; void main() { @@ -35,9 +32,8 @@ void main() vec4 pos = (gl_ModelViewMatrix * gl_Vertex); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - // KL this works around ATI not compiling the shader but maintains shadow offset and bias vec3 not vec4 - vary_position = pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias); - + vary_position = pos.xyz; + calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); @@ -58,8 +54,6 @@ void main() col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); col.rgb = scaleDownLight(col.rgb); - vary_light = gl_LightSource[0].position.xyz; - vary_ambient = col.rgb*gl_Color.rgb; vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl index ff64a6b0c..6c94f5c5a 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl @@ -12,7 +12,7 @@ uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[6]; +uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; vec3 atmosLighting(vec3 light); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 4b9cca258..58aa5a9cb 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -8,18 +8,13 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; +varying vec4 vary_position; void main() { - vec4 diff = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy); - // Viewer 2.0 uses 0.2 but for KL's viewer if i want a complete avatar need this to be 0.0 for now. - if (diff.a < 0.0) - { - discard; - } - - gl_FragData[0] = vec4(diff.rgb, 1.0); + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); + gl_FragData[2] = vec4(normalize(vary_normal), 0.0); + gl_FragData[3] = vary_position; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 00083eb6b..27c09db92 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -10,7 +10,6 @@ uniform sampler2D diffuseMap; void main() { - gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a); - //gl_FragColor = vec4(1,1,1,1); + gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy)); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index 8c8489d08..14da6b1ad 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -28,7 +28,8 @@ void main() norm = normalize(norm); pos = gl_ProjectionMatrix * pos; - pos.z = max(pos.z, -pos.w+0.01); + //smash geometry against near clip plane + pos.z = max(pos.z, -1.0); gl_Position = pos; gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index 471a1f040..12a7ff7f2 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -10,6 +10,7 @@ mat4 getSkinnedTransform(); attribute vec4 weight; varying vec3 vary_normal; +varying vec4 vary_position; void main() { @@ -29,6 +30,7 @@ void main() norm.z = dot(trans[2].xyz, gl_Normal); norm = normalize(norm); + vary_position = pos; vary_normal = norm; gl_Position = gl_ProjectionMatrix * pos; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 1713fe99f..3c6700a87 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -7,11 +7,10 @@ #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect depthMap; +uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; -uniform float dist_factor; uniform float blur_size; uniform vec2 delta; uniform vec3 kern[32]; @@ -20,52 +19,30 @@ uniform float kern_scale; varying vec2 vary_fragcoord; -uniform mat4 inv_proj; -uniform vec2 screen_res; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - void main() { - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; - vec3 pos = getPosition(vary_fragcoord.xy).xyz; - vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + vec3 pos = texture2DRect(positionMap, vary_fragcoord.xy).xyz; + vec2 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rg; vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); - dlt /= max(-pos.z*dist_factor, 1.0); - vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' - vec4 col = defined_weight.xyxx * ccol; + vec2 col = defined_weight * ccol; for (int i = 1; i < kern_length; i++) { vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; + vec3 samppos = texture2DRect(positionMap, tc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane if (d*d <= 0.003) { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; + col += texture2DRect(lightMap, tc).rg*kern[i].xy; defined_weight += kern[i].xy; } } + col /= defined_weight; - - col /= defined_weight.xyxx; - - gl_FragColor = col; - - //gl_FragColor = ccol; + gl_FragColor = vec4(col.r, col.g, 0.0, 1.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 1c29dae5f..a8712bc8c 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -11,6 +11,7 @@ uniform sampler2D bumpMap; varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; +varying vec4 vary_position; void main() { @@ -21,7 +22,8 @@ void main() dot(norm,vary_mat1), dot(norm,vary_mat2)); - gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); - gl_FragData[1] = vec4(col*gl_Color.a, gl_Color.a); - gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0); + gl_FragData[0].rgb = gl_Color.rgb*col; + gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); + gl_FragData[2] = vec4(normalize(tnorm), 0.0); + gl_FragData[3] = vary_position; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 9589912c6..ba180922c 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -8,6 +8,7 @@ varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; +varying vec4 vary_position; void main() { @@ -15,6 +16,8 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + vary_position = gl_ModelViewMatrix * gl_Vertex; + vec3 n = normalize(gl_NormalMatrix * gl_Normal); vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz); vec3 t = cross(b, n); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 919dd5ddf..f2ba2df69 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -8,11 +8,13 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; +varying vec4 vary_position; void main() { vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; - gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); // KL viewer 2.0 has 0.0 but this is not working right yet besides i like to see my eyes :) + gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); - gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); + gl_FragData[2] = vec4(normalize(vary_normal), 0.0); + gl_FragData[3] = vary_position; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 44468cdfa..3413a7f9d 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -6,13 +6,16 @@ */ varying vec3 vary_normal; +varying vec4 vary_position; void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + vary_position = gl_ModelViewMatrix * gl_Vertex; + vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index e518bddb9..2a811c589 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -8,9 +8,14 @@ #extension GL_ARB_texture_rectangle : enable uniform sampler2D diffuseMap; -uniform sampler2DRect depthMap; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; +uniform sampler2DRect positionMap; +uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -25,27 +30,12 @@ varying vec3 vary_fragcoord; uniform float alpha_soften; -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = getPosition(frag).xyz; + vec3 samp_pos = texture2DRect(positionMap, frag).xyz; float shadow = 1.0; vec4 pos = vary_position; @@ -56,10 +46,10 @@ void main() color.rgb = fullbrightScaleSoftClip(color.rgb); - if (samp_pos.z != 0.0 && color.a < 1.0) + if (samp_pos.z != 0.0) { float dist_factor = alpha_soften; - float a = color.a; + float a = gl_Color.a; a *= a; dist_factor *= 1.0/(1.0-a); color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index aff51178b..6381a1ced 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -12,12 +12,12 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); +varying vec4 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_normal; varying vec3 vary_fragcoord; uniform float near_clip; -varying vec4 vary_position; void main() { diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl deleted file mode 100644 index b351eec6e..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file giF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2D noiseMap; - -uniform sampler2D diffuseGIMap; -uniform sampler2D normalGIMap; -uniform sampler2D depthGIMap; - -uniform sampler2D lightFunc; - -// Inputs -varying vec2 vary_fragcoord; - -uniform vec2 screen_res; - -uniform mat4 inv_proj; -uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space -uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space -uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix -uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space -uniform float gi_radius; -uniform float gi_intensity; -uniform int gi_samples; -uniform vec2 gi_kern[25]; -uniform vec2 gi_scale; -uniform vec3 gi_quad; -uniform vec3 gi_spec; -uniform float gi_direction_weight; -uniform float gi_light_offset; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -vec4 getGIPosition(vec2 gi_tc) -{ - float depth = texture2D(depthGIMap, gi_tc).a; - vec2 sc = gi_tc*2.0; - sc -= vec2(1.0, 1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = gi_inv_proj*ndc; - pos.xyz /= pos.w; - pos.w = 1.0; - return pos; -} - -vec3 giAmbient(vec3 pos, vec3 norm) -{ - vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); - gi_c.xyz /= gi_c.w; - - vec4 gi_pos = gi_mat*vec4(pos,1.0); - vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; - gi_norm = normalize(gi_norm); - - vec2 tcx = gi_norm.xy; - vec2 tcy = gi_norm.yx; - - vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); - - vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w); - - //vec3 eye_dir = vec3(0,0,-1); - //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; - //eye_dir = normalize(eye_dir); - - //float round_x = gi_scale.x; - //float round_y = gi_scale.y; - - vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5; - debug.xz = vec2(0.0,0.0); - //debug = fract(debug); - - float round_x = 1.0/64.0; - float round_y = 1.0/64.0; - - //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; - //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; - - float fda = 0.0; - vec3 fdiff = vec3(0,0,0); - - vec3 rcol = vec3(0,0,0); - - float fsa = 0.0; - - for (int i = -1; i < 2; i+=2 ) - { - for (int j = -1; j < 2; j+=2) - { - vec2 tc = vec2(i, j)*0.75; - vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; - //tc += gi_norm.xy*nz.z; - tc += nz.xy*2.0; - tc /= gi_samples; - tc += gi_c.xy; - - vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); - vec3 lpos = getGIPosition(tc.xy).xyz; - - vec3 at = lpos-gi_pos.xyz; - float dist = dot(at,at); - float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); - - if (da > 0.0) - { - //add angular attenuation - vec3 ldir = at; - float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0); - - float ld = -dot(ldir, lnorm); - - if (ang_atten > 0.0 && ld < 0.0) - { - vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz; - da = da*ang_atten; - fda += da; - fdiff += diff*da; - } - } - } - } - - fdiff /= max(gi_spec.y*fda, gi_quad.z); - fdiff = clamp(fdiff, vec3(0), vec3(1)); - - vec3 ret = fda*fdiff; - //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; - - //fda *= nz.z; - - //rcol.rgb *= gi_intensity; - //return rcol.rgb+vary_AmblitColor.rgb*0.25; - //return vec4(debug, 0.0); - //return vec4(fda*fdiff, 0.0); - return clamp(ret,vec3(0.0), vec3(1.0)); - //return debug.xyz; -} - -void main() -{ - vec2 pos_screen = vary_fragcoord.xy; - vec4 pos = getPosition(pos_screen); - vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; - - gl_FragData[0].xyz = giAmbient(pos, norm); -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl deleted file mode 100644 index 71dcea962..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file giV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; - -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; - vec4 tex = gl_MultiTexCoord0; - tex.w = 1.0; - - gl_FrontColor = gl_Color; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl deleted file mode 100644 index e8b53b029..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @file luminanceF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect diffuseMap; - -varying vec2 vary_fragcoord; - -void main() -{ - gl_FragColor = texture2DRect(diffuseMap, vary_fragcoord.xy); -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl deleted file mode 100644 index db8775f02..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @file giV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; - -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; - - gl_FrontColor = gl_Color; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index ce0494c74..3689d1284 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -7,15 +7,13 @@ #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect depthMap; uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; +uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; uniform sampler2DRect lightMap; uniform sampler2D noiseMap; -uniform sampler2D lightFunc; - uniform vec3 env_mat[3]; uniform float sun_wash; @@ -25,48 +23,24 @@ uniform int light_count; uniform vec4 light[16]; uniform vec4 light_col[16]; -varying vec4 vary_fragcoord; +varying vec3 vary_fragcoord; uniform vec2 screen_res; -uniform float far_z; - -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - void main() { vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; - vec3 pos = getPosition(frag.xy).xyz; - if (pos.z < far_z) - { - discard; - } - - vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz*2.0-1.0); + vec3 pos = texture2DRect(positionMap, frag.xy).xyz; + vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz); vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; float noise = texture2D(noiseMap, frag.xy/128.0).b; vec3 out_col = vec3(0,0,0); - vec3 npos = normalize(-pos); for (int i = 0; i < light_count; ++i) { vec3 lv = light[i].xyz-pos; float dist2 = dot(lv,lv); - dist2 /= light[i].w; - if (dist2 > 1.0) + if (dist2 > light[i].w) { continue; } @@ -81,41 +55,29 @@ void main() da = dot(norm, lv); float fa = light_col[i].a+1.0; - float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-light[i].w*(1.0-fa))/(light[i].w*fa), 0.0, 1.0); dist_atten *= noise; float lit = da * dist_atten; vec3 col = light_col[i].rgb*lit*diff; - //vec3 col = vec3(dist2, light_col[i].a, lit); if (spec.a > 0.0) { - //vec3 ref = dot(pos+lv, norm); - - float sa = dot(normalize(lv+npos),norm); - - if (sa > 0) - { - sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*light_col[i].rgb*spec.rgb; - } + vec3 ref = reflect(normalize(pos), norm); + float sa = dot(ref,lv); + sa = max(sa, 0.0); + sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*light_col[i].rgb*spec.rgb; } out_col += col; } - if (dot(out_col, out_col) <= 0.0) - { - discard; - } - //attenuate point light contribution by SSAO component out_col *= texture2DRect(lightMap, frag.xy).g; gl_FragColor.rgb = out_col; gl_FragColor.a = 0.0; - - //gl_FragColor = vec4(0.1, 0.025, 0.025/4.0, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl deleted file mode 100644 index 021e8a277..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ /dev/null @@ -1,184 +0,0 @@ -/** - * @file multiSpotLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#version 120 - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform sampler2D lightFunc; -uniform sampler2D projectionMap; - -uniform mat4 proj_mat; //screen space to light space -uniform float proj_near; //near clip for projection -uniform vec3 proj_p; //plane projection is emitting from (in screen space) -uniform vec3 proj_n; -uniform float proj_focus; //distance from plane to begin blurring -uniform float proj_lod; //(number of mips in proj map) -uniform float proj_range; //range between near clip and far clip plane of projection -uniform float proj_ambient_lod; -uniform float proj_ambiance; -uniform float near_clip; -uniform float far_clip; - -uniform vec3 proj_origin; //origin of projection to be used for angular attenuation -uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade; - -varying vec4 vary_light; - -varying vec4 vary_fragcoord; -uniform vec2 screen_res; - -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -void main() -{ - vec4 frag = vary_fragcoord; - frag.xyz /= frag.w; - frag.xyz = frag.xyz*0.5+0.5; - frag.xy *= screen_res; - - vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = vary_light.xyz-pos.xyz; - float dist2 = dot(lv,lv); - dist2 /= vary_light.w; - if (dist2 > 1.0) - { - discard; - } - - float shadow = 1.0; - - if (proj_shadow_idx >= 0) - { - vec4 shd = texture2DRect(lightMap, frag.xy); - float sh[2]; - sh[0] = shd.b; - sh[1] = shd.a; - shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); - } - - vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; - - norm = normalize(norm); - float l_dist = -dot(lv, proj_n); - - vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); - if (proj_tc.z < 0.0) - { - discard; - } - - proj_tc.xyz /= proj_tc.w; - - float fa = gl_Color.a+1.0; - float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); - - lv = proj_origin-pos.xyz; - lv = normalize(lv); - float da = dot(norm, lv); - - vec3 col = vec3(0,0,0); - - vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; - - float noise = texture2D(noiseMap, frag.xy/128.0).b; - if (proj_tc.z > 0.0 && - proj_tc.x < 1.0 && - proj_tc.y < 1.0 && - proj_tc.x > 0.0 && - proj_tc.y > 0.0) - { - float lit = 0.0; - float amb_da = proj_ambiance; - - if (da > 0.0) - { - float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - - vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - - vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; - - lit = da * dist_atten * noise; - - col = lcol*lit*diff_tex*shadow; - amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; - } - - //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); - vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); - - amb_da += (da*da*0.5+0.5)*proj_ambiance; - - amb_da *= dist_atten * noise; - - amb_da = min(amb_da, 1.0-lit); - - col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; - } - - - vec4 spec = texture2DRect(specularRect, frag.xy); - if (spec.a > 0.0) - { - vec3 ref = reflect(normalize(pos), norm); - - //project from point pos in direction ref to plane proj_p, proj_n - vec3 pdelta = proj_p-pos; - float ds = dot(ref, proj_n); - - if (ds < 0.0) - { - vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; - - vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - - if (stc.z > 0.0) - { - stc.xy /= stc.w; - - if (stc.x < 1.0 && - stc.y < 1.0 && - stc.x > 0.0 && - stc.y > 0.0) - { - vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); - col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; - } - } - } - } - - //attenuate point light contribution by SSAO component - col *= texture2DRect(lightMap, frag.xy).g; - - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index d8ccfd4a8..52bad1f34 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -9,54 +9,33 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; +uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; uniform sampler2DRect lightMap; uniform sampler2D noiseMap; -uniform sampler2D lightFunc; -uniform sampler2DRect depthMap; uniform vec3 env_mat[3]; uniform float sun_wash; varying vec4 vary_light; -varying vec4 vary_fragcoord; +varying vec3 vary_fragcoord; uniform vec2 screen_res; -uniform mat4 inv_proj; -uniform vec4 viewport; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = (pos_screen.xy-viewport.xy)*2.0; - sc /= viewport.zw; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - void main() { - vec4 frag = vary_fragcoord; - frag.xyz /= frag.w; - frag.xyz = frag.xyz*0.5+0.5; - frag.xy *= screen_res; - - vec3 pos = getPosition(frag.xy).xyz; + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + frag *= screen_res; + vec3 pos = texture2DRect(positionMap, frag).xyz; vec3 lv = vary_light.xyz-pos; float dist2 = dot(lv,lv); - dist2 /= vary_light.w; - if (dist2 > 1.0) + if (dist2 > vary_light.w) { discard; } - vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + vec3 norm = texture2DRect(normalMap, frag).xyz; float da = dot(norm, lv); if (da < 0.0) { @@ -67,30 +46,24 @@ void main() lv = normalize(lv); da = dot(norm, lv); - float noise = texture2D(noiseMap, frag.xy/128.0).b; + float noise = texture2D(noiseMap, frag/128.0).b; - vec3 col = texture2DRect(diffuseRect, frag.xy).rgb; + vec3 col = texture2DRect(diffuseRect, frag).rgb; float fa = gl_Color.a+1.0; - float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-vary_light.w*(1.0-fa))/(vary_light.w*fa), 0.0, 1.0); float lit = da * dist_atten * noise; col = gl_Color.rgb*lit*col; - vec4 spec = texture2DRect(specularRect, frag.xy); + vec4 spec = texture2DRect(specularRect, frag); if (spec.a > 0.0) { - float sa = dot(normalize(lv-normalize(pos)),norm); - if (sa > 0.0) - { - sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*gl_Color.rgb*spec.rgb; - } - } - - if (dot(col, col) <= 0.0) - { - discard; + vec3 ref = reflect(normalize(pos), norm); + float sa = dot(ref,lv); + sa = max(sa, 0.0); + sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*gl_Color.rgb*spec.rgb; } //attenuate point light contribution by SSAO component diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index e815ca260..a4edb8825 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -6,7 +6,7 @@ */ varying vec4 vary_light; -varying vec4 vary_fragcoord; +varying vec3 vary_fragcoord; uniform vec2 screen_res; uniform float near_clip; @@ -14,10 +14,10 @@ uniform float near_clip; void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ftransform(); vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = pos; + vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); vec4 tex = gl_MultiTexCoord0; tex.w = 1.0; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl deleted file mode 100644 index 71de03663..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file postDeferredF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect localLightMap; -uniform sampler2DRect sunLightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D luminanceMap; -uniform sampler2DRect lightMap; - -uniform vec3 lum_quad; -uniform float lum_lod; -uniform vec4 ambient; - -uniform vec3 gi_quad; - -uniform vec2 screen_res; -varying vec2 vary_fragcoord; - -void main() -{ - vec2 tc = vary_fragcoord.xy; - vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - float luminance = lum.r; - luminance = luminance*lum_quad.y+lum_quad.z; - - vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); - - float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; - - vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; - gi_col *= diff; - - vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); - - vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; - - - sun_col *= 1.0/min(luminance, 1.0); - gi_col *= 1.0/luminance; - - vec3 col = sun_col.rgb+gi_col+local_col; - - gl_FragColor.rgb = col.rgb; - col.rgb = max(col.rgb-vec3(1.0,1.0,1.0), vec3(0.0, 0.0, 0.0)); - - gl_FragColor.a = 0.0; // max(dot(col.rgb,col.rgb)*lum_quad.x, sun_col.a); - - //gl_FragColor.rgb = vec3(lum_lod); -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl deleted file mode 100644 index 9819232fd..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file postDeferredV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl deleted file mode 100644 index 3556c7bb5..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file postgiF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2D diffuseGIMap; -uniform sampler2D normalGIMap; -uniform sampler2D depthGIMap; -uniform sampler2D diffuseMap; - -uniform sampler2D lastDiffuseGIMap; -uniform sampler2D lastNormalGIMap; -uniform sampler2D lastMinpGIMap; -uniform sampler2D lastMaxpGIMap; - -uniform float gi_blend; - -uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space -uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space -uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix -uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space -uniform float gi_radius; -uniform float gi_intensity; -uniform vec2 gi_kern[16]; -uniform vec2 gi_scale; - - -vec4 getGIPosition(vec2 gi_tc) -{ - float depth = texture2D(depthGIMap, gi_tc).a; - vec2 sc = gi_tc*2.0; - sc -= vec2(1.0, 1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = gi_inv_proj*ndc; - pos.xyz /= pos.w; - pos.w = 1.0; - return pos; -} - - -void main() -{ - vec2 c_tc = gl_TexCoord[0].xy; - - vec3 diff = vec3(0,0,0); - vec3 minp = vec3(1024,1024,1024); - vec3 maxp = vec3(-1024,-1024,-1024); - vec3 norm = vec3(0,0,0); - - float dweight = 0.0; - - vec3 cnorm = normalize(texture2D(normalGIMap, c_tc).rgb*2.0-1.0); - - vec3 cpos = vec3(0,0,0); - float tweight = 0.0; - - for (int i = 0; i < 8; ++i) - { - for (int j = 0; j < 8; ++j) - { - vec2 tc = vec2(i-4+0.5, j-4+0.5); - float weight = 1.0-length(tc)/6.0; - tc *= 1.0/(256.0); - tc += c_tc; - - vec3 n = texture2D(normalGIMap, tc).rgb*2.0-1.0; - tweight += weight; - - diff += weight*texture2D(diffuseGIMap, tc).rgb; - - norm += n*weight; - - dweight += dot(n, cnorm); - - vec3 pos = getGIPosition(tc).xyz; - cpos += pos*weight; - - minp = min(pos, minp); - maxp = max(pos, maxp); - } - } - - dweight = abs(1.0-dweight/64.0); - float mind = min(sqrt(dweight+0.5), 1.0); - - dweight *= dweight; - - cpos /= tweight; - - diff = clamp(diff/tweight, vec3(1.0/2.2), vec3(1,1,1)); - norm = normalize(norm); - maxp = cpos; - minp = vec3(dweight, mind, cpos.z-minp.z); - - //float blend = 1.0; - //diff = mix(texture2D(lastDiffuseGIMap, c_tc).rgb, diff, blend); - //norm = mix(texture2D(lastNormalGIMap, c_tc).rgb, norm, blend); - //maxp = mix(texture2D(lastMaxpGIMap, c_tc).rgb, maxp, blend); - //minp = mix(texture2D(lastMinpGIMap, c_tc).rgb, minp, blend); - - gl_FragData[0].rgb = diff; - gl_FragData[2].xyz = normalize(norm); - gl_FragData[1].xyz = maxp; - gl_FragData[3].xyz = minp; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl deleted file mode 100644 index 5a8eb658e..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @file postgiV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec3 vary_normal; - -void main() -{ - //transform vertex - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_Position = pos; - gl_TexCoord[0].xy = pos.xy*0.5+0.5; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index b0b31fd4b..b3758c363 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -7,11 +7,8 @@ uniform sampler2D diffuseMap; -varying vec4 post_pos; void main() { gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a); - - gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index 7214d246a..aae1beeae 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -5,17 +5,13 @@ * $License$ */ -varying vec4 post_pos; - void main() { //transform vertex vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex; - - post_pos = pos; - - gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); - + //smash geometry against the near clip plane (great for ortho projections) + pos.z = max(pos.z, -1.0); + gl_Position = pos; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_FrontColor = gl_Color; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 64e263ada..d5671a6ce 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -272,4 +272,8 @@ void main() gl_FragColor.rgb = col; gl_FragColor.a = 0.0; + //gl_FragColor.rg = scol_ambocc.rg; + //gl_FragColor.rgb = norm.rgb*0.5+0.5; + //gl_FragColor.rgb = vec3(ambocc); + //gl_FragColor.rgb = vec3(scol); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl deleted file mode 100644 index d6534083c..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @file spotLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#version 120 - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform sampler2D lightFunc; -uniform sampler2D projectionMap; - -uniform mat4 proj_mat; //screen space to light space -uniform float proj_near; //near clip for projection -uniform vec3 proj_p; //plane projection is emitting from (in screen space) -uniform vec3 proj_n; -uniform float proj_focus; //distance from plane to begin blurring -uniform float proj_lod; //(number of mips in proj map) -uniform float proj_range; //range between near clip and far clip plane of projection -uniform float proj_ambiance; -uniform float near_clip; -uniform float far_clip; - -uniform vec3 proj_origin; //origin of projection to be used for angular attenuation -uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade; - -varying vec4 vary_light; - -varying vec4 vary_fragcoord; -uniform vec2 screen_res; - -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -void main() -{ - vec4 frag = vary_fragcoord; - frag.xyz /= frag.w; - frag.xyz = frag.xyz*0.5+0.5; - frag.xy *= screen_res; - - float shadow = 1.0; - - if (proj_shadow_idx >= 0) - { - vec4 shd = texture2DRect(lightMap, frag.xy); - float sh[2]; - sh[0] = shd.b; - sh[1] = shd.a; - shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); - } - - vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = vary_light.xyz-pos.xyz; - float dist2 = dot(lv,lv); - dist2 /= vary_light.w; - if (dist2 > 1.0) - { - discard; - } - - vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; - - norm = normalize(norm); - float l_dist = -dot(lv, proj_n); - - vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); - if (proj_tc.z < 0.0) - { - discard; - } - - proj_tc.xyz /= proj_tc.w; - - float fa = gl_Color.a+1.0; - float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); - - lv = proj_origin-pos.xyz; - lv = normalize(lv); - float da = dot(norm, lv); - - vec3 col = vec3(0,0,0); - - vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; - - float noise = texture2D(noiseMap, frag.xy/128.0).b; - if (proj_tc.z > 0.0 && - proj_tc.x < 1.0 && - proj_tc.y < 1.0 && - proj_tc.x > 0.0 && - proj_tc.y > 0.0) - { - float lit = 0.0; - if (da > 0.0) - { - float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - - vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - - vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; - - lit = da * dist_atten * noise; - - col = lcol*lit*diff_tex*shadow; - } - - float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); - float amb_da = proj_ambiance; - if (da > 0.0) - { - amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; - } - - amb_da += (da*da*0.5+0.5)*proj_ambiance; - - amb_da *= dist_atten * noise; - - amb_da = min(amb_da, 1.0-lit); - - col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; - } - - - vec4 spec = texture2DRect(specularRect, frag.xy); - if (spec.a > 0.0) - { - vec3 ref = reflect(normalize(pos), norm); - - //project from point pos in direction ref to plane proj_p, proj_n - vec3 pdelta = proj_p-pos; - float ds = dot(ref, proj_n); - - if (ds < 0.0) - { - vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; - - vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; - - if (stc.z > 0.0) - { - stc.xy /= stc.z+proj_near; - - if (stc.x < 1.0 && - stc.y < 1.0 && - stc.x > 0.0 && - stc.y > 0.0) - { - vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); - col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; - } - } - } - } - - /*if (spec.a > 0.0) - { - //vec3 ref = reflect(normalize(pos), norm); - float sa = dot(normalize(lv-normalize(pos)),norm);; - //sa = max(sa, 0.0); - //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*lcol*spec.rgb; - }*/ - - //attenuate point light contribution by SSAO component - col *= texture2DRect(lightMap, frag.xy).g; - - - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index 22bdd2c7f..d43fe6ca9 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -7,21 +7,17 @@ #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect depthMap; +uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2DRectShadow shadowMap4; -uniform sampler2DRectShadow shadowMap5; +uniform sampler2DRect depthMap; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform sampler2D lightFunc; - - // Inputs -uniform mat4 shadow_matrix[6]; +uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; uniform float ssao_radius; uniform float ssao_max_radius; @@ -31,25 +27,6 @@ uniform float ssao_factor_inv; varying vec2 vary_fragcoord; varying vec4 vary_light; -uniform mat4 inv_proj; -uniform vec2 screen_res; - -uniform float shadow_bias; -uniform float shadow_offset; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - //calculate decreases in ambient lighting when crowded out (SSAO) float calcAmbientOcclusion(vec4 pos, vec3 norm) { @@ -77,7 +54,7 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) for (int i = 0; i < 8; i++) { vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = getPosition(samppos_screen).xyz; + vec3 samppos_world = texture2DRect(positionMap, samppos_screen).xyz; vec3 diff = pos_world - samppos_world; float dist2 = dot(diff, diff); @@ -97,18 +74,14 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - return (1.0 - (float(points != 0) * angle_hidden)); + return 1.0 - (float(points != 0) * angle_hidden); } void main() { vec2 pos_screen = vary_fragcoord.xy; - - //try doing an unproject here - - vec4 pos = getPosition(pos_screen); - - vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; + vec4 pos = vec4(texture2DRect(positionMap, pos_screen).xyz, 1.0); + vec3 norm = texture2DRect(normalMap, pos_screen).xyz; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL { @@ -117,45 +90,35 @@ void main() }*/ float shadow = 1.0; - float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); - vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); - - //vec3 debug = vec3(0,0,0); - if (dp_directional_light == 0.0) { // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup shadow = 0.0; } - else if (spos.z > -shadow_clip.w) + else if (pos.z > -shadow_clip.w) { - vec4 lpos; - - if (spos.z < -shadow_clip.z) + if (pos.z < -shadow_clip.z) { - lpos = shadow_matrix[3]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap3, lpos).x; + vec4 lpos = shadow_matrix[3]*pos; + shadow = shadow2DProj(shadowMap3, lpos).x; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (spos.z < -shadow_clip.y) + else if (pos.z < -shadow_clip.y) { - lpos = shadow_matrix[2]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap2, lpos).x; + vec4 lpos = shadow_matrix[2]*pos; + shadow = shadow2DProj(shadowMap2, lpos).x; } - else if (spos.z < -shadow_clip.x) + else if (pos.z < -shadow_clip.x) { - lpos = shadow_matrix[1]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap1, lpos).x; + vec4 lpos = shadow_matrix[1]*pos; + shadow = shadow2DProj(shadowMap1, lpos).x; } else { - lpos = shadow_matrix[0]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap0, lpos).x; + vec4 lpos = shadow_matrix[0]*pos; + shadow = shadow2DProj(shadowMap0, lpos).x; } // take the most-shadowed value out of these two: @@ -163,17 +126,6 @@ void main() // * an unblurred dot product between the sun and this norm // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting shadow = min(shadow, dp_directional_light); - - /*debug.r = lpos.y / (lpos.w*screen_res.y); - - lpos.xy /= lpos.w*32.0; - if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) - { - debug.gb = vec2(0.5, 0.5); - } - - debug += (1.0-shadow)*0.5;*/ - } else { @@ -183,18 +135,5 @@ void main() gl_FragColor[0] = shadow; gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - - //spotlight shadow 1 - vec4 lpos = shadow_matrix[4]*spos; - lpos.xy *= screen_res; - gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x; - - //spotlight shadow 2 - lpos = shadow_matrix[5]*spos; - lpos.xy *= screen_res; - gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x; - - //gl_FragColor.rgb = pos.xyz; - //gl_FragColor.b = shadow; - //gl_FragColor.rgb = debug; + //gl_FragColor[2] is unused as of August 2008, may be used for debugging } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 308b9b1fd..211b2e039 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -12,6 +12,7 @@ uniform sampler2D detail_3; uniform sampler2D alpha_ramp; varying vec3 vary_normal; +varying vec4 vary_position; void main() { @@ -27,8 +28,9 @@ void main() float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a; vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); - gl_FragData[0] = vec4(outColor.rgb, 0.0); // Kl 0.0 looks fine atm however check grass above waterline when GI enabled in future releases! + gl_FragData[0] = vec4(outColor.rgb, 1.0); gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); - gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); + gl_FragData[2] = vec4(normalize(vary_normal), 0.0); + gl_FragData[3] = vary_position; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index 3038b1477..e9d6dcabf 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -6,6 +6,7 @@ */ varying vec3 vary_normal; +varying vec4 vary_position; vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) { @@ -26,6 +27,7 @@ void main() //transform vertex gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_position = gl_ModelViewMatrix * gl_Vertex; vary_normal = normalize(gl_NormalMatrix * gl_Normal); // Transform and pass tex coords diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 49c65f117..bc2c9816d 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -8,11 +8,13 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; +varying vec4 vary_position; void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragData[0] = gl_Color*col; gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); + gl_FragData[2] = vec4(normalize(vary_normal), 0.0); + gl_FragData[3] = vary_position; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index 6b9dc2def..9131d7c2b 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -6,6 +6,7 @@ */ varying vec3 vary_normal; +varying vec4 vary_position; void main() { @@ -13,6 +14,8 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + vary_position = gl_ModelViewMatrix * gl_Vertex; + vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 6eea65633..0a1f019e3 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -17,7 +17,7 @@ uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[6]; +uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; uniform float sunAngle; diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl deleted file mode 100644 index 623ef7a81..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file colorFilterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect RenderTexture; -uniform float brightness; -uniform float contrast; -uniform vec3 contrastBase; -uniform float saturation; -uniform vec3 lumWeights; - -const float gamma = 2.0; - -void main(void) -{ - vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); - - /// Modulate brightness - color *= brightness; - - /// Modulate contrast - color = mix(contrastBase, color, contrast); - - /// Modulate saturation - color = mix(vec3(dot(color, lumWeights)), color, saturation); - - gl_FragColor = vec4(color, 1.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl deleted file mode 100644 index 29c2a0948..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @file drawQuadV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -void main(void) -{ - //transform vertex - gl_Position = ftransform(); - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_TexCoord[1] = gl_MultiTexCoord1; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl deleted file mode 100644 index 271d5cf8d..000000000 --- a/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file nightVisionF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect RenderTexture; -uniform sampler2D NoiseTexture; -uniform float brightMult; -uniform float noiseStrength; - -float luminance(vec3 color) -{ - /// CALCULATING LUMINANCE (Using NTSC lum weights) - /// http://en.wikipedia.org/wiki/Luma_%28video%29 - return dot(color, vec3(0.299, 0.587, 0.114)); -} - -void main(void) -{ - /// Get scene color - vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); - - /// Extract luminance and scale up by night vision brightness - float lum = luminance(color) * brightMult; - - /// Convert into night vision color space - /// Newer NVG colors (crisper and more saturated) - vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); - - /// Add noise - float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r; - noiseValue = (noiseValue - 0.5) * noiseStrength; - - /// Older NVG colors (more muted) - // vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); - - outColor += noiseValue; - - gl_FragColor = vec4(outColor, 1.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl deleted file mode 100644 index 0055a736c..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file alphaF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2D diffuseMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2D noiseMap; -uniform sampler2DRect depthMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform vec2 screen_res; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_fragcoord; -varying vec3 vary_position; -varying vec3 vary_light; - -uniform float alpha_soften; - -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -void main() -{ - vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; - frag *= screen_res; - - vec3 samp_pos = getPosition(frag).xyz; - - float shadow = 1.0; - vec4 pos = vec4(vary_position, 1.0); - - vec4 spos = pos; - - if (spos.z > -shadow_clip.w) - { - vec4 lpos; - - if (spos.z < -shadow_clip.z) - { - lpos = shadow_matrix[3]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap3, lpos).x; - shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); - } - else if (spos.z < -shadow_clip.y) - { - lpos = shadow_matrix[2]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap2, lpos).x; - } - else if (spos.z < -shadow_clip.x) - { - lpos = shadow_matrix[1]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap1, lpos).x; - } - else - { - lpos = shadow_matrix[0]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap0, lpos).x; - } - } - - vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; - - color.rgb = atmosLighting(color.rgb); - - color.rgb = scaleSoftClip(color.rgb); - - if (samp_pos.z != 0.0) - { - float dist_factor = alpha_soften; - float a = gl_Color.a; - a *= a; - dist_factor *= 1.0/(1.0-a); - color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); - } - - //gl_FragColor = gl_Color; - gl_FragColor = color; - //gl_FragColor = vec4(1,0,1,1)*shadow; - -} - diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl deleted file mode 100644 index ab60b6512..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file alphaV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void calcAtmospherics(vec3 inPositionEye); - -float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); - -vec3 atmosAmbient(vec3 light); -vec3 atmosAffectDirectionalLight(float lightIntensity); -vec3 scaleDownLight(vec3 light); -vec3 scaleUpLight(vec3 light); - -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_fragcoord; -varying vec3 vary_position; -varying vec3 vary_light; - -uniform float near_clip; -uniform float shadow_offset; -uniform float shadow_bias; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - - vec4 pos = (gl_ModelViewMatrix * gl_Vertex); - vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - - vary_position = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); - - calcAtmospherics(pos.xyz); - - //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); - vec4 col; - col.a = gl_Color.a; - - // Add windlight lights - col.rgb = atmosAmbient(vec3(0.)); - col.rgb = scaleUpLight(col.rgb); - - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); - - vary_light = gl_LightSource[0].position.xyz; - - vary_ambient = col.rgb*gl_Color.rgb; - vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); - - col.rgb = min(col.rgb*gl_Color.rgb, 1.0); - - gl_FrontColor = col; - - gl_FogFragCoord = pos.z; - - pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); - -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl deleted file mode 100644 index fe83c3c10..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file avatarAlphaF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2D diffuseMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2D noiseMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform vec2 screen_res; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec4 vary_position; -varying vec3 vary_normal; - -void main() -{ - float shadow = 1.0; - vec4 pos = vary_position; - vec3 norm = normalize(vary_normal); - - vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - - vec4 spos = pos; - - if (spos.z > -shadow_clip.w) - { - vec4 lpos; - - if (spos.z < -shadow_clip.z) - { - lpos = shadow_matrix[3]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap3, lpos).x; - shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); - } - else if (spos.z < -shadow_clip.y) - { - lpos = shadow_matrix[2]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap2, lpos).x; - } - else if (spos.z < -shadow_clip.x) - { - lpos = shadow_matrix[1]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap1, lpos).x; - } - else - { - lpos = shadow_matrix[0]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap0, lpos).x; - } - } - - - vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; - - color.rgb = atmosLighting(color.rgb); - - color.rgb = scaleSoftClip(color.rgb); - - gl_FragColor = color; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl deleted file mode 100644 index c1988d3c7..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file avatarAlphaV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -mat4 getSkinnedTransform(); -void calcAtmospherics(vec3 inPositionEye); - -float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); - -vec3 atmosAmbient(vec3 light); -vec3 atmosAffectDirectionalLight(float lightIntensity); -vec3 scaleDownLight(vec3 light); -vec3 scaleUpLight(vec3 light); - -varying vec4 vary_position; -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_normal; - -void main() -{ - gl_TexCoord[0] = gl_MultiTexCoord0; - - vec4 pos; - vec3 norm; - - mat4 trans = getSkinnedTransform(); - pos.x = dot(trans[0], gl_Vertex); - pos.y = dot(trans[1], gl_Vertex); - pos.z = dot(trans[2], gl_Vertex); - pos.w = 1.0; - - norm.x = dot(trans[0].xyz, gl_Normal); - norm.y = dot(trans[1].xyz, gl_Normal); - norm.z = dot(trans[2].xyz, gl_Normal); - norm = normalize(norm); - - gl_Position = gl_ProjectionMatrix * pos; - vary_position = pos; - vary_normal = norm; - - calcAtmospherics(pos.xyz); - - //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); - vec4 col; - col.a = gl_Color.a; - - // Add windlight lights - col.rgb = atmosAmbient(vec3(0.)); - col.rgb = scaleUpLight(col.rgb); - - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); - - vary_ambient = col.rgb*gl_Color.rgb; - vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); - - col.rgb = min(col.rgb*gl_Color.rgb, 1.0); - - gl_FrontColor = col; - - gl_FogFragCoord = pos.z; - -} - - diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl deleted file mode 100644 index 1713fe99f..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file blurLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; - -uniform float dist_factor; -uniform float blur_size; -uniform vec2 delta; -uniform vec3 kern[32]; -uniform int kern_length; -uniform float kern_scale; - -varying vec2 vary_fragcoord; - -uniform mat4 inv_proj; -uniform vec2 screen_res; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -void main() -{ - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; - vec3 pos = getPosition(vary_fragcoord.xy).xyz; - vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; - - vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); - - dlt /= max(-pos.z*dist_factor, 1.0); - - vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' - vec4 col = defined_weight.xyxx * ccol; - - for (int i = 1; i < kern_length; i++) - { - vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; - float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) - { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; - defined_weight += kern[i].xy; - } - } - - - - col /= defined_weight.xyxx; - - gl_FragColor = col; - - //gl_FragColor = ccol; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl deleted file mode 100644 index b7f07e570..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file blurLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl deleted file mode 100644 index 651959413..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ /dev/null @@ -1,188 +0,0 @@ -/** - * @file multiSpotLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#version 120 - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform sampler2D lightFunc; -uniform sampler2D projectionMap; - -uniform mat4 proj_mat; //screen space to light space -uniform float proj_near; //near clip for projection -uniform vec3 proj_p; //plane projection is emitting from (in screen space) -uniform vec3 proj_n; -uniform float proj_focus; //distance from plane to begin blurring -uniform float proj_lod; //(number of mips in proj map) -uniform float proj_range; //range between near clip and far clip plane of projection -uniform float proj_ambient_lod; -uniform float proj_ambiance; -uniform float near_clip; -uniform float far_clip; - -uniform vec3 proj_origin; //origin of projection to be used for angular attenuation -uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade; - -varying vec4 vary_light; - -varying vec4 vary_fragcoord; -uniform vec2 screen_res; - -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -void main() -{ - vec4 frag = vary_fragcoord; - frag.xyz /= frag.w; - frag.xyz = frag.xyz*0.5+0.5; - frag.xy *= screen_res; - - vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = vary_light.xyz-pos.xyz; - float dist2 = dot(lv,lv); - dist2 /= vary_light.w; - if (dist2 > 1.0) - { - discard; - } - - float shadow = 1.0; - - if (proj_shadow_idx >= 0) - { - vec4 shd = texture2DRect(lightMap, frag.xy); - float sh[2]; - sh[0] = shd.b; - sh[1] = shd.a; - shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); - } - - vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; - - norm = normalize(norm); - float l_dist = -dot(lv, proj_n); - - vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); - if (proj_tc.z < 0.0) - { - discard; - } - - proj_tc.xyz /= proj_tc.w; - - float fa = gl_Color.a+1.0; - float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); - if (dist_atten <= 0.0) - { - discard; - } - - lv = proj_origin-pos.xyz; - lv = normalize(lv); - float da = dot(norm, lv); - - vec3 col = vec3(0,0,0); - - vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; - - float noise = texture2D(noiseMap, frag.xy/128.0).b; - if (proj_tc.z > 0.0 && - proj_tc.x < 1.0 && - proj_tc.y < 1.0 && - proj_tc.x > 0.0 && - proj_tc.y > 0.0) - { - float lit = 0.0; - float amb_da = proj_ambiance; - - if (da > 0.0) - { - float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - - vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - - vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; - - lit = da * dist_atten * noise; - - col = lcol*lit*diff_tex*shadow; - amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; - } - - //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); - vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); - - amb_da += (da*da*0.5+0.5)*proj_ambiance; - - amb_da *= dist_atten * noise; - - amb_da = min(amb_da, 1.0-lit); - - col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; - } - - - vec4 spec = texture2DRect(specularRect, frag.xy); - if (spec.a > 0.0) - { - vec3 ref = reflect(normalize(pos), norm); - - //project from point pos in direction ref to plane proj_p, proj_n - vec3 pdelta = proj_p-pos; - float ds = dot(ref, proj_n); - - if (ds < 0.0) - { - vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; - - vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); - - if (stc.z > 0.0) - { - stc.xy /= stc.w; - - if (stc.x < 1.0 && - stc.y < 1.0 && - stc.x > 0.0 && - stc.y > 0.0) - { - vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); - col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; - } - } - } - } - - //attenuate point light contribution by SSAO component - col *= texture2DRect(lightMap, frag.xy).g; - - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl deleted file mode 100644 index ee0e9d636..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file postDeferredF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect localLightMap; -uniform sampler2DRect sunLightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D luminanceMap; -uniform sampler2DRect lightMap; - -uniform vec3 gi_lum_quad; -uniform vec3 sun_lum_quad; -uniform vec3 lum_quad; -uniform float lum_lod; -uniform vec4 ambient; - -uniform vec3 gi_quad; - -uniform vec2 screen_res; -varying vec2 vary_fragcoord; - -void main() -{ - vec2 tc = vary_fragcoord.xy; - vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - - float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; - - vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); - - float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; - - vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; - gi_col *= diff; - - vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); - - vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; - - - float sun_lum = 1.0-lum; - sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; - - float gi_lum = lum; - gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; - gi_col *= 1.0/gi_lum; - - vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; - - gl_FragColor.rgb = col.rgb; - gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); - - //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl deleted file mode 100644 index 9819232fd..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file postDeferredV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl deleted file mode 100644 index 52b79e3de..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ /dev/null @@ -1,294 +0,0 @@ -/** - * @file softenLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform samplerCube environmentMap; -uniform sampler2D lightFunc; -uniform vec3 gi_quad; - -uniform float blur_size; -uniform float blur_fidelity; - -// Inputs -uniform vec4 morphFactor; -uniform vec3 camPosLocal; -//uniform vec4 camPosWorld; -uniform vec4 gamma; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 ambient; -uniform vec4 blue_horizon; -uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 distance_multiplier; -uniform vec4 max_y; -uniform vec4 glow; -uniform float scene_light_strength; -uniform vec3 env_mat[3]; -uniform vec4 shadow_clip; -uniform mat3 ssao_effect_mat; - -uniform sampler2DRect depthMap; -uniform mat4 inv_proj; -uniform vec2 screen_res; - -varying vec4 vary_light; -varying vec2 vary_fragcoord; - -vec3 vary_PositionEye; - -vec3 vary_SunlitColor; -vec3 vary_AmblitColor; -vec3 vary_AdditiveColor; -vec3 vary_AtmosAttenuation; - -vec4 getPosition(vec2 pos_screen) -{ //get position in screen space (world units) given window coordinate and depth map - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -vec3 getPositionEye() -{ - return vary_PositionEye; -} -vec3 getSunlitColor() -{ - return vary_SunlitColor; -} -vec3 getAmblitColor() -{ - return vary_AmblitColor; -} -vec3 getAdditiveColor() -{ - return vary_AdditiveColor; -} -vec3 getAtmosAttenuation() -{ - return vary_AtmosAttenuation; -} - - -void setPositionEye(vec3 v) -{ - vary_PositionEye = v; -} - -void setSunlitColor(vec3 v) -{ - vary_SunlitColor = v; -} - -void setAmblitColor(vec3 v) -{ - vary_AmblitColor = v; -} - -void setAdditiveColor(vec3 v) -{ - vary_AdditiveColor = v; -} - -void setAtmosAttenuation(vec3 v) -{ - vary_AtmosAttenuation = v; -} - -void calcAtmospherics(vec3 inPositionEye, float ambFactor) { - - vec3 P = inPositionEye; - setPositionEye(P); - - //(TERRAIN) limit altitude - if (P.y > max_y.x) P *= (max_y.x / P.y); - if (P.y < -max_y.x) P *= (-max_y.x / P.y); - - vec3 tmpLightnorm = lightnorm.xyz; - - vec3 Pn = normalize(P); - float Plen = length(P); - - vec4 temp1 = vec4(0); - vec3 temp2 = vec3(0); - vec4 blue_weight; - vec4 haze_weight; - vec4 sunlight = sunlight_color; - vec4 light_atten; - - //sunlight attenuation effect (hue and brightness) due to atmosphere - //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); - //I had thought blue_density and haze_density should have equal weighting, - //but attenuation due to haze_density tends to seem too strong - - temp1 = blue_density + vec4(haze_density.r); - blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density.r) / temp1; - - //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) - temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; - sunlight *= exp( - light_atten * temp2.y); - - // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier.x; - - // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati - // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); - - //final atmosphere attenuation factor - setAtmosAttenuation(temp1.rgb); - - //compute haze glow - //(can use temp2.x as temp because we haven't used it yet) - temp2.x = dot(Pn, tmpLightnorm.xyz); - temp2.x = 1. - temp2.x; - //temp2.x is 0 at the sun and increases away from sun - temp2.x = max(temp2.x, .03); //was glow.y - //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; - //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z); - //glow.z should be negative, so we're doing a sort of (1 / "angle") function - - //add "minimum anti-solar illumination" - temp2.x += .25; - - //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; - - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - - //haze color - setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x - + tmpAmbient))); - - //brightness of surface both sunlight and ambient - setSunlitColor(vec3(sunlight * .5)); - setAmblitColor(vec3(tmpAmbient * .25)); - setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); -} - -vec3 atmosLighting(vec3 light) -{ - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); - return (2.0 * light); -} - -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; - return light; -} -vec3 atmosGetDiffuseSunlightColor() -{ - return getSunlitColor(); -} - -vec3 scaleDownLight(vec3 light) -{ - return (light / scene_light_strength ); -} - -vec3 scaleUpLight(vec3 light) -{ - return (light * scene_light_strength); -} - -vec3 atmosAmbient(vec3 light) -{ - return getAmblitColor() + light / 2.0; -} - -vec3 atmosAffectDirectionalLight(float lightIntensity) -{ - return getSunlitColor() * lightIntensity; -} - -vec3 scaleSoftClip(vec3 light) -{ - //soft clip effect: - light = 1. - clamp(light, vec3(0.), vec3(1.)); - light = 1. - pow(light, gamma.xxx); - - return light; -} - -void main() -{ - vec2 tc = vary_fragcoord.xy; - vec3 pos = getPosition(tc).xyz; - vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; - vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; - - float da = max(dot(norm.xyz, vary_light.xyz), 0.0); - - vec4 diffuse = texture2DRect(diffuseRect, tc); - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - - vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; - float scol = max(scol_ambocc.r, diffuse.a); - float ambocc = scol_ambocc.g; - - calcAtmospherics(pos.xyz, ambocc); - - vec3 col = atmosAmbient(vec3(0)); - col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); - - col *= diffuse.rgb; - - if (spec.a > 0.0) - { - vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); - float sa = dot(ref, vary_light.xyz); - col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; - } - - col = atmosLighting(col); - col = scaleSoftClip(col); - - gl_FragColor.rgb = col; - - //gl_FragColor.rgb = gi_col.rgb; - gl_FragColor.a = 0.0; - - //gl_FragColor.rg = scol_ambocc.rg; - //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; - //gl_FragColor.rgb = norm.rgb*0.5+0.5; - //gl_FragColor.rgb = vec3(ambocc); - //gl_FragColor.rgb = vec3(scol); -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl deleted file mode 100644 index ad8af4780..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @file softenLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform vec2 screen_res; - -varying vec4 vary_light; -varying vec2 vary_fragcoord; -void main() -{ - //transform vertex - gl_Position = ftransform(); - - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; - - vec4 tex = gl_MultiTexCoord0; - tex.w = 1.0; - - vary_light = gl_MultiTexCoord0; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl deleted file mode 100644 index d6534083c..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @file spotLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#version 120 - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; -uniform sampler2D noiseMap; -uniform sampler2D lightFunc; -uniform sampler2D projectionMap; - -uniform mat4 proj_mat; //screen space to light space -uniform float proj_near; //near clip for projection -uniform vec3 proj_p; //plane projection is emitting from (in screen space) -uniform vec3 proj_n; -uniform float proj_focus; //distance from plane to begin blurring -uniform float proj_lod; //(number of mips in proj map) -uniform float proj_range; //range between near clip and far clip plane of projection -uniform float proj_ambiance; -uniform float near_clip; -uniform float far_clip; - -uniform vec3 proj_origin; //origin of projection to be used for angular attenuation -uniform float sun_wash; -uniform int proj_shadow_idx; -uniform float shadow_fade; - -varying vec4 vary_light; - -varying vec4 vary_fragcoord; -uniform vec2 screen_res; - -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -void main() -{ - vec4 frag = vary_fragcoord; - frag.xyz /= frag.w; - frag.xyz = frag.xyz*0.5+0.5; - frag.xy *= screen_res; - - float shadow = 1.0; - - if (proj_shadow_idx >= 0) - { - vec4 shd = texture2DRect(lightMap, frag.xy); - float sh[2]; - sh[0] = shd.b; - sh[1] = shd.a; - shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); - } - - vec3 pos = getPosition(frag.xy).xyz; - vec3 lv = vary_light.xyz-pos.xyz; - float dist2 = dot(lv,lv); - dist2 /= vary_light.w; - if (dist2 > 1.0) - { - discard; - } - - vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; - - norm = normalize(norm); - float l_dist = -dot(lv, proj_n); - - vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); - if (proj_tc.z < 0.0) - { - discard; - } - - proj_tc.xyz /= proj_tc.w; - - float fa = gl_Color.a+1.0; - float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); - - lv = proj_origin-pos.xyz; - lv = normalize(lv); - float da = dot(norm, lv); - - vec3 col = vec3(0,0,0); - - vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; - - float noise = texture2D(noiseMap, frag.xy/128.0).b; - if (proj_tc.z > 0.0 && - proj_tc.x < 1.0 && - proj_tc.y < 1.0 && - proj_tc.x > 0.0 && - proj_tc.y > 0.0) - { - float lit = 0.0; - if (da > 0.0) - { - float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - - vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - - vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; - - lit = da * dist_atten * noise; - - col = lcol*lit*diff_tex*shadow; - } - - float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); - float lod = diff * proj_lod; - vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); - //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); - float amb_da = proj_ambiance; - if (da > 0.0) - { - amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; - } - - amb_da += (da*da*0.5+0.5)*proj_ambiance; - - amb_da *= dist_atten * noise; - - amb_da = min(amb_da, 1.0-lit); - - col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; - } - - - vec4 spec = texture2DRect(specularRect, frag.xy); - if (spec.a > 0.0) - { - vec3 ref = reflect(normalize(pos), norm); - - //project from point pos in direction ref to plane proj_p, proj_n - vec3 pdelta = proj_p-pos; - float ds = dot(ref, proj_n); - - if (ds < 0.0) - { - vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; - - vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; - - if (stc.z > 0.0) - { - stc.xy /= stc.z+proj_near; - - if (stc.x < 1.0 && - stc.y < 1.0 && - stc.x > 0.0 && - stc.y > 0.0) - { - vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); - col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; - } - } - } - } - - /*if (spec.a > 0.0) - { - //vec3 ref = reflect(normalize(pos), norm); - float sa = dot(normalize(lv-normalize(pos)),norm);; - //sa = max(sa, 0.0); - //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*lcol*spec.rgb; - }*/ - - //attenuate point light contribution by SSAO component - col *= texture2DRect(lightMap, frag.xy).g; - - - gl_FragColor.rgb = col; - gl_FragColor.a = 0.0; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl deleted file mode 100644 index 8ced94ee0..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @file sunLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2DRectShadow shadowMap4; -uniform sampler2DRectShadow shadowMap5; -uniform sampler2D noiseMap; - -uniform sampler2D lightFunc; - - -// Inputs -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform float ssao_radius; -uniform float ssao_max_radius; -uniform float ssao_factor; -uniform float ssao_factor_inv; - -varying vec2 vary_fragcoord; -varying vec4 vary_light; - -uniform mat4 inv_proj; -uniform vec2 screen_res; - -uniform float shadow_bias; -uniform float shadow_offset; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -//calculate decreases in ambient lighting when crowded out (SSAO) -float calcAmbientOcclusion(vec4 pos, vec3 norm) -{ - vec2 kern[8]; - // exponentially (^2) distant occlusion samples spread around origin - kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; - kern[1] = vec2(1.0, 0.0) * 0.250*0.250; - kern[2] = vec2(0.0, 1.0) * 0.375*0.375; - kern[3] = vec2(0.0, -1.0) * 0.500*0.500; - kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; - kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; - kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; - kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; - - vec2 pos_screen = vary_fragcoord.xy; - vec3 pos_world = pos.xyz; - vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; - - float angle_hidden = 0.0; - int points = 0; - - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); - - // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) - for (int i = 0; i < 8; i++) - { - vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = getPosition(samppos_screen).xyz; - - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); - - // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area - // --> solid angle shrinking by the square of distance - //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 - //(k should vary inversely with # of samples, but this is taken care of later) - - //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces - // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); - - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); - } - - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - - return (1.0 - (float(points != 0) * angle_hidden)); -} - -void main() -{ - vec2 pos_screen = vary_fragcoord.xy; - - //try doing an unproject here - - vec4 pos = getPosition(pos_screen); - - vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; - - /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL - { - gl_FragColor = vec4(0.0); // doesn't matter - return; - }*/ - - float shadow = 1.0; - float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); - - vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); - - //vec3 debug = vec3(0,0,0); - - if (spos.z > -shadow_clip.w) - { - if (dp_directional_light == 0.0) - { - // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup - shadow = 0.0; - } - else - { - vec4 lpos; - - if (spos.z < -shadow_clip.z) - { - lpos = shadow_matrix[3]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap3, lpos).x; - shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); - } - else if (spos.z < -shadow_clip.y) - { - lpos = shadow_matrix[2]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap2, lpos).x; - } - else if (spos.z < -shadow_clip.x) - { - lpos = shadow_matrix[1]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap1, lpos).x; - } - else - { - lpos = shadow_matrix[0]*spos; - lpos.xy *= screen_res; - shadow = shadow2DRectProj(shadowMap0, lpos).x; - } - - // take the most-shadowed value out of these two: - // * the blurred sun shadow in the light (shadow) map - // * an unblurred dot product between the sun and this norm - // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting - shadow = min(shadow, dp_directional_light); - } - - /*debug.r = lpos.y / (lpos.w*screen_res.y); - - lpos.xy /= lpos.w*32.0; - if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) - { - debug.gb = vec2(0.5, 0.5); - } - - debug += (1.0-shadow)*0.5;*/ - - } - else - { - // more distant than the shadow map covers - shadow = 1.0; - } - - gl_FragColor[0] = shadow; - gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - - //spotlight shadow 1 - vec4 lpos = shadow_matrix[4]*spos; - lpos.xy *= screen_res; - gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x; - - //spotlight shadow 2 - lpos = shadow_matrix[5]*spos; - lpos.xy *= screen_res; - gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x; - - //gl_FragColor.rgb = pos.xyz; - //gl_FragColor.b = shadow; - //gl_FragColor.rgb = debug; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl deleted file mode 100644 index 5081485c4..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @file sunLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec4 vary_light; -varying vec2 vary_fragcoord; - -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; - vec4 tex = gl_MultiTexCoord0; - tex.w = 1.0; - - vary_light = gl_MultiTexCoord0; - - gl_FrontColor = gl_Color; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl deleted file mode 100644 index 734218616..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file waterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -vec3 scaleSoftClip(vec3 inColor); -vec3 atmosTransport(vec3 inColor); - -uniform sampler2D bumpMap; -uniform sampler2D screenTex; -uniform sampler2D refTex; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2D noiseMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; - -uniform float sunAngle; -uniform float sunAngle2; -uniform vec3 lightDir; -uniform vec3 specular; -uniform float lightExp; -uniform float refScale; -uniform float kd; -uniform vec2 screenRes; -uniform vec3 normScale; -uniform float fresnelScale; -uniform float fresnelOffset; -uniform float blurMultiplier; -uniform vec2 screen_res; -uniform mat4 norm_mat; //region space to screen space - -//bigWave is (refCoord.w, view.w); -varying vec4 refCoord; -varying vec4 littleWave; -varying vec4 view; -varying vec4 vary_position; - -void main() -{ - vec4 color; - float dist = length(view.xy); - - //normalize view vector - vec3 viewVec = normalize(view.xyz); - - //get wave normals - vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; - vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; - vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; - //get base fresnel components - - vec3 df = vec3( - dot(viewVec, wave1), - dot(viewVec, (wave2 + wave3) * 0.5), - dot(viewVec, wave3) - ) * fresnelScale + fresnelOffset; - df *= df; - - vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; - - float dist2 = dist; - dist = max(dist, 5.0); - - float dmod = sqrt(dist); - - vec2 dmod_scale = vec2(dmod*dmod, dmod); - - //get reflected color - vec2 refdistort1 = wave1.xy*normScale.x; - vec2 refvec1 = distort+refdistort1/dmod_scale; - vec4 refcol1 = texture2D(refTex, refvec1); - - vec2 refdistort2 = wave2.xy*normScale.y; - vec2 refvec2 = distort+refdistort2/dmod_scale; - vec4 refcol2 = texture2D(refTex, refvec2); - - vec2 refdistort3 = wave3.xy*normScale.z; - vec2 refvec3 = distort+refdistort3/dmod_scale; - vec4 refcol3 = texture2D(refTex, refvec3); - - vec4 refcol = refcol1 + refcol2 + refcol3; - float df1 = df.x + df.y + df.z; - refcol *= df1 * 0.333; - - vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; - //wavef.z *= max(-viewVec.z, 0.1); - wavef = normalize(wavef); - - float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; - - vec2 refdistort4 = wavef.xy*0.125; - refdistort4.y -= abs(refdistort4.y); - vec2 refvec4 = distort+refdistort4/dmod; - float dweight = min(dist2*blurMultiplier, 1.0); - vec4 baseCol = texture2D(refTex, refvec4); - refcol = mix(baseCol*df2, refcol, dweight); - - //get specular component - //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); - - //harden specular - //spec = pow(spec, 128.0); - - //figure out distortion vector (ripply) - vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); - - vec4 fb = texture2D(screenTex, distort2); - - //mix with reflection - // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug - color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); - - float shadow = 1.0; - vec4 pos = vary_position; - - vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - vec4 spos = pos; - - //spec *= shadow; - //color.rgb += spec * specular; - - //color.rgb = atmosTransport(color.rgb); - //color.rgb = scaleSoftClip(color.rgb); - //color.a = spec * sunAngle2; - - //wavef.z *= 0.1f; - wavef = normalize(wavef); - wavef = (norm_mat*vec4(wavef, 1.0)).xyz; - - gl_FragData[0] = vec4(color.rgb, 0.75); - gl_FragData[1] = vec4(1,1,1, 0.8); - gl_FragData[2] = vec4(wavef*0.5+0.5, 0.f); -} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl deleted file mode 100644 index b45e5c530..000000000 --- a/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file waterV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -void calcAtmospherics(vec3 inPositionEye); - -uniform vec2 d1; -uniform vec2 d2; -uniform float time; -uniform vec3 eyeVec; -uniform float waterHeight; - -varying vec4 refCoord; -varying vec4 littleWave; -varying vec4 view; - -varying vec4 vary_position; - -float wave(vec2 v, float t, float f, vec2 d, float s) -{ - return (dot(d, v)*f + t*s)*f; -} - -void main() -{ - //transform vertex - vec4 position = gl_Vertex; - mat4 modelViewProj = gl_ModelViewProjectionMatrix; - - vec4 oPosition; - - //get view vector - vec3 oEyeVec; - oEyeVec.xyz = position.xyz-eyeVec; - - float d = length(oEyeVec.xy); - float ld = min(d, 2560.0); - - position.xy = eyeVec.xy + oEyeVec.xy/d*ld; - view.xyz = oEyeVec; - - d = clamp(ld/1536.0-0.5, 0.0, 1.0); - d *= d; - - oPosition = position; - oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); - vary_position = gl_ModelViewMatrix * oPosition; - oPosition = modelViewProj * oPosition; - - refCoord.xyz = oPosition.xyz + vec3(0,0,0.2); - - //get wave position parameter (create sweeping horizontal waves) - vec3 v = position.xyz; - v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0; - - //push position for further horizon effect. - position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z); - position.w = 1.0; - position = position*gl_ModelViewMatrix; - - calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz); - - - //pass wave parameters to pixel shader - vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; - //get two normal map (detail map) texture coordinates - littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13; - littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1; - view.w = bigWave.y; - refCoord.w = bigWave.x; - - gl_Position = oPosition; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl deleted file mode 100644 index 9cc71a709..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @file avatarF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2D diffuseMap; - -varying vec3 vary_normal; - -void main() -{ - gl_FragData[0] = vec4(gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb, 0.0); - gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); -} - diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl deleted file mode 100644 index 6eb4a5184..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @file bumpF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2D diffuseMap; -uniform sampler2D bumpMap; - -varying vec3 vary_mat0; -varying vec3 vary_mat1; -varying vec3 vary_mat2; - -void main() -{ - vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; - vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0; - - vec3 tnorm = vec3(dot(norm,vary_mat0), - dot(norm,vary_mat1), - dot(norm,vary_mat2)); - - gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); - gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); - gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl deleted file mode 100644 index c9f75f731..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @file diffuseF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2D diffuseMap; - -varying vec3 vary_normal; - -void main() -{ - vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; - gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); - gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); - gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl deleted file mode 100644 index 7325825d6..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file giDownsampleF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect giLightMap; - -uniform vec2 kern[32]; -uniform float dist_factor; -uniform float blur_size; -uniform vec2 delta; -uniform int kern_length; -uniform float kern_scale; -uniform vec3 blur_quad; - -varying vec2 vary_fragcoord; - -uniform mat4 inv_proj; -uniform vec2 screen_res; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -float getDepth(vec2 pos_screen) -{ - float z = texture2DRect(depthMap, pos_screen.xy).a; - z = z*2.0-1.0; - vec4 ndc = vec4(0.0, 0.0, z, 1.0); - vec4 p = inv_proj*ndc; - return p.z/p.w; -} - -void main() -{ - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; - float depth = getDepth(vary_fragcoord.xy); - - vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy); - dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0); - float defined_weight = kern[0].x; - vec3 col = ccol*kern[0].x; - - for (int i = 0; i < kern_length; i++) - { - vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; - vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0; - - float d = dot(norm.xyz, sampNorm); - - if (d > 0.5) - { - float sampdepth = getDepth(tc.xy); - sampdepth -= depth; - if (sampdepth*sampdepth < blur_quad.z) - { - col += texture2DRect(giLightMap, tc).rgb*kern[i].x; - defined_weight += kern[i].x; - } - } - } - - col /= defined_weight; - - //col = ccol; - - col = col*blur_quad.y; - - gl_FragData[0].xyz = col; - - //gl_FragColor = ccol; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl deleted file mode 100644 index 6adcda82a..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file postgiV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl deleted file mode 100644 index 43da836cc..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl +++ /dev/null @@ -1,219 +0,0 @@ -/** - * @file giF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; -uniform sampler2DRect specularRect; - -uniform sampler2D noiseMap; - -uniform sampler2D diffuseGIMap; -uniform sampler2D specularGIMap; -uniform sampler2D normalGIMap; -uniform sampler2D depthGIMap; - -uniform sampler2D lightFunc; - -// Inputs -varying vec2 vary_fragcoord; - -uniform vec2 screen_res; - -uniform vec4 sunlight_color; - -uniform mat4 inv_proj; -uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space -uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space -uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix -uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space -uniform float gi_radius; -uniform float gi_intensity; -uniform int gi_samples; -uniform vec2 gi_kern[25]; -uniform vec2 gi_scale; -uniform vec3 gi_quad; -uniform vec3 gi_spec; -uniform float gi_direction_weight; -uniform float gi_light_offset; -uniform float gi_range; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -vec4 getGIPosition(vec2 gi_tc) -{ - float depth = texture2D(depthGIMap, gi_tc).a; - vec2 sc = gi_tc*2.0; - sc -= vec2(1.0, 1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = gi_inv_proj*ndc; - pos.xyz /= pos.w; - pos.w = 1.0; - return pos; -} - -vec3 giAmbient(vec3 pos, vec3 norm) -{ - vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); - gi_c.xyz /= gi_c.w; - - vec4 gi_pos = gi_mat*vec4(pos,1.0); - vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; - gi_norm = normalize(gi_norm); - - vec4 c_spec = texture2DRect(specularRect, vary_fragcoord.xy); - gi_pos.xyz += (texture2D(noiseMap, vary_fragcoord.xy/128.0).x)*gi_spec.z*gi_norm.xyz; - vec2 tcx = gi_norm.xy; - vec2 tcy = gi_norm.yx; - - vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); - - vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz); - vec3 eye_ref = reflect(eye_dir, gi_norm); - - //vec3 eye_dir = vec3(0,0,-1); - //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; - //eye_dir = normalize(eye_dir); - - //float round_x = gi_scale.x; - //float round_y = gi_scale.y; - - vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb; - //debug.xz = vec2(0.0,0.0); - //debug = fract(debug); - - float round_x = 1.0/64.0; - float round_y = 1.0/64.0; - - //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; - //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; - - float da = texture2DRect(lightMap, vary_fragcoord.xy).r; - - vec3 fdiff = vec3(da); - - if (da > 0.0) - { - vec3 ha = -eye_dir; - ha.z += 1.0; - ha = normalize(ha); - - float sa = dot(ha,gi_norm); - da = min(da, texture2D(lightFunc, vec2(sa, c_spec.a)).a); - fdiff += da*(c_spec.rgb*c_spec.a*2.0); - } - - float fda = da; - - vec3 rcol = vec3(0,0,0); - - float fsa = 0.0; - - - for (int i = -1; i <= 1; i += 1 ) - { - for (int j = -1; j <= 1; j+= 1) - { - vec2 tc = vec2(i, j)*0.75+gi_norm.xy; - vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; - tc += gi_norm.xy*nz.z; - tc += nz.xy*2.0; - tc /= gi_samples; - tc += gi_c.xy; - - vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); - vec3 lpos = getGIPosition(tc.xy).xyz; - - vec3 at = lpos-gi_pos.xyz; - float dist = dot(at,at); - float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); - - - if (da > 0.01) - { //possible contribution of indirect light to this surface - vec3 ldir = at; - - float ld = -dot(ldir, lnorm); - - if (ld < 0.0) - { - float ang_atten = dot(ldir, gi_norm); - - if (ang_atten > 0.0) - { - vec4 spec = texture2D(specularGIMap, tc.xy); - at = normalize(at); - vec3 diff; - - { //contribution from indirect source to visible pixel - vec3 ha = at; - ha.z -= 1.0; - ha = normalize(ha); - float sa = dot(ha,lnorm); - da = min(da, texture2D(lightFunc, vec2(sa, spec.a)).a); - - diff = texture2D(diffuseGIMap, tc.xy).rgb+spec.rgb*spec.a*2.0; - } - - if (da > 0.0) - { //contribution from visible pixel to eye - vec3 ha = normalize(at-eye_dir); - float sa = dot(ha, gi_norm); - da = min(da, texture2D(lightFunc, vec2(sa, c_spec.a)).a); - fda += da; - fdiff += da*(c_spec.rgb*c_spec.a*2.0+vec3(1,1,1))*diff.rgb; - } - } - } - } - } - } - - //fdiff /= max(gi_spec.y*fda, gi_quad.z); - //fdiff = clamp(fdiff, vec3(0), vec3(1)); - fdiff *= 64.0; - fdiff *= sunlight_color.rgb; - - vec3 ret = fda*fdiff; - //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; - - //fda *= nz.z; - - //rcol.rgb *= gi_intensity; - //return rcol.rgb+vary_AmblitColor.rgb*0.25; - //return vec4(debug, 0.0); - //return vec4(fda*fdiff, 0.0); - return clamp(ret,vec3(0.0), vec3(1.0)); - //return debug.xyz; -} - -void main() -{ - vec2 pos_screen = vary_fragcoord.xy; - vec4 pos = getPosition(pos_screen); - - float rad = gi_range*0.5; - - vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; - float dist = max(length(pos.xyz)-rad, 0.0); - - float da = clamp(1.0-dist/rad, 0.0, 1.0); - gl_FragData[0].xyz = da > 0.0 ? giAmbient(pos, norm)*da : vec3(0,0,0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl deleted file mode 100644 index 71dcea962..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file giV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; - -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; - vec4 tex = gl_MultiTexCoord0; - tex.w = 1.0; - - gl_FrontColor = gl_Color; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl deleted file mode 100644 index 0de0d11b2..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @file luminanceF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect diffuseMap; - -varying vec2 vary_fragcoord; -uniform float fade; -void main() -{ - gl_FragColor.rgb = texture2DRect(diffuseMap, vary_fragcoord.xy).rgb; - gl_FragColor.a = fade; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl deleted file mode 100644 index db8775f02..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @file giV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; - -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; - - gl_FrontColor = gl_Color; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl deleted file mode 100644 index 609fb1d1e..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file postDeferredF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect localLightMap; -uniform sampler2DRect sunLightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D luminanceMap; -uniform sampler2DRect lightMap; -uniform sampler2D lightFunc; - - -uniform vec3 gi_lum_quad; -uniform vec3 sun_lum_quad; -uniform vec3 lum_quad; -uniform float lum_lod; -uniform vec4 ambient; - -uniform vec3 gi_quad; - -uniform vec2 screen_res; -varying vec2 vary_fragcoord; - -void main() -{ - vec2 tc = vary_fragcoord.xy; - vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - - float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; - - vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - - float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; - - vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - vec3 gi_col = ccol; - /*for (int i = -1; i <= 1; i+=1) - { - for (int j = -1; j <= 1; j+=1) - { - vec2 tc = vec2(i,j); - float wght = 1.0/(length(tc)+1.0); - gi_col += texture2DRect(giLightMap, vary_fragcoord.xy+vec2(i,j)).rgb * wght; - } - }*/ - - //gi_col *= 1.0+spec.a*4.0; - gi_col = (sqrt(gi_col)*gi_quad.x + gi_col*gi_quad.y)*(diff.rgb+spec.rgb*spec.a)+gi_quad.z*ambocc*ambient.rgb*diff.rgb; - - vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); - - vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; - - - float sun_lum = 1.0-lum; - sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; - - float gi_lum = lum; - gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; - gi_col *= 1.0/gi_lum; - - - vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; - - gl_FragColor.rgb = col.rgb; - gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); - - //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - //gl_FragColor.rgb = vec3(texture2D(lightFunc, vary_fragcoord.xy/512.0-vec2(0.5, 0.5)).a); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl deleted file mode 100644 index 9819232fd..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file postDeferredV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl deleted file mode 100644 index 12a5f3945..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file postgiF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DRect giLightMap; -uniform sampler2D noiseMap; - -uniform vec2 kern[32]; -uniform float dist_factor; -uniform float blur_size; -uniform vec2 delta; -uniform int kern_length; -uniform float kern_scale; -uniform vec3 blur_quad; - -varying vec2 vary_fragcoord; - -uniform mat4 inv_proj; -uniform vec2 screen_res; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -float getDepth(vec2 pos_screen) -{ - float z = texture2DRect(depthMap, pos_screen.xy).a; - z = z*2.0-1.0; - vec4 ndc = vec4(0.0, 0.0, z, 1.0); - vec4 p = inv_proj*ndc; - return p.z/p.w; -} - -void main() -{ - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; - float depth = getDepth(vary_fragcoord.xy); - - vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy); - dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0); - float defined_weight = kern[0].x; - vec3 col = ccol*kern[0].x; - - for (int i = 0; i < kern_length; i++) - { - vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; - vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0; - - float d = dot(norm.xyz, sampNorm); - - if (d > 0.5) - { - float sampdepth = getDepth(tc.xy); - sampdepth -= depth; - if (sampdepth*sampdepth < blur_quad.z) - { - col += texture2DRect(giLightMap, tc).rgb*kern[i].x; - defined_weight += kern[i].x; - } - } - } - - col /= defined_weight; - - //col = ccol; - - col = col*blur_quad.y; - - gl_FragData[0].xyz = col; - - //gl_FragColor = ccol; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl deleted file mode 100644 index 6adcda82a..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file postgiV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl deleted file mode 100644 index 654b18260..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ /dev/null @@ -1,312 +0,0 @@ -/** - * @file softenLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect specularRect; -uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D noiseMap; -uniform samplerCube environmentMap; -uniform sampler2D lightFunc; -uniform sampler2D luminanceMap; - -uniform vec3 gi_quad; -uniform vec3 lum_quad; -uniform float lum_lod; - -uniform float blur_size; -uniform float blur_fidelity; - -// Inputs -uniform vec4 morphFactor; -uniform vec3 camPosLocal; -//uniform vec4 camPosWorld; -uniform vec4 gamma; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 ambient; -uniform vec4 blue_horizon; -uniform vec4 blue_density; -uniform vec4 haze_horizon; -uniform vec4 haze_density; -uniform vec4 cloud_shadow; -uniform vec4 density_multiplier; -uniform vec4 distance_multiplier; -uniform vec4 max_y; -uniform vec4 glow; -uniform float scene_light_strength; -uniform vec3 env_mat[3]; -uniform vec4 shadow_clip; -uniform mat3 ssao_effect_mat; - -uniform sampler2DRect depthMap; -uniform mat4 inv_proj; -uniform vec2 screen_res; - -varying vec4 vary_light; -varying vec2 vary_fragcoord; - -vec3 vary_PositionEye; - -vec3 vary_SunlitColor; -vec3 vary_AmblitColor; -vec3 vary_AdditiveColor; -vec3 vary_AtmosAttenuation; - -vec4 getPosition(vec2 pos_screen) -{ //get position in screen space (world units) given window coordinate and depth map - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -vec3 getPositionEye() -{ - return vary_PositionEye; -} -vec3 getSunlitColor() -{ - return vary_SunlitColor; -} -vec3 getAmblitColor() -{ - return vary_AmblitColor; -} -vec3 getAdditiveColor() -{ - return vary_AdditiveColor; -} -vec3 getAtmosAttenuation() -{ - return vary_AtmosAttenuation; -} - - -void setPositionEye(vec3 v) -{ - vary_PositionEye = v; -} - -void setSunlitColor(vec3 v) -{ - vary_SunlitColor = v; -} - -void setAmblitColor(vec3 v) -{ - vary_AmblitColor = v; -} - -void setAdditiveColor(vec3 v) -{ - vary_AdditiveColor = v; -} - -void setAtmosAttenuation(vec3 v) -{ - vary_AtmosAttenuation = v; -} - -void calcAtmospherics(vec3 inPositionEye, float ambFactor) { - - vec3 P = inPositionEye; - setPositionEye(P); - - //(TERRAIN) limit altitude - if (P.y > max_y.x) P *= (max_y.x / P.y); - if (P.y < -max_y.x) P *= (-max_y.x / P.y); - - vec3 tmpLightnorm = lightnorm.xyz; - - vec3 Pn = normalize(P); - float Plen = length(P); - - vec4 temp1 = vec4(0); - vec3 temp2 = vec3(0); - vec4 blue_weight; - vec4 haze_weight; - vec4 sunlight = sunlight_color; - vec4 light_atten; - - //sunlight attenuation effect (hue and brightness) due to atmosphere - //this is used later for sunlight modulation at various altitudes - light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); - //I had thought blue_density and haze_density should have equal weighting, - //but attenuation due to haze_density tends to seem too strong - - temp1 = blue_density + vec4(haze_density.r); - blue_weight = blue_density / temp1; - haze_weight = vec4(haze_density.r) / temp1; - - //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) - temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; - sunlight *= exp( - light_atten * temp2.y); - - // main atmospheric scattering line integral - temp2.z = Plen * density_multiplier.x; - - // Transparency (-> temp1) - // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati - // compiler gets confused. - temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); - - //final atmosphere attenuation factor - setAtmosAttenuation(temp1.rgb); - - //compute haze glow - //(can use temp2.x as temp because we haven't used it yet) - temp2.x = dot(Pn, tmpLightnorm.xyz); - temp2.x = 1. - temp2.x; - //temp2.x is 0 at the sun and increases away from sun - temp2.x = max(temp2.x, .03); //was glow.y - //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; - //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z); - //glow.z should be negative, so we're doing a sort of (1 / "angle") function - - //add "minimum anti-solar illumination" - temp2.x += .25; - - //increase ambient when there are more clouds - vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; - - /* decrease value and saturation (that in HSV, not HSL) for occluded areas - * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html - * // The following line of code performs the equivalent of: - * float ambAlpha = tmpAmbient.a; - * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis - * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); - * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); - */ - tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); - - //haze color - setAdditiveColor( - vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) - + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x - + tmpAmbient))); - - //brightness of surface both sunlight and ambient - setSunlitColor(vec3(sunlight * .5)); - setAmblitColor(vec3(tmpAmbient * .25)); - setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); -} - -vec3 atmosLighting(vec3 light) -{ - light *= getAtmosAttenuation().r; - light += getAdditiveColor(); - return (2.0 * light); -} - -vec3 atmosTransport(vec3 light) { - light *= getAtmosAttenuation().r; - light += getAdditiveColor() * 2.0; - return light; -} -vec3 atmosGetDiffuseSunlightColor() -{ - return getSunlitColor(); -} - -vec3 scaleDownLight(vec3 light) -{ - return (light / scene_light_strength ); -} - -vec3 scaleUpLight(vec3 light) -{ - return (light * scene_light_strength); -} - -vec3 atmosAmbient(vec3 light) -{ - return getAmblitColor() + light / 2.0; -} - -vec3 atmosAffectDirectionalLight(float lightIntensity) -{ - return getSunlitColor() * lightIntensity; -} - -vec3 scaleSoftClip(vec3 light) -{ - //soft clip effect: - light = 1. - clamp(light, vec3(0.), vec3(1.)); - light = 1. - pow(light, gamma.xxx); - - return light; -} - -void main() -{ - vec2 tc = vary_fragcoord.xy; - vec3 pos = getPosition(tc).xyz; - vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; - vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; - - vec3 at = normalize(pos); - - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - - vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - - vec3 ha = normalize(vary_light.xyz-at); - - float da = dot(ha, norm.xyz); - da = texture2D(lightFunc, vec2(da, spec.a)).a; - - vec4 diffuse = texture2DRect(diffuseRect, tc); - - vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; - float scol = max(scol_ambocc.r, diffuse.a); - float ambocc = scol_ambocc.g; - - calcAtmospherics(pos.xyz, ambocc); - - vec3 col = vec3(0,0,0); - - col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)*(1.0+spec.a)); - - col *= diffuse.rgb; - - col += da*spec.rgb*spec.a*vary_SunlitColor*scol_ambocc.r; - - /*if (spec.a > 0.0) - { - vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); - float sa = dot(ref, vary_light.xyz); - col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; - }*/ - - col = atmosLighting(col); - col = scaleSoftClip(col); - - col = col*vec3(1.0+1.0/2.2); - - gl_FragColor.rgb = col; - //gl_FragColor.rgb = lum; - - gl_FragColor.a = 0.0; - - //gl_FragColor.rg = scol_ambocc.rg; - //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; - //gl_FragColor.rgb = norm.rgb*0.5+0.5; - //gl_FragColor.rgb = vec3(ambocc); - //gl_FragColor.rgb = vec3(scol); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl deleted file mode 100644 index ad8af4780..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @file softenLightF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform vec2 screen_res; - -varying vec4 vary_light; -varying vec2 vary_fragcoord; -void main() -{ - //transform vertex - gl_Position = ftransform(); - - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; - - vec4 tex = gl_MultiTexCoord0; - tex.w = 1.0; - - vary_light = gl_MultiTexCoord0; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl deleted file mode 100644 index 258acee08..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @file treeF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2D diffuseMap; - -varying vec3 vary_normal; - -void main() -{ - vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); - gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005); - gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl deleted file mode 100644 index bea1515f5..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file waterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -vec3 scaleSoftClip(vec3 inColor); -vec3 atmosTransport(vec3 inColor); - -uniform sampler2D bumpMap; -uniform sampler2D screenTex; -uniform sampler2D refTex; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2D noiseMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; - -uniform float sunAngle; -uniform float sunAngle2; -uniform vec3 lightDir; -uniform vec3 specular; -uniform float lightExp; -uniform float refScale; -uniform float kd; -uniform vec2 screenRes; -uniform vec3 normScale; -uniform float fresnelScale; -uniform float fresnelOffset; -uniform float blurMultiplier; -uniform vec2 screen_res; -uniform mat4 norm_mat; //region space to screen space - -//bigWave is (refCoord.w, view.w); -varying vec4 refCoord; -varying vec4 littleWave; -varying vec4 view; -varying vec4 vary_position; - -void main() -{ - vec4 color; - float dist = length(view.xy); - - //normalize view vector - vec3 viewVec = normalize(view.xyz); - - //get wave normals - vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; - vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; - vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; - //get base fresnel components - - vec3 df = vec3( - dot(viewVec, wave1), - dot(viewVec, (wave2 + wave3) * 0.5), - dot(viewVec, wave3) - ) * fresnelScale + fresnelOffset; - df *= df; - - vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; - - float dist2 = dist; - dist = max(dist, 5.0); - - float dmod = sqrt(dist); - - vec2 dmod_scale = vec2(dmod*dmod, dmod); - - //get reflected color - vec2 refdistort1 = wave1.xy*normScale.x; - vec2 refvec1 = distort+refdistort1/dmod_scale; - vec4 refcol1 = texture2D(refTex, refvec1); - - vec2 refdistort2 = wave2.xy*normScale.y; - vec2 refvec2 = distort+refdistort2/dmod_scale; - vec4 refcol2 = texture2D(refTex, refvec2); - - vec2 refdistort3 = wave3.xy*normScale.z; - vec2 refvec3 = distort+refdistort3/dmod_scale; - vec4 refcol3 = texture2D(refTex, refvec3); - - vec4 refcol = refcol1 + refcol2 + refcol3; - float df1 = df.x + df.y + df.z; - refcol *= df1 * 0.333; - - vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; - //wavef.z *= max(-viewVec.z, 0.1); - wavef = normalize(wavef); - - float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; - - vec2 refdistort4 = wavef.xy*0.125; - refdistort4.y -= abs(refdistort4.y); - vec2 refvec4 = distort+refdistort4/dmod; - float dweight = min(dist2*blurMultiplier, 1.0); - vec4 baseCol = texture2D(refTex, refvec4); - refcol = mix(baseCol*df2, refcol, dweight); - - //get specular component - //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); - - //harden specular - //spec = pow(spec, 128.0); - - //figure out distortion vector (ripply) - vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); - - vec4 fb = texture2D(screenTex, distort2); - - //mix with reflection - // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug - color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); - - float shadow = 1.0; - vec4 pos = vary_position; - - vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - vec4 spos = pos; - - //spec *= shadow; - //color.rgb += spec * specular; - - //color.rgb = atmosTransport(color.rgb); - //color.rgb = scaleSoftClip(color.rgb); - //color.a = spec * sunAngle2; - - //wavef.z *= 0.1f; - wavef = normalize(wavef); - wavef = (norm_mat*vec4(wavef, 1.0)).xyz; - - gl_FragData[0] = vec4(color.rgb, 0.5); - gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); - gl_FragData[2] = vec4(wavef*0.5+0.5, 0.f); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl deleted file mode 100644 index 94433202a..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file blurf.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect RenderTexture; -uniform float bloomStrength; - -varying vec4 gl_TexCoord[gl_MaxTextureCoords]; -void main(void) -{ - float blurWeights[7]; - blurWeights[0] = 0.05; - blurWeights[1] = 0.1; - blurWeights[2] = 0.2; - blurWeights[3] = 0.3; - blurWeights[4] = 0.2; - blurWeights[5] = 0.1; - blurWeights[6] = 0.05; - - vec3 color = vec3(0,0,0); - for (int i = 0; i < 7; i++){ - color += vec3(texture2DRect(RenderTexture, gl_TexCoord[i].st)) * blurWeights[i]; - } - - color *= bloomStrength; - - gl_FragColor = vec4(color, 1.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl deleted file mode 100644 index ba65b16cc..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file blurV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform vec2 texelSize; -uniform vec2 blurDirection; -uniform float blurWidth; - -void main(void) -{ - // Transform vertex - gl_Position = ftransform(); - - vec2 blurDelta = texelSize * blurDirection * vec2(blurWidth, blurWidth); - vec2 s = gl_MultiTexCoord0.st - (blurDelta * 3.0); - - // for (int i = 0; i < 7; i++) { - // gl_TexCoord[i].st = s + (i * blurDelta); - // } - - // MANUALLY UNROLL - gl_TexCoord[0].st = s; - gl_TexCoord[1].st = s + blurDelta; - gl_TexCoord[2].st = s + (2. * blurDelta); - gl_TexCoord[3].st = s + (3. * blurDelta); - gl_TexCoord[4].st = s + (4. * blurDelta); - gl_TexCoord[5].st = s + (5. * blurDelta); - gl_TexCoord[6].st = s + (6. * blurDelta); - - // gl_TexCoord[0].st = s; - // gl_TexCoord[1].st = blurDelta; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl deleted file mode 100644 index 623ef7a81..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file colorFilterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect RenderTexture; -uniform float brightness; -uniform float contrast; -uniform vec3 contrastBase; -uniform float saturation; -uniform vec3 lumWeights; - -const float gamma = 2.0; - -void main(void) -{ - vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); - - /// Modulate brightness - color *= brightness; - - /// Modulate contrast - color = mix(contrastBase, color, contrast); - - /// Modulate saturation - color = mix(vec3(dot(color, lumWeights)), color, saturation); - - gl_FragColor = vec4(color, 1.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl deleted file mode 100644 index 29c2a0948..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @file drawQuadV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -void main(void) -{ - //transform vertex - gl_Position = ftransform(); - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_TexCoord[1] = gl_MultiTexCoord1; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl deleted file mode 100644 index a1583b13e..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file extractF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect RenderTexture; -uniform float extractLow; -uniform float extractHigh; -uniform vec3 lumWeights; - -void main(void) -{ - /// Get scene color - vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); - - /// Extract luminance and scale up by night vision brightness - float lum = smoothstep(extractLow, extractHigh, dot(color, lumWeights)); - - gl_FragColor = vec4(vec3(lum), 1.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl deleted file mode 100644 index 271d5cf8d..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file nightVisionF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect RenderTexture; -uniform sampler2D NoiseTexture; -uniform float brightMult; -uniform float noiseStrength; - -float luminance(vec3 color) -{ - /// CALCULATING LUMINANCE (Using NTSC lum weights) - /// http://en.wikipedia.org/wiki/Luma_%28video%29 - return dot(color, vec3(0.299, 0.587, 0.114)); -} - -void main(void) -{ - /// Get scene color - vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); - - /// Extract luminance and scale up by night vision brightness - float lum = luminance(color) * brightMult; - - /// Convert into night vision color space - /// Newer NVG colors (crisper and more saturated) - vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); - - /// Add noise - float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r; - noiseValue = (noiseValue - 0.5) * noiseStrength; - - /// Older NVG colors (more muted) - // vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); - - outColor += noiseValue; - - gl_FragColor = vec4(outColor, 1.0); -} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl deleted file mode 100644 index e55d278b8..000000000 --- a/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @file simpleF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ - */ - -uniform sampler2DRect RenderTexture; - -void main(void) -{ - vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); - gl_FragColor = vec4(1.0 - color, 1.0); -} diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index bfaa4adbc..1b2c8e15c 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -223,7 +223,6 @@ LLAgent gAgent; // Statics // BOOL LLAgent::sPhantom = FALSE; -BOOL LLAgent::sDebugDisplayTarget = FALSE; const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f; @@ -6624,7 +6623,7 @@ void LLAgent::saveWearable( EWearableType type, BOOL send_update ) return; } - // getAvatarObject()->wearableUpdated( type ); + getAvatarObject()->wearableUpdated( type ); if( send_update ) { diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 22851c165..f1cad9cbc 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -771,7 +771,6 @@ class LLAgent : public LLObservable BOOL mInitialized; - static BOOL sDebugDisplayTarget; S32 mNumPendingQueries; S32* mActiveCacheQueries; diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 3a3f51b9b..9fad9f172 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -448,7 +448,7 @@ static void settings_modify() LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] gDebugGL = gSavedSettings.getBOOL("RenderDebugGL"); gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); -// gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); + gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); #if LL_VECTORIZE if (gSysCPU.hasAltivec()) { diff --git a/linden/indra/newview/llcolorswatch.cpp b/linden/indra/newview/llcolorswatch.cpp index 3222c0dd2..5905bb0f2 100644 --- a/linden/indra/newview/llcolorswatch.cpp +++ b/linden/indra/newview/llcolorswatch.cpp @@ -219,12 +219,11 @@ void LLColorSwatchCtrl::draw() gl_rect_2d(interior, mColor, TRUE); LLColor4 opaque_color = mColor; opaque_color.mV[VALPHA] = 1.f; - gGL.color4fv(opaque_color.mV); if (mAlphaGradientImage.notNull()) { gGL.pushMatrix(); { - mAlphaGradientImage->draw(interior, mColor); + mAlphaGradientImage->draw(interior, opaque_color); } gGL.popMatrix(); } diff --git a/linden/indra/newview/llcompilequeue.cpp b/linden/indra/newview/llcompilequeue.cpp index a81972da0..ed18a1002 100644 --- a/linden/indra/newview/llcompilequeue.cpp +++ b/linden/indra/newview/llcompilequeue.cpp @@ -58,6 +58,7 @@ #include "llfloaterchat.h" #include "llviewerstats.h" #include "lluictrlfactory.h" +#include "llselectmgr.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llconsole.cpp b/linden/indra/newview/llconsole.cpp index a8554a037..2379da37c 100644 --- a/linden/indra/newview/llconsole.cpp +++ b/linden/indra/newview/llconsole.cpp @@ -63,25 +63,17 @@ const S32 CONSOLE_GUTTER_LEFT = 14; const S32 CONSOLE_GUTTER_RIGHT = 15; -LLConsole::LLConsole(const std::string& name, const LLRect &rect, +LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect, S32 font_size_index, F32 persist_time ) - : LLFixedBuffer(), - LLView(name, rect, FALSE), - mLinePersistTime(persist_time), - mFadeTime(persist_time - FADE_DURATION), - mFont(LLFontGL::getFontSansSerif()), - mConsoleWidth(0), - mConsoleHeight(0), - mQueueMutex(NULL) + : + LLFixedBuffer(max_lines), + LLView(name, rect, FALSE) { - mTimer.reset(); + mLinePersistTime = persist_time; // seconds + mFadeTime = persist_time - FADE_DURATION; - setFontSize( font_size_index ); -} - -LLConsole::~LLConsole() -{ - clear(); + setFontSize( font_size_index ); + setMaxLines(gSavedSettings.getS32("ConsoleMaxLines")); } void LLConsole::setLinePersistTime(F32 seconds) @@ -106,10 +98,10 @@ void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent) mConsoleHeight= new_height; LLView::reshape(new_width, new_height, called_from_parent); - + for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++) { - (*paragraph_it)->updateLines((F32)getRect().getWidth(), mFont, true); + (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true); } } @@ -134,7 +126,7 @@ void LLConsole::setFontSize(S32 size_index) for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++) { - (*paragraph_it)->updateLines((F32)getRect().getWidth(), mFont, true); + (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true); } } @@ -142,49 +134,35 @@ void LLConsole::draw() { LLGLSUIDefault gls_ui; - { - LLMutexLock lock(&mQueueMutex); - for(paragraph_t::iterator paragraph_it = mNewParagraphs.begin(); paragraph_it != mNewParagraphs.end(); paragraph_it++) - { - Paragraph* paragraph = *paragraph_it; - mParagraphs.push_back(paragraph); - paragraph->updateLines((F32)getRect().getWidth(), mFont); - } - mNewParagraphs.clear(); - } - - if (mParagraphs.empty()) //No text to draw. - { - return; - } - // skip lines added more than mLinePersistTime ago F32 cur_time = mTimer.getElapsedTimeF32(); F32 skip_time = cur_time - mLinePersistTime; F32 fade_time = cur_time - mFadeTime; - U32 max_lines = gSavedSettings.getS32("ConsoleMaxLines"); + updateBuffer() ; + + if (mParagraphs.empty()) //No text to draw. + { + return; + } + U32 num_lines=0; paragraph_t::reverse_iterator paragraph_it; paragraph_it = mParagraphs.rbegin(); U32 paragraph_num=mParagraphs.size(); - + while (!mParagraphs.empty() && paragraph_it != mParagraphs.rend()) { - num_lines += (*paragraph_it)->mLines.size(); - if(num_lines > max_lines - || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) + num_lines += (*paragraph_it).mLines.size(); + if(num_lines > mMaxLines + || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) { //All lines above here are done. Lose them. for (U32 i=0;i<paragraph_num;i++) { if (!mParagraphs.empty()) - { - Paragraph* paragraph = mParagraphs.front(); mParagraphs.pop_front(); - delete paragraph; - } } break; } @@ -215,8 +193,8 @@ void LLConsole::draw() S32 bkg_width=0; for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { - S32 target_height = llfloor( (*paragraph_it)->mLines.size() * line_height + message_spacing); - S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); + S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + message_spacing); + S32 target_width = llfloor( (*paragraph_it).mMaxWidth + CONSOLE_GUTTER_RIGHT); bkg_height+= target_height; if (target_width > bkg_width) @@ -225,7 +203,7 @@ void LLConsole::draw() } // Why is this not using llfloor as above? - y_pos += ((*paragraph_it)->mLines.size()) * line_height; + y_pos += ((*paragraph_it).mLines.size()) * line_height; y_pos += message_spacing; //Extra spacing between messages. } imagep->drawSolid(-CONSOLE_GUTTER_LEFT, (S32)(y_pos + line_height - bkg_height - message_spacing), bkg_width, bkg_height, color); @@ -235,10 +213,10 @@ void LLConsole::draw() for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { //080813 Spatters: Dainty per-message block boxes -// S32 target_height = llfloor( (*paragraph_it)->mLines.size() * line_height + 8); - S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); +// S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + 8); + S32 target_width = llfloor( (*paragraph_it).mMaxWidth + CONSOLE_GUTTER_RIGHT); - y_pos += ((*paragraph_it)->mLines.size()) * line_height; + y_pos += ((*paragraph_it).mLines.size()) * line_height; //080813 Spatters: Dainty per-message block boxes // imagep->drawSolid(-14, (S32)(y_pos + line_height - target_height), target_width, target_height, color); @@ -246,9 +224,9 @@ void LLConsole::draw() F32 alpha; - if ((mLinePersistTime > 0.f) && ((*paragraph_it)->mAddTime < fade_time)) + if ((mLinePersistTime > 0.f) && ((*paragraph_it).mAddTime < fade_time)) { - alpha = ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime); + alpha = ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime); } else { @@ -257,12 +235,12 @@ void LLConsole::draw() if( alpha > 0.f ) { - for (lines_t::iterator line_it=(*paragraph_it)->mLines.begin(); - line_it != (*paragraph_it)->mLines.end(); + for (lines_t::iterator line_it=(*paragraph_it).mLines.begin(); + line_it != (*paragraph_it).mLines.end(); line_it ++) { - for (line_color_segments_t::iterator seg_it = (*line_it).begin(); - seg_it != (*line_it).end(); + for (line_color_segments_t::iterator seg_it = (*line_it).mLineColorSegments.begin(); + seg_it != (*line_it).mLineColorSegments.end(); seg_it++) { mFont->render((*seg_it).mText, 0, (*seg_it).mXPosition - 8, y_pos - y_off, @@ -285,34 +263,21 @@ void LLConsole::draw() } } -//virtual -void LLConsole::clear() +void LLConsole::addLine(const std::string& utf8line) { - mTimer.reset(); - LLMutexLock lock(&mQueueMutex); - std::for_each(mParagraphs.begin(), mParagraphs.end(), DeletePointer()); - mParagraphs.clear(); - std::for_each(mNewParagraphs.begin(), mNewParagraphs.end(), DeletePointer()); - mNewParagraphs.clear(); + LLWString wline = utf8str_to_wstring(utf8line); + addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); } -//virtual -void LLConsole::addLine(const std::string& utf8line) +void LLConsole::addLine(const LLWString& wline) { - addConsoleLine(utf8line, LLColor4(1.f, 1.f, 1.f, 1.f)); + addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); } -void LLConsole::addConsoleLine(const std::string& utf8line, const LLColor4 &color) +void LLConsole::addLine(const std::string& utf8line, F32 size, const LLColor4 &color) { LLWString wline = utf8str_to_wstring(utf8line); - addConsoleLine(wline, color); -} - -void LLConsole::addConsoleLine(const LLWString& wline, const LLColor4 &color) -{ - Paragraph* paragraph = new Paragraph(wline, color, mTimer.getElapsedTimeF32()); - LLMutexLock lock(&mQueueMutex); - mNewParagraphs.push_back ( paragraph ); + addLine(wline, size, color); } //Generate highlight color segments for this paragraph. Pass in default color of paragraph. @@ -394,7 +359,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo F32 x_position = 0; //Screen X position of text. mMaxWidth = llmax( mMaxWidth, (F32)font->getWidth( mParagraphText.substr( paragraph_offset, drawable ).c_str() ) ); - line_color_segments_t line; + Line line; U32 left_to_draw = drawable; U32 drawn = 0; @@ -403,7 +368,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo && current_color != mParagraphColorSegments.end() ) { LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, current_color_length ); - line.push_back( LineColorSegment( color_text, //Append segment to line. + line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line. (*current_color).mColor, x_position ) ); @@ -424,7 +389,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo { LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, left_to_draw ); - line.push_back( LineColorSegment( color_text, //Append segment to line. + line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line. (*current_color).mColor, x_position ) ); @@ -442,9 +407,50 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo } //Pass in the string and the default color for this block of text. -LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time) +LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, LLFontGL* font, F32 screen_width) : mParagraphText(str), mAddTime(add_time), mMaxWidth(-1) { makeParagraphColorSegments(color); + updateLines( screen_width, font ); } +void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color) +{ + Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() ); + + mParagraphs.push_back ( paragraph ); + +#if LL_WINDOWS && LL_LCD_COMPILE + // add to LCD screen + AddNewDebugConsoleToLCD(wline); +#endif +} + +// +//check if there are some messages stored in the buffer +//if yes, output them. +// +void LLConsole::updateBuffer() +{ + BOOL need_clear = FALSE ; + + mMutex.lock() ; + if(!mLines.empty()) + { + S32 end = mLines.size() ; + LLColor4 color(1.f, 1.f, 1.f, 1.f) ; + for(S32 i = 0 ; i < end ; i++) + { + Paragraph paragraph(mLines[i], color, mAddTimes[i], mFont, (F32)getRect().getWidth() ); + mParagraphs.push_back ( paragraph ); + } + + need_clear = TRUE ; + } + mMutex.unlock() ; + + if(need_clear) + { + clear() ; + } +} diff --git a/linden/indra/newview/llconsole.h b/linden/indra/newview/llconsole.h index 578670e33..2915c48b6 100644 --- a/linden/indra/newview/llconsole.h +++ b/linden/indra/newview/llconsole.h @@ -33,8 +33,7 @@ #ifndef LL_LLCONSOLE_H #define LL_LLCONSOLE_H -#include "llerrorcontrol.h" // For LLLineBuffer -#include "llthread.h" +#include "llfixedbuffer.h" #include "llview.h" #include "v4color.h" #include <deque> @@ -48,10 +47,10 @@ class LLConsole : public LLFixedBuffer, public LLView F32 mLinePersistTime; // Age at which to stop drawing. F32 mFadeTime; // Age at which to start fading LLFontGL* mFont; + S32 mLastBoxHeight; + S32 mLastBoxWidth; S32 mConsoleWidth; S32 mConsoleHeight; - LLMutex mQueueMutex; - LLTimer mTimer; public: //A paragraph color segment defines the color of text in a line @@ -81,7 +80,14 @@ class LLConsole : public LLFixedBuffer, public LLView typedef std::list<LineColorSegment> line_color_segments_t; - typedef std::list<line_color_segments_t> lines_t; + //A line is composed of one or more color segments. + class Line + { + public: + line_color_segments_t mLineColorSegments; + }; + + typedef std::list<Line> lines_t; typedef std::list<ParagraphColorSegment> paragraph_color_segments_t; //A paragraph is a processed element containing the entire text of the @@ -92,7 +98,7 @@ class LLConsole : public LLFixedBuffer, public LLView class Paragraph { public: - Paragraph (LLWString str, const LLColor4 &color, F32 add_time); + Paragraph (LLWString str, const LLColor4 &color, F32 add_time, LLFontGL* font, F32 screen_width); void makeParagraphColorSegments ( const LLColor4 &color); void updateLines ( F32 screen_width, LLFontGL* font, bool force_resize=false ); public: @@ -105,32 +111,35 @@ class LLConsole : public LLFixedBuffer, public LLView }; //The console contains a deque of paragraphs which represent the individual messages. - typedef std::deque<Paragraph*> paragraph_t; + typedef std::deque<Paragraph> paragraph_t; paragraph_t mParagraphs; - paragraph_t mNewParagraphs; // Font size: // -1 = monospace, 0 means small, font size = 1 means big - LLConsole(const std::string& name, const LLRect &rect, - S32 font_size_index, F32 persist_time ); - ~LLConsole(); + LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect, + S32 font_size_index, F32 persist_time ); + ~LLConsole(){}; // each line lasts this long after being added - void setLinePersistTime(F32 seconds); + void setLinePersistTime(F32 seconds); - void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); // -1 = monospace, 0 means small, font size = 1 means big - void setFontSize(S32 size_index); + void setFontSize(S32 size_index); - // From LLLineBuffer - /*virtual*/ void clear(); - /*virtual*/ void addLine(const std::string& utf8line); - void addConsoleLine(const std::string& utf8line, const LLColor4 &color); - void addConsoleLine(const LLWString& wline, const LLColor4 &color); + void addLine(const std::string& utf8line, F32 size, const LLColor4 &color); + void addLine(const LLWString& wline, F32 size, const LLColor4 &color); // Overrides /*virtual*/ void draw(); + + //do not make these two "virtual" + void addLine(const std::string& utf8line); + void addLine(const LLWString& line); + +private: + void updateBuffer() ; }; extern LLConsole* gConsole; diff --git a/linden/indra/newview/lldebugview.cpp b/linden/indra/newview/lldebugview.cpp index a6d6f2dd0..40f520206 100644 --- a/linden/indra/newview/lldebugview.cpp +++ b/linden/indra/newview/lldebugview.cpp @@ -62,7 +62,7 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect) LLRect r; r.set(10, rect.getHeight() - 100, rect.getWidth()/2, 100); - mDebugConsolep = new LLConsole("debug console", r, -1, 0.f ); + mDebugConsolep = new LLConsole("debug console", 20, r, -1, 0.f ); mDebugConsolep->setFollowsBottom(); mDebugConsolep->setFollowsLeft(); mDebugConsolep->setVisible( FALSE ); @@ -98,27 +98,6 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect) addChild(gTextureView); //gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE); -/* -//there seems to be some debug code, we don't have -#if !LL_RELEASE_FOR_DOWNLOAD - r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100); - gTextureSizeView = new LLTextureSizeView("gTextureSizeView"); - gTextureSizeView->setRect(r); - gTextureSizeView->setFollowsBottom(); - gTextureSizeView->setFollowsLeft(); - addChild(gTextureSizeView); - - - r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureMemByCategory.size() * 30, 100); - gTextureCategoryView = new LLTextureSizeView("gTextureCategoryView"); - gTextureCategoryView->setRect(r); - gTextureCategoryView->setFollowsBottom(); - gTextureCategoryView->setFollowsLeft(); - gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY); - addChild(gTextureCategoryView); -#endif -*/ - const S32 VELOCITY_LEFT = 10; // 370; const S32 VELOCITY_WIDTH = 500; const S32 VELOCITY_TOP = 140; @@ -136,6 +115,5 @@ LLDebugView::~LLDebugView() // These have already been deleted. Fix the globals appropriately. gDebugView = NULL; gTextureView = NULL; - gTextureSizeView = NULL; } diff --git a/linden/indra/newview/lldrawable.cpp b/linden/indra/newview/lldrawable.cpp index 2b4337437..5a383bc9f 100644 --- a/linden/indra/newview/lldrawable.cpp +++ b/linden/indra/newview/lldrawable.cpp @@ -102,7 +102,7 @@ void LLDrawable::init() mVObjp = NULL; // mFaces mSpatialGroupp = NULL; - mVisible = 0; + mVisible = sCurVisible - 2;//invisible for the current frame and the last frame. mRadius = 0.f; mGeneration = -1; @@ -125,7 +125,7 @@ void LLDrawable::destroy() if (LLSpatialGroup::sNoDelete) { - llwarns << "Illegal deletion of LLDrawable!" << llendl; + llerrs << "Illegal deletion of LLDrawable!" << llendl; } std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); @@ -234,7 +234,7 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) LLMemType mt(LLMemType::MTYPE_DRAWABLE); LLFace *face = new LLFace(this, mVObjp); - if (!face) llwarns << "Allocating new Face: " << mFaces.size() << llendl; + if (!face) llerrs << "Allocating new Face: " << mFaces.size() << llendl; if (face) { @@ -346,7 +346,7 @@ void LLDrawable::deleteFaces(S32 offset, S32 count) void LLDrawable::update() { - llwarns << "Shouldn't be called!" << llendl; + llerrs << "Shouldn't be called!" << llendl; } @@ -369,7 +369,7 @@ void LLDrawable::makeActive() pcode == LLViewerObject::LL_VO_GROUND || pcode == LLViewerObject::LL_VO_SKY) { - llwarns << "Static viewer object has active drawable!" << llendl; + llerrs << "Static viewer object has active drawable!" << llendl; } } #endif @@ -693,22 +693,19 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) pos += volume->getRegion()->getOriginAgent(); } - if (isState(LLDrawable::HAS_ALPHA)) + for (S32 i = 0; i < getNumFaces(); i++) { - for (S32 i = 0; i < getNumFaces(); i++) + LLFace* facep = getFace(i); + if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) { - LLFace* facep = getFace(i); - if (facep->getPoolType() == LLDrawPool::POOL_ALPHA) + LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; + LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); + LLVector3 at = camera.getAtAxis(); + for (U32 j = 0; j < 3; j++) { - LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; - LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); - const LLVector3& at = camera.getAtAxis(); - for (U32 j = 0; j < 3; j++) - { - v.mV[j] -= box.mV[j] * at.mV[j]; - } - facep->mDistance = v * camera.getAtAxis(); + v.mV[j] -= box.mV[j] * at.mV[j]; } + facep->mDistance = v * camera.getAtAxis(); } } } @@ -740,11 +737,7 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - if (!isActive()) - { - //gPipeline.markMoved(this); - } - else + if (isActive()) { if (isRoot()) { @@ -1011,8 +1004,8 @@ BOOL LLDrawable::isVisible() const // Spatial Partition Bridging Drawable //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) // KL Sd version -: LLSpatialPartition(data_mask, render_by_group, FALSE) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask) +: LLSpatialPartition(data_mask, FALSE) { mDrawable = root; root->setSpatialBridge(this); @@ -1142,26 +1135,26 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, { if (isActive() && !mParent->isActive()) { - llwarns << "Active drawable has static parent!" << llendl; + llerrs << "Active drawable has static parent!" << llendl; } if (isStatic() && !mParent->isStatic()) { - llwarns << "Static drawable has active parent!" << llendl; + llerrs << "Static drawable has active parent!" << llendl; } if (mSpatialBridge) { - llwarns << "Child drawable has spatial bridge!" << llendl; + llerrs << "Child drawable has spatial bridge!" << llendl; } } else if (isActive() && !mSpatialBridge) { - llwarns << "Active root drawable has no spatial bridge!" << llendl; + llerrs << "Active root drawable has no spatial bridge!" << llendl; } else if (isStatic() && mSpatialBridge.notNull()) { - llwarns << "Static drawable has spatial bridge!" << llendl; + llerrs << "Static drawable has spatial bridge!" << llendl; } } #endif @@ -1285,25 +1278,12 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) return; } - if (mDrawable->getVObj()) - { - if (mDrawable->getVObj()->isAttachment()) - { - LLDrawable* parent = mDrawable->getParent(); - if (parent && parent->getVObj()) - { - LLVOAvatar* av = parent->getVObj()->asAvatar(); - if (av && av->isImpostor()) - { - return; - } - } - } - - LLCamera camera = transformCamera(camera_in); + LLCamera camera = transformCamera(camera_in); mDrawable->updateDistance(camera, force_update); + if (mDrawable->getVObj()) + { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -1325,7 +1305,7 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) void LLSpatialBridge::makeActive() { //it is an error to make a spatial bridge active (it's already active) - llwarns << "makeActive called on spatial bridge" << llendl; + llerrs << "makeActive called on spatial bridge" << llendl; } void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) @@ -1441,9 +1421,9 @@ void LLDrawable::updateFaceSize(S32 idx) } LLBridgePartition::LLBridgePartition() -: LLSpatialPartition(0, FALSE, 0) +: LLSpatialPartition(0, TRUE) { - //mRenderByGroup = FALSE; // KL + mRenderByGroup = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; mLODPeriod = 16; diff --git a/linden/indra/newview/lldrawable.h b/linden/indra/newview/lldrawable.h index e6753b56b..71b75dc4c 100644 --- a/linden/indra/newview/lldrawable.h +++ b/linden/indra/newview/lldrawable.h @@ -267,8 +267,7 @@ class LLDrawable : public LLRefCount BUILT = 0x08000000, FORCE_INVISIBLE = 0x10000000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) CLEAR_INVISIBLE = 0x20000000, // clear FORCE_INVISIBLE next draw frame - REBUILD_SHADOW = 0x40000000, - HAS_ALPHA = 0x80000000, + REBUILD_SHADOW = 0x40000000 } EDrawableFlags; LLXformMatrix mXform; diff --git a/linden/indra/newview/lldrawpool.h b/linden/indra/newview/lldrawpool.h index 6920a9985..f8c2ead5d 100644 --- a/linden/indra/newview/lldrawpool.h +++ b/linden/indra/newview/lldrawpool.h @@ -68,11 +68,6 @@ class LLDrawPool POOL_GLOW, POOL_ALPHA, NUM_POOL_TYPES, - // * invisiprims work by rendering to the depth buffer but not the color buffer, occluding anything rendered after them - // - and the LLDrawPool types enum controls what order things are rendered in - // - so, it has absolute control over what invisprims block - // ...invisiprims being rendered in pool_invisible - // ...shiny/bump mapped objects in rendered in POOL_BUMP }; LLDrawPool(const U32 type); diff --git a/linden/indra/newview/lldrawpoolalpha.cpp b/linden/indra/newview/lldrawpoolalpha.cpp index c9c06f4f5..4b552acd5 100644 --- a/linden/indra/newview/lldrawpoolalpha.cpp +++ b/linden/indra/newview/lldrawpoolalpha.cpp @@ -88,12 +88,7 @@ void LLDrawPoolAlpha::beginDeferredPass(S32 pass) void LLDrawPoolAlpha::endDeferredPass(S32 pass) { - -} - -void LLDrawPoolAlpha::renderDeferred(S32 pass) -{ - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f); { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); gDeferredTreeProgram.bind(); @@ -104,6 +99,11 @@ void LLDrawPoolAlpha::renderDeferred(S32 pass) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } +void LLDrawPoolAlpha::renderDeferred(S32 pass) +{ + +} + S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { @@ -261,8 +261,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; - S32 diffuse_channel = 0; - //BOOL is_particle = FALSE; BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) || gPipeline.canUseWindLightShadersOnObjects(); @@ -293,6 +291,19 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) LLRenderPass::applyModelMatrix(params); + if (params.mTexture.notNull()) + { + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->bind(params.mTexture.get()); + + if (params.mTextureMatrix) + { + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } + if (params.mFullbright) { // Turn off lighting if it hasn't already been so. @@ -333,13 +344,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); - diffuse_channel = 0; } current_shader = target_shader; if (deferred_render) { gPipeline.bindDeferredShader(*current_shader); - diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } else { @@ -348,12 +357,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } else if (!use_shaders && current_shader != NULL) { + LLGLSLShader::bindNoShader(); if (deferred_render) { gPipeline.unbindDeferredShader(*current_shader); - diffuse_channel = 0; } - LLGLSLShader::bindNoShader(); current_shader = NULL; } @@ -361,24 +369,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { params.mGroup->rebuildMesh(); } - - - if (params.mTexture.notNull()) - { - gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get(), TRUE, TRUE); - if(params.mViewerTexture.notNull()) - { - params.mViewerTexture->addTextureStats(params.mVSize); - } - if (params.mTextureMatrix) - { - gGL.getTexUnit(0)->activate(); - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - } - params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); @@ -393,15 +383,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } - if (deferred_render && current_shader != NULL) - { - gPipeline.unbindDeferredShader(*current_shader); - LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - } - if (!light_enabled) { gPipeline.enableLightsDynamic(); diff --git a/linden/indra/newview/lldrawpoolavatar.cpp b/linden/indra/newview/lldrawpoolavatar.cpp index af7b5e386..80c7d73e6 100644 --- a/linden/indra/newview/lldrawpoolavatar.cpp +++ b/linden/indra/newview/lldrawpoolavatar.cpp @@ -94,7 +94,6 @@ BOOL gAvatarEmbossBumpMap = FALSE; static BOOL sRenderingSkinned = FALSE; S32 normal_channel = -1; S32 specular_channel = -1; -S32 diffuse_channel = -1; LLDrawPoolAvatar::LLDrawPoolAvatar() : LLFacePool(POOL_AVATAR) @@ -448,8 +447,7 @@ void LLDrawPoolAvatar::beginDeferredImpostor() normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); - diffuse_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); // KL SD - + sVertexProgram->bind(); } @@ -458,7 +456,6 @@ void LLDrawPoolAvatar::endDeferredImpostor() sShaderLevel = mVertexShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); - sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); // KL SD sVertexProgram->unbind(); gGL.getTexUnit(0)->activate(); } @@ -702,8 +699,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) avatarp->mImpostor.bindTexture(1, specular_channel); } } - // avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel); // KL SD - avatarp->renderImpostor(); + avatarp->renderImpostor(); } else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred) { @@ -756,67 +752,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if( !single_avatar || (avatarp == single_avatar) ) { - if (LLVOAvatar::sShowCollisionVolumes) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - avatarp->renderCollisionVolumes(); - } - - if (avatarp->isSelf() && LLAgent::sDebugDisplayTarget) - { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLVector3 pos = avatarp->getPositionAgent(); - - gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }gGL.end(); - - pos = avatarp->mDrawable->getPositionAgent(); - gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }gGL.end(); - - pos = avatarp->mRoot.getWorldPosition(); - gGL.color4f(1.0f, 1.0f, 1.0f, 0.8f); - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }gGL.end(); - - pos = avatarp->mPelvisp->getWorldPosition(); - gGL.color4f(0.0f, 0.0f, 1.0f, 0.8f); - gGL.begin(LLRender::LINES); - { - gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }gGL.end(); - - color.setColor(1.0f, 1.0f, 1.0f, 1.0f); - } - avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } } diff --git a/linden/indra/newview/lldrawpoolbump.cpp b/linden/indra/newview/lldrawpoolbump.cpp index e14b34d1d..93fadcac7 100644 --- a/linden/indra/newview/lldrawpoolbump.cpp +++ b/linden/indra/newview/lldrawpoolbump.cpp @@ -140,7 +140,7 @@ void LLStandardBumpmap::restoreGL() return; } -// llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; + llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = gImageList.getImageFromFile(bump_file, @@ -310,8 +310,8 @@ void LLDrawPoolBump::endRenderPass(S32 pass) void LLDrawPoolBump::beginShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| - invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| + (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) { return; } @@ -385,8 +385,8 @@ void LLDrawPoolBump::beginShiny(bool invisible) void LLDrawPoolBump::renderShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| - invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| + (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) { return; } @@ -412,8 +412,8 @@ void LLDrawPoolBump::renderShiny(bool invisible) void LLDrawPoolBump::endShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| - invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| + (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) { return; } @@ -573,11 +573,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) LLImageGL* bump = NULL; U8 bump_code = params.mBump; - LLViewerImage* tex = params.mViewerTexture; - if(!tex) - { - return FALSE ; - } + LLViewerImage* tex = params.mTexture; switch( bump_code ) { @@ -1231,10 +1227,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) if (params.mTexture.notNull()) { gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); - if(params.mViewerTexture.notNull()) - { - params.mViewerTexture->addTextureStats(params.mVSize); - } + //params.mTexture->addTextureStats(params.mVSize); } else { diff --git a/linden/indra/newview/lldrawpoolsky.cpp b/linden/indra/newview/lldrawpoolsky.cpp index 0ca913076..bed103047 100644 --- a/linden/indra/newview/lldrawpoolsky.cpp +++ b/linden/indra/newview/lldrawpoolsky.cpp @@ -61,8 +61,8 @@ LLDrawPool *LLDrawPoolSky::instancePool() void LLDrawPoolSky::prerender() { - mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); -// gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); + mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); + gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); } void LLDrawPoolSky::render(S32 pass) @@ -97,7 +97,6 @@ void LLDrawPoolSky::render(S32 pass) } - LLVOSky *voskyp = gSky.mVOSkyp; LLGLSPipelineSkyBox gls_skybox; LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -120,43 +119,9 @@ void LLDrawPoolSky::render(S32 pass) { renderSkyCubeFace(i); } - - LLFace *hbfaces[3]; - hbfaces[0] = NULL; - hbfaces[1] = NULL; - hbfaces[2] = NULL; - for (S32 curr_face = 0; curr_face < face_count; curr_face++) - { - LLFace* facep = mDrawFace[curr_face]; - if (voskyp->isSameFace(LLVOSky::FACE_SUN, facep)) - { - hbfaces[0] = facep; - } - if (voskyp->isSameFace(LLVOSky::FACE_MOON, facep)) - { - hbfaces[1] = facep; - } - if (voskyp->isSameFace(LLVOSky::FACE_BLOOM, facep)) - { - hbfaces[2] = facep; - } - } LLGLEnable blend(GL_BLEND); - if (hbfaces[2]) - { - // renderSunHalo(hbfaces[2]); - } - if (hbfaces[0]) - { - // renderHeavenlyBody(0, hbfaces[0]); - } - if (hbfaces[1]) - { - // renderHeavenlyBody(1, hbfaces[1]); - } - glPopMatrix(); } @@ -181,35 +146,6 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side) } } -void LLDrawPoolSky::renderHeavenlyBody(U8 hb, LLFace* face) -{ - if ( !mHB[hb]->getDraw() ) return; - if (! face->getGeomCount()) return; - - LLImageGL* tex = face->getTexture(); - gGL.getTexUnit(0)->bind(tex); - LLColor4 color(mHB[hb]->getInterpColor()); - LLOverrideFaceColor override(this, color); - face->renderIndexed(); -} - - - -void LLDrawPoolSky::renderSunHalo(LLFace* face) -{ - if (! mHB[0]->getDraw()) return; - if (! face->getGeomCount()) return; - - LLImageGL* tex = face->getTexture(); - gGL.getTexUnit(0)->bind(tex); - LLColor4 color(mHB[0]->getInterpColor()); - color.mV[3] = llclamp(mHB[0]->getHaloBrighness(), 0.f, 1.f); - - LLOverrideFaceColor override(this, color); - face->renderIndexed(); -} - - void LLDrawPoolSky::renderForSelect() { } diff --git a/linden/indra/newview/lldrawpoolsky.h b/linden/indra/newview/lldrawpoolsky.h index f35b11473..8595d73ae 100644 --- a/linden/indra/newview/lldrawpoolsky.h +++ b/linden/indra/newview/lldrawpoolsky.h @@ -36,14 +36,12 @@ #include "lldrawpool.h" class LLSkyTex; -class LLHeavenBody; class LLGLSLShader; class LLDrawPoolSky : public LLFacePool { private: LLSkyTex *mSkyTex; - LLHeavenBody *mHB[2]; // Sun and Moon LLGLSLShader *mShader; public: @@ -69,8 +67,6 @@ class LLDrawPoolSky : public LLFacePool /*virtual*/ void renderForSelect(); /*virtual*/ void endRenderPass(S32 pass); void setSkyTex(LLSkyTex* const st) { mSkyTex = st; } - void setSun(LLHeavenBody* sun_flag) { mHB[0] = sun_flag; } - void setMoon(LLHeavenBody* moon) { mHB[1] = moon; } void renderSkyCubeFace(U8 side); void renderHeavenlyBody(U8 hb, LLFace* face); diff --git a/linden/indra/newview/lldrawpoolterrain.cpp b/linden/indra/newview/lldrawpoolterrain.cpp index 249f5a9bb..d0bf2c126 100644 --- a/linden/indra/newview/lldrawpoolterrain.cpp +++ b/linden/indra/newview/lldrawpoolterrain.cpp @@ -73,19 +73,19 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) : TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); - //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c", TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); - //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_TERRAIN); - //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } LLDrawPoolTerrain::~LLDrawPoolTerrain() diff --git a/linden/indra/newview/lldrawpooltree.cpp b/linden/indra/newview/lldrawpooltree.cpp index 52f669a29..e4560f2c2 100644 --- a/linden/indra/newview/lldrawpooltree.cpp +++ b/linden/indra/newview/lldrawpooltree.cpp @@ -52,7 +52,7 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) : LLFacePool(POOL_TREE), mTexturep(texturep) { -// gGL.getTexUnit(0)->bind(mTexturep.get()); + gGL.getTexUnit(0)->bind(mTexturep.get()); mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); } @@ -110,7 +110,7 @@ void LLDrawPoolTree::render(S32 pass) } else { - gGL.getTexUnit(sDiffTex)->bind(mTexturep, TRUE); + gGL.getTexUnit(sDiffTex)->bind(mTexturep); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) @@ -140,7 +140,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass) void LLDrawPoolTree::beginDeferredPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); // KL Render-pipeline has this set at 0.f ... NOOOOOO! make shitty trees :) + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); shader = &gDeferredTreeProgram; shader->bind(); @@ -166,9 +166,6 @@ void LLDrawPoolTree::beginShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), - gSavedSettings.getF32("RenderDeferredTreeShadowBias")); - gDeferredShadowProgram.bind(); } @@ -181,11 +178,7 @@ void LLDrawPoolTree::endShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - - glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"), - gSavedSettings.getF32("RenderDeferredSpotShadowBias")); - - //gDeferredShadowProgram.unbind(); + gDeferredShadowProgram.unbind(); } diff --git a/linden/indra/newview/lldrawpoolwater.cpp b/linden/indra/newview/lldrawpoolwater.cpp index d08d004ca..624b8a8b6 100644 --- a/linden/indra/newview/lldrawpoolwater.cpp +++ b/linden/indra/newview/lldrawpoolwater.cpp @@ -98,7 +98,7 @@ void LLDrawPoolWater::restoreGL() LLDrawPool *LLDrawPoolWater::instancePool() { - llwarns << "Should never be calling instancePool on a water pool!" << llendl; + llerrs << "Should never be calling instancePool on a water pool!" << llendl; return NULL; } @@ -401,15 +401,6 @@ void LLDrawPoolWater::shade() shader = &gWaterProgram; } - if (deferred_render) - { - gPipeline.bindDeferredShader(*shader); - } - else - { - shader->bind(); - } - sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); @@ -445,6 +436,15 @@ void LLDrawPoolWater::shade() S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); + if (deferred_render) + { + gPipeline.bindDeferredShader(*shader); + } + else + { + shader->bind(); + } + if (screentex > -1) { shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); diff --git a/linden/indra/newview/lldynamictexture.cpp b/linden/indra/newview/lldynamictexture.cpp index e219d4bc4..61f5a8905 100644 --- a/linden/indra/newview/lldynamictexture.cpp +++ b/linden/indra/newview/lldynamictexture.cpp @@ -41,7 +41,6 @@ #include "llvertexbuffer.h" #include "llviewerdisplay.h" #include "llrender.h" -#include "pipeline.h" // static LLDynamicTexture::instance_list_t LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ]; @@ -59,14 +58,9 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder mClamp(clamp) { llassert((1 <= components) && (components <= 4)); - if(!LLPipeline::sRenderDeferred) - { - generateGLTexture(); - } - else - { - gPipeline.markGLRebuild(this); // KL SD well for this to work its either gotta be one or the other so lets slap in the if/else can't do any harm. - } + + generateGLTexture(); + llassert( 0 <= order && order < ORDER_COUNT ); LLDynamicTexture::sInstances[ order ].insert(this); } @@ -83,11 +77,6 @@ LLDynamicTexture::~LLDynamicTexture() } } -void LLDynamicTexture::updateGL() -{ - generateGLTexture(); -} - //----------------------------------------------------------------------------- // releaseGLTexture() //----------------------------------------------------------------------------- @@ -112,7 +101,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima { if (mComponents < 1 || mComponents > 4) { - llwarns << "Bad number of components in dynamic texture: " << mComponents << llendl; + llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl; } releaseGLTexture(); LLPointer<LLImageRaw> raw_image = new LLImageRaw(mWidth, mHeight, mComponents); @@ -122,7 +111,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); } // llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; - mTexture->createGLTexture(0, raw_image); + mTexture->createGLTexture(0, raw_image, 0, TRUE, LLViewerImageBoostLevel::DYNAMIC_TEX); mTexture->setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); mTexture->setGLTextureCreated(false); } diff --git a/linden/indra/newview/lldynamictexture.h b/linden/indra/newview/lldynamictexture.h index 14807991b..5a20eaef9 100644 --- a/linden/indra/newview/lldynamictexture.h +++ b/linden/indra/newview/lldynamictexture.h @@ -37,7 +37,7 @@ #include "llcoord.h" #include "llimagegl.h" -class LLDynamicTexture : public LLGLUpdate +class LLDynamicTexture { public: enum EOrder { ORDER_FIRST = 0, ORDER_MIDDLE = 1, ORDER_LAST = 2, ORDER_RESET = 3, ORDER_COUNT = 4 }; @@ -49,8 +49,6 @@ class LLDynamicTexture : public LLGLUpdate BOOL clamp); virtual ~LLDynamicTexture(); - void updateGL(); - S32 getOriginX() { return mOrigin.mX; } S32 getOriginY() { return mOrigin.mY; } S32 getWidth() { return mWidth; } diff --git a/linden/indra/newview/llface.cpp b/linden/indra/newview/llface.cpp index ae57a3c2c..aa8cd15dd 100644 --- a/linden/indra/newview/llface.cpp +++ b/linden/indra/newview/llface.cpp @@ -176,8 +176,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mLastIndicesCount = mIndicesCount; mLastIndicesIndex = mIndicesIndex; - mAtlasInfop = NULL ; - mUsingAtlas = FALSE ; + mImportanceToCamera = 0.f ; + mBoundingSphereRadius = 0.0f ; } @@ -205,14 +205,12 @@ void LLFace::destroy() if (group) { group->dirtyGeom(); - gPipeline.markRebuild(group, TRUE); } } } setDrawInfo(NULL); - removeAtlas(); mDrawablep = NULL; mVObjp = NULL; } @@ -225,7 +223,7 @@ void LLFace::initClass() void LLFace::setWorldMatrix(const LLMatrix4 &mat) { - llwarns << "Faces on this drawable are not independently modifiable\n" << llendl; + llerrs << "Faces on this drawable are not independently modifiable\n" << llendl; } void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) @@ -234,7 +232,7 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) if (!new_pool) { - llwarns << "Setting pool to null!" << llendl; + llerrs << "Setting pool to null!" << llendl; } if (new_pool != mDrawPoolp) @@ -272,7 +270,6 @@ void LLFace::setTexture(LLViewerImage* tex) if(mTexture.notNull()) { mTexture->removeFace(this) ; - removeAtlas() ; } mTexture = tex ; @@ -456,15 +453,8 @@ void LLFace::renderForSelect(U32 data_mask) void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) { - if (mDrawablep->getSpatialGroup() == NULL) - { - return; - } - - mDrawablep->getSpatialGroup()->rebuildGeom(); - mDrawablep->getSpatialGroup()->rebuildMesh(); - - if(mDrawablep.isNull() || mVertexBuffer.isNull()) + if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL || + mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY)) { return; } @@ -483,10 +473,17 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); } - glColor4fv(color.mV); + setFaceColor(color); + renderSetColor(); + mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays("", LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +#endif mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); + unsetFaceColor(); + unsetFaceColor(); gGL.popMatrix(); } } @@ -730,8 +727,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, } mCenterLocal = (newMin+newMax)*0.5f; - // LLVector3 tmp = (newMin - newMax) ; - // mBoundingSphereRadius = tmp.length() * 0.5f ; + LLVector3 tmp = (newMin - newMax) ; + mBoundingSphereRadius = tmp.length() * 0.5f ; updateCenterAgent(); } @@ -966,12 +963,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getBinormalStrider(binormals, mGeomIndex); } - F32 tcoord_xoffset = 0.f ; - F32 tcoord_yoffset = 0.f ; - F32 tcoord_xscale = 1.f ; - F32 tcoord_yscale = 1.f ; - BOOL in_atlas = FALSE ; - if (rebuild_tcoord) { mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex); @@ -979,18 +970,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex); } - - in_atlas = isAtlasInUse() ; - if(in_atlas) - { - const LLVector2* tmp = getTexCoordOffset() ; - tcoord_xoffset = tmp->mV[0] ; - tcoord_yoffset = tmp->mV[1] ; - - tmp = getTexCoordScale() ; - tcoord_xscale = tmp->mV[0] ; - tcoord_yscale = tmp->mV[1] ; - } } if (rebuild_color) { @@ -1078,7 +1057,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 0.75f }; - if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || LLPipeline::sRenderBump && tep->getShiny())) + if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) { color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } @@ -1200,93 +1179,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, xform(tc, cos_ang, sin_ang, os, ot, ms, mt); } - if(in_atlas) - { - // - //manually calculate tex-coord per vertex for varying address modes. - //should be removed if shader can handle this. - // - - S32 int_part = 0 ; - switch(mTexture->getAddressMode()) - { - case LLTexUnit::TAM_CLAMP: - if(tc.mV[0] < 0.f) - { - tc.mV[0] = 0.f ; - } - else if(tc.mV[0] > 1.f) - { - tc.mV[0] = 1.f; - } - - if(tc.mV[1] < 0.f) - { - tc.mV[1] = 0.f ; - } - else if(tc.mV[1] > 1.f) - { - tc.mV[1] = 1.f; - } - break; - case LLTexUnit::TAM_MIRROR: - if(tc.mV[0] < 0.f) - { - tc.mV[0] = -tc.mV[0] ; - } - int_part = (S32)tc.mV[0] ; - if(int_part & 1) //odd number - { - tc.mV[0] = int_part + 1 - tc.mV[0] ; - } - else //even number - { - tc.mV[0] -= int_part ; - } - - if(tc.mV[1] < 0.f) - { - tc.mV[1] = -tc.mV[1] ; - } - int_part = (S32)tc.mV[1] ; - if(int_part & 1) //odd number - { - tc.mV[1] = int_part + 1 - tc.mV[1] ; - } - else //even number - { - tc.mV[1] -= int_part ; - } - break; - case LLTexUnit::TAM_WRAP: - if(tc.mV[0] > 1.f) - tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; - else if(tc.mV[0] < -1.f) - tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; - - if(tc.mV[1] > 1.f) - tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; - else if(tc.mV[1] < -1.f) - tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; - - if(tc.mV[0] < 0.f) - { - tc.mV[0] = 1.0f + tc.mV[0] ; - } - if(tc.mV[1] < 0.f) - { - tc.mV[1] = 1.0f + tc.mV[1] ; - } - break; - default: - break; - } - - tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; - tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; - } - - *tex_coords++ = tc; if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) @@ -1353,6 +1245,159 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, return TRUE; } +const F32 LEAST_IMPORTANCE = 0.05f ; +const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; + +F32 LLFace::getTextureVirtualSize() +{ + F32 radius; + F32 cos_angle_to_view_dir; + mPixelArea = calcPixelArea(cos_angle_to_view_dir, radius); + + if (mPixelArea <= 0) + { + return 0.f; + } + + //get area of circle in texture space + LLVector2 tdim = mTexExtents[1] - mTexExtents[0]; + F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; + if (texel_area <= 0) + { + // Probably animated, use default + texel_area = 1.f; + } + + F32 face_area; + if (mVObjp->isSculpted() && texel_area > 1.f) + { + //sculpts can break assumptions about texel area + face_area = mPixelArea; + } + else + { + //apply texel area to face area to get accurate ratio + //face_area /= llclamp(texel_area, 1.f/64.f, 16.f); + face_area = mPixelArea / llclamp(texel_area, 0.015625f, 1024.f); + } + + if(face_area > LLViewerImage::sMaxSmallImageSize) + { + if(mImportanceToCamera < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res. + { + face_area = LLViewerImage::sMaxSmallImageSize ; + } + else if(face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. + { + if(mImportanceToCamera < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res. + { + face_area = LLViewerImage::sMinLargeImageSize ; + } + else if(mTexture.notNull() && mTexture->isLargeImage()) + { + face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius ); + } + } + } + + return face_area; +} + +F32 LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) +{ + //get area of circle around face + LLVector3 center = getPositionAgent(); + LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f; + + LLVector3 lookAt = center - LLViewerCamera::getInstance()->getOrigin(); + F32 dist = lookAt.normVec() ; + + //get area of circle around node + F32 app_angle = atanf(size.length()/dist); + radius = app_angle*LLDrawable::sCurPixelAngle; + F32 face_area = radius*radius * 3.14159f; + + if(dist < mBoundingSphereRadius) //camera is very close + { + cos_angle_to_view_dir = 1.0f ; + mImportanceToCamera = 1.0f ; + } + else + { + cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; + mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ; + } + + return face_area ; +} + +//the projection of the face partially overlaps with the screen +F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ) +{ + F32 screen_radius = (F32)llmax(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()) ; + F32 center_angle = acosf(cos_angle_to_view_dir) ; + F32 d = center_angle * LLDrawable::sCurPixelAngle ; + + if(d + radius > screen_radius + 5.f) + { + //---------------------------------------------- + //calculate the intersection area of two circles + //F32 radius_square = radius * radius ; + //F32 d_square = d * d ; + //F32 screen_radius_square = screen_radius * screen_radius ; + //face_area = + // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) + + // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) - + // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ; + //---------------------------------------------- + + //the above calculation is too expensive + //the below is a good estimation: bounding box of the bounding sphere: + F32 alpha = 0.5f * (radius + screen_radius - d) / radius ; + alpha = llclamp(alpha, 0.f, 1.f) ; + return alpha * alpha ; + } + return 1.0f ; +} + +const S8 FACE_IMPORTANCE_LEVEL = 4 ; +const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight} + {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ; +const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] = //{cos(angle), importance_weight} + {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ; + +//static +F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) +{ + F32 importance = 0.f ; + + if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && + dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) + { + F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; + F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); + + if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f) + { + //if camera moves or rotates too fast, ignore the importance factor + return 0.f ; + } + + //F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ; + + S32 i = 0 ; + for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i); + i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; + F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ; + + for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ; + i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; + importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ; + } + + return importance ; +} + BOOL LLFace::verify(const U32* indices_array) const { BOOL ok = TRUE; @@ -1541,153 +1586,3 @@ LLVector3 LLFace::getPositionAgent() const return mCenterLocal * getRenderMatrix(); } } - -// -//atlas -// -void LLFace::removeAtlas() -{ - setAtlasInUse(FALSE) ; - mAtlasInfop = NULL ; -} - -const LLTextureAtlas* LLFace::getAtlas()const -{ - if(mAtlasInfop) - { - return mAtlasInfop->getAtlas() ; - } - return NULL ; -} - -const LLVector2* LLFace::getTexCoordOffset()const -{ - if(isAtlasInUse()) - { - return mAtlasInfop->getTexCoordOffset() ; - } - return NULL ; -} -const LLVector2* LLFace::getTexCoordScale() const -{ - if(isAtlasInUse()) - { - return mAtlasInfop->getTexCoordScale() ; - } - return NULL ; -} - -BOOL LLFace::isAtlasInUse()const -{ - return mUsingAtlas ; -} - -BOOL LLFace::canUseAtlas()const -{ - //no drawable or no spatial group, do not use atlas - if(!mDrawablep || !mDrawablep->getSpatialGroup()) - { - return FALSE ; - } - - //if bump face, do not use atlas - if(getTextureEntry() && getTextureEntry()->getBumpmap()) - { - return FALSE ; - } - - //if animated texture, do not use atlas - if(isState(TEXTURE_ANIM)) - { - return FALSE ; - } - - return TRUE ; -} - -void LLFace::setAtlasInUse(BOOL flag) -{ - //no valid atlas to use. - if(flag && (!mAtlasInfop || !mAtlasInfop->isValid())) - { - flag = FALSE ; - } - - if(!flag && !mUsingAtlas) - { - return ; - } - - // - //at this stage (flag || mUsingAtlas) is always true. - // - - //rebuild the tex coords - if(mDrawablep) - { - gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD); - mUsingAtlas = flag ; - } - else - { - mUsingAtlas = FALSE ; - } -} - -LLTextureAtlasSlot* LLFace::getAtlasInfo() -{ - return mAtlasInfop ; -} - -void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp) -{ - if(mAtlasInfop != atlasp) - { - if(mAtlasInfop) - { - //llwarns << "Atlas slot changed!" << llendl ; - } - mAtlasInfop = atlasp ; - } -} - -LLImageGL* LLFace::getGLTexture() const -{ - if(isAtlasInUse()) - { - return (LLImageGL*)mAtlasInfop->getAtlas() ; - } - - return (LLImageGL*)mTexture ; -} - -//switch to atlas or switch back to gl texture -//return TRUE if using atlas. -BOOL LLFace::switchTexture() -{ - //no valid atlas or texture - if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture) - { - return FALSE ; - } - - if(mTexture->getTexelsInAtlas() >= (U32)mVSize || mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture()) - { - //switch to use atlas - //atlas resolution is qualified, use it. - if(!mUsingAtlas) - { - setAtlasInUse(TRUE) ; - } - } - else //if atlas not qualified. - { - //switch back to GL texture - if(mUsingAtlas && mTexture->isGLTextureCreated() && mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas()) - { - setAtlasInUse(FALSE) ; - } - } - - return mUsingAtlas ; -} diff --git a/linden/indra/newview/llface.h b/linden/indra/newview/llface.h index 9f76d6b91..4893e825d 100644 --- a/linden/indra/newview/llface.h +++ b/linden/indra/newview/llface.h @@ -48,7 +48,6 @@ #include "llviewerimage.h" #include "llstat.h" #include "lldrawable.h" -#include "lltextureatlasmanager.h" class LLFacePool; class LLVolume; @@ -57,7 +56,6 @@ class LLTextureEntry; class LLVertexProgram; class LLViewerImage; class LLGeometryManager; -class LLTextureAtlasSlot; const F32 MIN_ALPHA_SIZE = 1024.f; const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -191,18 +189,14 @@ class LLFace void setIndicesIndex(S32 idx) { mIndicesIndex = idx; } void setDrawInfo(LLDrawInfo* draw_info); - // KL was atlas S19 - LLImageGL* getGLTexture() const; - LLTextureAtlasSlot* getAtlasInfo() ; - void setAtlasInUse(BOOL flag); - void setAtlasInfo(LLTextureAtlasSlot* atlasp); - BOOL isAtlasInUse()const; - BOOL canUseAtlas() const; - const LLVector2* getTexCoordScale() const ; - const LLVector2* getTexCoordOffset()const; - const LLTextureAtlas* getAtlas()const ; - void removeAtlas() ; - BOOL switchTexture() ; + F32 getTextureVirtualSize() ; + F32 getImportanceToCamera()const {return mImportanceToCamera ;} + +private: + F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ); + F32 calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ; +public: + static F32 calcImportanceToCamera(F32 to_view_dir, F32 dist); public: @@ -218,7 +212,7 @@ class LLFace LLMatrix4* mTextureMatrix; LLDrawInfo* mDrawInfo; -protected: +private: friend class LLGeometryManager; friend class LLVolumeGeometryManager; @@ -248,10 +242,12 @@ class LLFace F32 mVSize; F32 mPixelArea; - //atlas - LLPointer<LLTextureAtlasSlot> mAtlasInfop ; - BOOL mUsingAtlas ; - + //importance factor, in the range [0, 1.0]. + //1.0: the most important. + //based on the distance from the face to the view point and the angle from the face center to the view direction. + F32 mImportanceToCamera ; + F32 mBoundingSphereRadius ; + protected: static BOOL sSafeRenderSelect; @@ -279,9 +275,9 @@ class LLFace const LLTextureEntry* lte = lhs->getTextureEntry(); const LLTextureEntry* rte = rhs->getTextureEntry(); - if(lhs->getGLTexture() != rhs->getGLTexture()) // KL SD get GL + if (lhs->getTexture() != rhs->getTexture()) { - return lhs->getGLTexture() < rhs->getGLTexture(); // not getTexture? + return lhs->getTexture() < rhs->getTexture(); } else if (lte->getBumpShinyFullbright() != rte->getBumpShinyFullbright()) { diff --git a/linden/indra/newview/llfloaterassetbrowser.cpp b/linden/indra/newview/llfloaterassetbrowser.cpp index ca0e8d17d..af81c4a68 100644 --- a/linden/indra/newview/llfloaterassetbrowser.cpp +++ b/linden/indra/newview/llfloaterassetbrowser.cpp @@ -63,7 +63,7 @@ LLFloaterAssetBrowser::~LLFloaterAssetBrowser() mTextureAssets.clear(); mMaxIndex = 0; mFirstIndex = 0; - mMouseOverIndex = NULL; + mMouseOverIndex = 0; mMouseOverUUID = LLUUID::null; mMouseOverAssetUUID = LLUUID::null; mFloaterTitle = ""; @@ -79,7 +79,7 @@ void LLFloaterAssetBrowser::initialize() mAssetInfoIndex = 0; mFloaterHeight = getRect().getHeight(); mFloaterWidth = getRect().getWidth(); - mMouseOverIndex = NULL; + mMouseOverIndex = 0; mMouseOverUUID = LLUUID::null; mMouseOverAssetUUID = LLUUID::null; mFloaterTitle = ""; @@ -131,14 +131,14 @@ void LLFloaterAssetBrowser::createThumbnails() { mTextureAssets[i].mTexturep = gImageList.getImage(mTextureAssets[i].mAssetUUID, MIPMAP_YES, IMMEDIATE_NO); mTextureAssets[i].mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); - mTextureAssets[i].mTexturep->processTextureStats(); + //mTextureAssets[i].mTexturep->processTextureStats(); } //Generate the asset info text - for(S32 i = 0; i < items.count(); i++) + /*for(S32 i = 0; i < items.count(); i++) { - std::string asset_info; - std::string dimensions; + LLString asset_info; + LLString dimensions; asset_info.append(mTextureAssets[i].mName); @@ -151,7 +151,7 @@ void LLFloaterAssetBrowser::createThumbnails() asset_info.append(dimensions); mTextureAssets[i].mAssetInfo = asset_info; - } + }*/ mFloaterTitle = llformat("Asset Browser (%d assets fetched)", mTextureAssets.size()); setTitle(mFloaterTitle); @@ -288,7 +288,7 @@ void LLFloaterAssetBrowser::draw() if(mImageAssetID.notNull()) { mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); - mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); + //mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); mTexturep->processTextureStats(); mTextureAssets[i].mWidth = mTexturep->mFullWidth; mTextureAssets[i].mHeight = mTexturep->mFullHeight; diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index 5f43406e4..2daa5aa4b 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp @@ -582,8 +582,7 @@ void LLFloaterChat::addChat(const LLChat& chat, // We display anything if it's not an IM. If it's an IM, check pref... if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatConsole") ) { - gConsole->addConsoleLine(chat.mText, text_color); - + gConsole->addLine(chat.mText, size, text_color); } } diff --git a/linden/indra/newview/llfloaterhardwaresettings.cpp b/linden/indra/newview/llfloaterhardwaresettings.cpp index 8c91f5a50..7886e394a 100644 --- a/linden/indra/newview/llfloaterhardwaresettings.cpp +++ b/linden/indra/newview/llfloaterhardwaresettings.cpp @@ -68,7 +68,6 @@ void LLFloaterHardwareSettings::onClickHelp(void* data) void LLFloaterHardwareSettings::initCallbacks(void) { - childSetCommitCallback("fbo", refreshState); } // menu maintenance functions @@ -84,8 +83,7 @@ void LLFloaterHardwareSettings::refresh() mVideoCardMem = gSavedSettings.getS32("TextureMemory"); mFogRatio = gSavedSettings.getF32("RenderFogRatio"); mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); - mRenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); - mRenderUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); + childSetValue("fsaa", (LLSD::Integer) mFSAASamples); refreshEnabledState(); } @@ -103,20 +101,6 @@ void LLFloaterHardwareSettings::refreshEnabledState() childSetEnabled("vbo", FALSE); } - if (!gGLManager.mHasFramebufferObject) - { - childSetEnabled("fbo", FALSE); - } - - if (!gGLManager.mHasDrawBuffers || !gSavedSettings.getBOOL("RenderUseFBO")) - { - childSetEnabled("deferred", FALSE); - } - else - { - childSetEnabled("deferred", TRUE); - } - // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance childSetEnabled("gamma", !gPipeline.canUseWindLightShaders()); childSetEnabled("(brightness, lower is brighter)", !gPipeline.canUseWindLightShaders()); @@ -124,12 +108,6 @@ void LLFloaterHardwareSettings::refreshEnabledState() } -//static -void LLFloaterHardwareSettings::refreshState(LLUICtrl*, void*) -{ - LLFloaterHardwareSettings::instance()->refreshEnabledState(); -} - // static instance of it LLFloaterHardwareSettings* LLFloaterHardwareSettings::instance() { @@ -224,8 +202,7 @@ void LLFloaterHardwareSettings::cancel() gSavedSettings.setS32("TextureMemory", mVideoCardMem); gSavedSettings.setF32("RenderFogRatio", mFogRatio); gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); - gSavedSettings.setBOOL("RenderUseFBO", mRenderUseFBO); - gSavedSettings.setBOOL("RenderDeferred", mRenderDeferred); + close(); } diff --git a/linden/indra/newview/llfloaterhardwaresettings.h b/linden/indra/newview/llfloaterhardwaresettings.h index e564e1c10..04a33f69d 100644 --- a/linden/indra/newview/llfloaterhardwaresettings.h +++ b/linden/indra/newview/llfloaterhardwaresettings.h @@ -61,8 +61,6 @@ class LLFloaterHardwareSettings : public LLFloater /// OK button static void onBtnOK( void* userdata ); - static void refreshState(LLUICtrl*, void*); - //// menu management /// show off our menu @@ -90,8 +88,6 @@ class LLFloaterHardwareSettings : public LLFloater LLSliderCtrl* mCtrlVideoCardMem; BOOL mUseVBO; - BOOL mRenderUseFBO; - BOOL mRenderDeferred; BOOL mUseAniso; U32 mFSAASamples; F32 mGamma; diff --git a/linden/indra/newview/llfloaterlagmeter.cpp b/linden/indra/newview/llfloaterlagmeter.cpp index 2ae2e32a0..8fe455fde 100644 --- a/linden/indra/newview/llfloaterlagmeter.cpp +++ b/linden/indra/newview/llfloaterlagmeter.cpp @@ -180,7 +180,7 @@ void LLFloaterLagMeter::determineClient() { mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); } - else if((LLViewerImage::sBoundTextureMemoryInBytes >> 20) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) + else if((BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes)) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) { mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); } diff --git a/linden/indra/newview/llfloaterpostprocess.cpp b/linden/indra/newview/llfloaterpostprocess.cpp index c5b2018ec..de9b598b1 100644 --- a/linden/indra/newview/llfloaterpostprocess.cpp +++ b/linden/indra/newview/llfloaterpostprocess.cpp @@ -52,29 +52,28 @@ LLFloaterPostProcess::LLFloaterPostProcess() : LLFloater(std::string("Post-Proce LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml"); /// Color Filter Callbacks - //childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); - childSetCommitCallback("wmiColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); + childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); //childSetCommitCallback("ColorFilterGamma", &LLFloaterPostProcess::onFloatControlMoved, &(gPostProcess->tweaks.gamma())); - childSetCommitCallback("wmiColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness"); - childSetCommitCallback("wmiColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation"); - childSetCommitCallback("wmiColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast"); + childSetCommitCallback("ColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness"); + childSetCommitCallback("ColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation"); + childSetCommitCallback("ColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast"); - childSetCommitCallback("wmiColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base"); - childSetCommitCallback("wmiColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base"); - childSetCommitCallback("wmiColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base"); - childSetCommitCallback("wmiColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base"); + childSetCommitCallback("ColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base"); + childSetCommitCallback("ColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base"); + childSetCommitCallback("ColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base"); + childSetCommitCallback("ColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base"); /// Night Vision Callbacks - childSetCommitCallback("wmiNightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision"); - childSetCommitCallback("wmiNightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier"); - childSetCommitCallback("wmiNightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size"); - childSetCommitCallback("wmiNightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength"); + childSetCommitCallback("NightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision"); + childSetCommitCallback("NightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier"); + childSetCommitCallback("NightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size"); + childSetCommitCallback("NightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength"); /// Bloom Callbacks - childSetCommitCallback("wmiBloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom"); - childSetCommitCallback("wmiBloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low"); - childSetCommitCallback("wmiBloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); - childSetCommitCallback("wmiBloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); + childSetCommitCallback("BloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom"); + childSetCommitCallback("BloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low"); + childSetCommitCallback("BloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); + childSetCommitCallback("BloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); // Effect loading and saving. LLComboBox* comboBox = getChild<LLComboBox>("PPEffectsCombo"); @@ -114,7 +113,6 @@ void LLFloaterPostProcess::onBoolToggle(LLUICtrl* ctrl, void* userData) // check the bool LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl); gPostProcess->tweaks[boolVariableName] = cbCtrl->getValue(); - } // Float Moved @@ -249,25 +247,25 @@ void LLFloaterPostProcess::syncMenu() comboBox->selectByValue(gPostProcess->getSelectedEffect()); /// Sync Color Filter Menu - childSetValue("wmiColorFilterToggle", gPostProcess->tweaks.useColorFilter()); + childSetValue("ColorFilterToggle", gPostProcess->tweaks.useColorFilter()); //childSetValue("ColorFilterGamma", gPostProcess->tweaks.gamma()); - childSetValue("wmiColorFilterBrightness", gPostProcess->tweaks.brightness()); - childSetValue("wmiColorFilterSaturation", gPostProcess->tweaks.saturation()); - childSetValue("wmiColorFilterContrast", gPostProcess->tweaks.contrast()); - childSetValue("wmiColorFilterBaseR", gPostProcess->tweaks.contrastBaseR()); - childSetValue("wmiColorFilterBaseG", gPostProcess->tweaks.contrastBaseG()); - childSetValue("wmiColorFilterBaseB", gPostProcess->tweaks.contrastBaseB()); - childSetValue("wmiColorFilterBaseI", gPostProcess->tweaks.contrastBaseIntensity()); + childSetValue("ColorFilterBrightness", gPostProcess->tweaks.brightness()); + childSetValue("ColorFilterSaturation", gPostProcess->tweaks.saturation()); + childSetValue("ColorFilterContrast", gPostProcess->tweaks.contrast()); + childSetValue("ColorFilterBaseR", gPostProcess->tweaks.contrastBaseR()); + childSetValue("ColorFilterBaseG", gPostProcess->tweaks.contrastBaseG()); + childSetValue("ColorFilterBaseB", gPostProcess->tweaks.contrastBaseB()); + childSetValue("ColorFilterBaseI", gPostProcess->tweaks.contrastBaseIntensity()); /// Sync Night Vision Menu - childSetValue("wmiNightVisionToggle", gPostProcess->tweaks.useNightVisionShader()); - childSetValue("wmiNightVisionBrightMult", gPostProcess->tweaks.brightMult()); - childSetValue("wmiNightVisionNoiseSize", gPostProcess->tweaks.noiseSize()); - childSetValue("wmiNightVisionNoiseStrength", gPostProcess->tweaks.noiseStrength()); + childSetValue("NightVisionToggle", gPostProcess->tweaks.useNightVisionShader()); + childSetValue("NightVisionBrightMult", gPostProcess->tweaks.brightMult()); + childSetValue("NightVisionNoiseSize", gPostProcess->tweaks.noiseSize()); + childSetValue("NightVisionNoiseStrength", gPostProcess->tweaks.noiseStrength()); /// Sync Bloom Menu - childSetValue("wmiBloomToggle", LLSD(gPostProcess->tweaks.useBloomShader())); - childSetValue("wmiBloomExtract", gPostProcess->tweaks.extractLow()); - childSetValue("wmiBloomSize", gPostProcess->tweaks.bloomWidth()); - childSetValue("wmiBloomStrength", gPostProcess->tweaks.bloomStrength()); + childSetValue("BloomToggle", LLSD(gPostProcess->tweaks.useBloomShader())); + childSetValue("BloomExtract", gPostProcess->tweaks.extractLow()); + childSetValue("BloomSize", gPostProcess->tweaks.bloomWidth()); + childSetValue("BloomStrength", gPostProcess->tweaks.bloomStrength()); } diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp index 9209f4183..a7f41eae4 100644 --- a/linden/indra/newview/llfloaterreporter.cpp +++ b/linden/indra/newview/llfloaterreporter.cpp @@ -952,8 +952,7 @@ void LLFloaterReporter::takeScreenshot() // store in the image list so it doesn't try to fetch from the server LLPointer<LLViewerImage> image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid); - image_in_list->createGLTexture(0, raw); - + image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); gImageList.addImage(image_in_list); // the texture picker then uses that texture diff --git a/linden/indra/newview/llhudeffect.cpp b/linden/indra/newview/llhudeffect.cpp index 20bbb321e..c1d46f98d 100644 --- a/linden/indra/newview/llhudeffect.cpp +++ b/linden/indra/newview/llhudeffect.cpp @@ -78,7 +78,7 @@ void LLHUDEffect::unpackData(LLMessageSystem *mesgsys, S32 blocknum) void LLHUDEffect::render() { - llwarns << "Never call this!" << llendl; // Then why the &*^&*^ is it here? + llerrs << "Never call this!" << llendl; } void LLHUDEffect::setID(const LLUUID &id) diff --git a/linden/indra/newview/llhudtext.cpp b/linden/indra/newview/llhudtext.cpp index b17f8d780..7d9f7f9e2 100644 --- a/linden/indra/newview/llhudtext.cpp +++ b/linden/indra/newview/llhudtext.cpp @@ -1116,8 +1116,6 @@ void LLHUDText::renderAllHUD() LLVertexBuffer::unbind(); - LLVertexBuffer::unbind(); // KL not entirely sure why but render pipeline has this twice? - LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); diff --git a/linden/indra/newview/llmanip.cpp b/linden/indra/newview/llmanip.cpp index 0c88c477e..45550fcfb 100644 --- a/linden/indra/newview/llmanip.cpp +++ b/linden/indra/newview/llmanip.cpp @@ -60,7 +60,7 @@ #include "llglheaders.h" // Local constants... -const S32 VERTICAL_OFFSET = 100; // KL adjusted to compensate for toolbars move to the top of the screen! +const S32 VERTICAL_OFFSET = 50; F32 LLManip::sHelpTextVisibleTime = 2.f; F32 LLManip::sHelpTextFadeTime = 2.f; diff --git a/linden/indra/newview/llmaniptranslate.h b/linden/indra/newview/llmaniptranslate.h index 25ff35cc7..77f12ff91 100644 --- a/linden/indra/newview/llmaniptranslate.h +++ b/linden/indra/newview/llmaniptranslate.h @@ -116,7 +116,7 @@ class LLManipTranslate : public LLManip LLVector3d mDragCursorStartGlobal; LLVector3d mDragSelectionStartGlobal; LLTimer mUpdateTimer; - typedef std::set<ManipulatorHandle*, compare_manipulators> minpulator_list_t; + typedef std::multiset<ManipulatorHandle*, compare_manipulators> minpulator_list_t; minpulator_list_t mProjectedManipulators; LLVector4 mManipulatorVertices[18]; F32 mSnapOffsetMeters; diff --git a/linden/indra/newview/llmediactrl.cpp b/linden/indra/newview/llmediactrl.cpp index a517332bd..153059897 100644 --- a/linden/indra/newview/llmediactrl.cpp +++ b/linden/indra/newview/llmediactrl.cpp @@ -1012,7 +1012,8 @@ BOOL LLWebBrowserTexture::render() x_pos, y_pos, width, - height); + height, + TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) } media_plugin->resetDirty(); diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index 1b60eeeb5..3af3d0e26 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp @@ -444,6 +444,7 @@ void LLOverlayBar::toggleMusicPlay(void*) // if ( gAudiop->isInternetStreamPlaying() == 0 ) { gAudiop->startInternetStream(parcel->getMusicURL()); +//awfixme sTitleObserver.init(parcel->getMusicURL()); } } } diff --git a/linden/indra/newview/llpanelvolume.cpp b/linden/indra/newview/llpanelvolume.cpp index 4270f0bba..6d014a23d 100644 --- a/linden/indra/newview/llpanelvolume.cpp +++ b/linden/indra/newview/llpanelvolume.cpp @@ -53,7 +53,6 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcolorswatch.h" -#include "lltexturectrl.h" #include "llcombobox.h" #include "llfirstuse.h" #include "llfocusmgr.h" @@ -112,28 +111,12 @@ BOOL LLPanelVolume::postBuild() LightColorSwatch->setOnSelectCallback(onLightSelectColor); childSetCommitCallback("colorswatch",onCommitLight,this); } - - LLTextureCtrl* LightTexPicker = getChild<LLTextureCtrl>("light texture control"); - if (LightTexPicker) - { - LightTexPicker->setOnCancelCallback(onLightCancelTexture); - LightTexPicker->setOnSelectCallback(onLightSelectTexture); - childSetCommitCallback("light texture control", onCommitLight, this); - } - childSetCommitCallback("Light Intensity",onCommitLight,this); childSetValidate("Light Intensity",precommitValidate); childSetCommitCallback("Light Radius",onCommitLight,this); childSetValidate("Light Radius",precommitValidate); childSetCommitCallback("Light Falloff",onCommitLight,this); childSetValidate("Light Falloff",precommitValidate); - - childSetCommitCallback("Light FOV", onCommitLight, this); - childSetValidate("Light FOV", precommitValidate); - childSetCommitCallback("Light Focus", onCommitLight, this); - childSetValidate("Light Focus", precommitValidate); - childSetCommitCallback("Light Ambiance", onCommitLight, this); - childSetValidate("Light Ambiance", precommitValidate); } // Start with everyone disabled @@ -238,32 +221,14 @@ void LLPanelVolume::getState( ) LightColorSwatch->setValid( TRUE ); LightColorSwatch->set(volobjp->getLightBaseColor()); } - - LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); - if (LightTextureCtrl) - { - LightTextureCtrl->setEnabled(TRUE); - LightTextureCtrl->setValid(TRUE); - LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); - } - childSetEnabled("Light Intensity",true); childSetEnabled("Light Radius",true); childSetEnabled("Light Falloff",true); - childSetEnabled("Light FOV", true); - childSetEnabled("Light Focus", true); - childSetEnabled("Light Ambiance", true); - childSetValue("Light Intensity",volobjp->getLightIntensity()); childSetValue("Light Radius",volobjp->getLightRadius()); childSetValue("Light Falloff",volobjp->getLightFalloff()); - LLVector3 params = volobjp->getSpotLightParams(); - childSetValue("Light FOV", params.mV[0]); - childSetValue("Light Focus", params.mV[1]); - childSetValue("Light Ambiance", params.mV[2]); - mLightSavedColor = volobjp->getLightColor(); } else @@ -279,20 +244,9 @@ void LLPanelVolume::getState( ) LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } - LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); - if (LightTextureCtrl) - { - LightTextureCtrl->setEnabled(FALSE); - LightTextureCtrl->setValid(FALSE); - } - childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); - - childSetEnabled("Light FOV",false); - childSetEnabled("Light Focus",false); - childSetEnabled("Light Ambiance",false); } // Flexible properties @@ -408,13 +362,6 @@ void LLPanelVolume::clearCtrls() LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } - LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); - if(LightTextureCtrl) - { - LightTextureCtrl->setEnabled( FALSE ); - LightTextureCtrl->setValid( FALSE ); - } - childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); @@ -491,16 +438,6 @@ void LLPanelVolume::onLightCancelColor(LLUICtrl* ctrl, void* userdata) onLightSelectColor(NULL, userdata); } -void LLPanelVolume::onLightCancelTexture(LLUICtrl* ctrl, void* userdata) -{ - LLPanelVolume* self = (LLPanelVolume*) userdata; - LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control"); - if (LightTextureCtrl) - { - LightTextureCtrl->setImageAssetID(self->mLightSavedTexture); - } -} - void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*) userdata; @@ -522,25 +459,6 @@ void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) } } -void LLPanelVolume::onLightSelectTexture(LLUICtrl* ctrl, void* userdata) -{ - LLPanelVolume* self = (LLPanelVolume*) userdata; - LLViewerObject* objectp = self->mObject; - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) - { - return; - } - LLVOVolume *volobjp = (LLVOVolume *)objectp; - - - LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control"); - if(LightTextureCtrl) - { - LLUUID id = LightTextureCtrl->getImageAssetID(); - volobjp->setLightTextureID(id); - self->mLightSavedTexture = id; - } -} // static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { @@ -556,47 +474,12 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) volobjp->setLightIntensity((F32)self->childGetValue("Light Intensity").asReal()); volobjp->setLightRadius((F32)self->childGetValue("Light Radius").asReal()); volobjp->setLightFalloff((F32)self->childGetValue("Light Falloff").asReal()); - LLColorSwatchCtrl* LightColorSwatch = self->getChild<LLColorSwatchCtrl>("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); volobjp->setLightColor(LLColor3(clr)); } - - LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control"); - if(LightTextureCtrl) - { - LLUUID id = LightTextureCtrl->getImageAssetID(); - if (id.notNull()) - { - if (volobjp->getLightTextureID().isNull()) - { //this commit is making this a spot light, set UI to default params - volobjp->setLightTextureID(id); - LLVector3 spot_params = volobjp->getSpotLightParams(); - self->childSetValue("Light FOV", spot_params.mV[0]); - self->childSetValue("Light Focus", spot_params.mV[1]); - self->childSetValue("Light Ambiance", spot_params.mV[2]); - } - else - { //modifying existing params - LLVector3 spot_params; - spot_params.mV[0] = (F32) self->childGetValue("Light FOV").asReal(); - spot_params.mV[1] = (F32) self->childGetValue("Light Focus").asReal(); - spot_params.mV[2] = (F32) self->childGetValue("Light Ambiance").asReal(); - volobjp->setSpotLightParams(spot_params); - } - } - else if (volobjp->getLightTextureID().notNull()) - { //no longer a spot light - volobjp->setLightTextureID(id); - //self->childDisable("Light FOV"); - //self->childDisable("Light Focus"); - //self->childDisable("Light Ambiance"); - } - } - - } // static diff --git a/linden/indra/newview/llpanelvolume.h b/linden/indra/newview/llpanelvolume.h index 5d206fc3b..841880b14 100644 --- a/linden/indra/newview/llpanelvolume.h +++ b/linden/indra/newview/llpanelvolume.h @@ -74,10 +74,6 @@ class LLPanelVolume : public LLPanel static void onLightCancelColor(LLUICtrl* ctrl, void* userdata); static void onLightSelectColor(LLUICtrl* ctrl, void* userdata); - static void onLightCancelTexture(LLUICtrl* ctrl, void* userdata); - static void onLightSelectTexture(LLUICtrl* ctrl, void* userdata); - - protected: void getState(); @@ -103,7 +99,6 @@ class LLPanelVolume : public LLPanel */ LLColor4 mLightSavedColor; - LLUUID mLightSavedTexture; LLPointer<LLViewerObject> mObject; LLPointer<LLViewerObject> mRootObject; }; diff --git a/linden/indra/newview/llpostprocess.cpp b/linden/indra/newview/llpostprocess.cpp deleted file mode 100644 index c7d5dad60..000000000 --- a/linden/indra/newview/llpostprocess.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/** - * @file llpostprocess.cpp - * @brief LLPostProcess class implementation - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "linden_common.h" - -#include "llpostprocess.h" -#include "llglslshader.h" -#include "llsdserialize.h" -#include "llrender.h" - -#include "llviewershadermgr.h" // KL throwing some includes at postprocess see if we can get the bastard working! -#include "pipeline.h" -#include "llimagegl.h" - - - -LLPostProcess * gPostProcess = NULL; - - -static const unsigned int NOISE_SIZE = 512; - -/// CALCULATING LUMINANCE (Using NTSC lum weights) -/// http://en.wikipedia.org/wiki/Luma_%28video%29 -static const float LUMINANCE_R = 0.299f; -static const float LUMINANCE_G = 0.587f; -static const float LUMINANCE_B = 0.114f; - -static const char * const XML_FILENAME = "postprocesseffects.xml"; - -LLPostProcess::LLPostProcess(void) : - initialized(false), - mAllEffects(LLSD::emptyMap()), - screenW(1), screenH(1) -{ - mSceneRenderTexture = NULL ; - mNoiseTexture = NULL ; - mTempBloomTexture = NULL ; - - // Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); - LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL; - - llifstream effectsXML(pathName); - - if (effectsXML) - { - LLPointer<LLSDParser> parser = new LLSDXMLParser(); - - parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED); - } - - if (!mAllEffects.has("default")) - { - LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap()); - - defaultEffect["enable_night_vision"] = LLSD::Boolean(false); - defaultEffect["enable_bloom"] = LLSD::Boolean(false); - defaultEffect["enable_color_filter"] = LLSD::Boolean(false); - - /// NVG Defaults - defaultEffect["brightness_multiplier"] = 3.0; - defaultEffect["noise_size"] = 25.0; - defaultEffect["noise_strength"] = 0.4; - - // TODO BTest potentially add this to tweaks? - noiseTextureScale = 1.0f; - - /// Bloom Defaults - defaultEffect["extract_low"] = 0.95; - defaultEffect["extract_high"] = 1.0; - defaultEffect["bloom_width"] = 2.25; - defaultEffect["bloom_strength"] = 1.5; - - /// Color Filter Defaults - defaultEffect["brightness"] = 1.0; - defaultEffect["contrast"] = 1.0; - defaultEffect["saturation"] = 1.0; - - LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray()); - contrastBase.append(1.0); - contrastBase.append(1.0); - contrastBase.append(1.0); - contrastBase.append(0.5); - } - - setSelectedEffect("default"); - -} - -LLPostProcess::~LLPostProcess(void) -{ - invalidate() ; -} - -// static -void LLPostProcess::initClass(void) -{ - //this will cause system to crash at second time login - //if first time login fails due to network connection --- bao - //***llassert_always(gPostProcess == NULL); - //replaced by the following line: - if(gPostProcess) - return ; - - - gPostProcess = new LLPostProcess(); -} - -// static -void LLPostProcess::cleanupClass() -{ - delete gPostProcess; - gPostProcess = NULL; -} - -void LLPostProcess::setSelectedEffect(std::string const & effectName) -{ - mSelectedEffectName = effectName; - static_cast<LLSD &>(tweaks) = mAllEffects[effectName]; -} - -void LLPostProcess::saveEffect(std::string const & effectName) -{ - // Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. - mAllEffects[effectName] = tweaks; - - std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); - //llinfos << "Saving PostProcess Effects settings to " << pathName << llendl; - - llofstream effectsXML(pathName); - - LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter(); - - formatter->format(mAllEffects, effectsXML); - -} -void LLPostProcess::invalidate() -{ - mSceneRenderTexture = NULL ; - mNoiseTexture = NULL ; - mTempBloomTexture = NULL ; - initialized = FALSE ; -} - -void LLPostProcess::apply(unsigned int width, unsigned int height) -{ - if (!initialized || width != screenW || height != screenH){ - initialize(width, height); - } - if (shadersEnabled()){ - doEffects(); - } -} - -void LLPostProcess::initialize(unsigned int width, unsigned int height) -{ - screenW = width; - screenH = height; - createTexture(mSceneRenderTexture, screenW, screenH); - initialized = true; - - checkError(); - createNightVisionShader(); - createBloomShader(); - createColorFilterShader(); - checkError(); -} - -inline bool LLPostProcess::shadersEnabled(void) -{ - return (tweaks.useColorFilter().asBoolean() || - tweaks.useNightVisionShader().asBoolean() || - tweaks.useBloomShader().asBoolean() ); - -} - -void LLPostProcess::applyShaders(void) -{ - if (tweaks.useColorFilter()){ - applyColorFilterShader(); - checkError(); - } - if (tweaks.useNightVisionShader()){ - /// If any of the above shaders have been called update the frame buffer; - if (tweaks.useColorFilter()) - { - U32 tex = mSceneRenderTexture->getTexName() ; - copyFrameBuffer(tex, screenW, screenH); - } - applyNightVisionShader(); - checkError(); - } - if (tweaks.useBloomShader()){ - /// If any of the above shaders have been called update the frame buffer; - if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean()) - { - U32 tex = mSceneRenderTexture->getTexName() ; - copyFrameBuffer(tex, screenW, screenH); - } - applyBloomShader(); - checkError(); - } -} - -void LLPostProcess::applyColorFilterShader(void) -{ - // Do nothing. moved back to newview work in progress KL - gPostColorFilterProgram.bind(); - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); - - U32 tex = mSceneRenderTexture->getTexName() ; // KL - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, tex); - - getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject); - glUniform1iARB(colorFilterUniforms["RenderTexture"], 0); - glUniform1fARB(colorFilterUniforms["brightness"], tweaks.getBrightness()); - glUniform1fARB(colorFilterUniforms["contrast"], tweaks.getContrast()); - float baseI = (tweaks.getContrastBaseR() + tweaks.getContrastBaseG() + tweaks.getContrastBaseB()) / 3.0f; - baseI = tweaks.getContrastBaseIntensity() / ((baseI < 0.001f) ? 0.001f : baseI); - float baseR = tweaks.getContrastBaseR() * baseI; - float baseG = tweaks.getContrastBaseG() * baseI; - float baseB = tweaks.getContrastBaseB() * baseI; - glUniform3fARB(colorFilterUniforms["contrastBase"], baseR, baseG, baseB); - glUniform1fARB(colorFilterUniforms["saturation"], tweaks.getSaturation()); - glUniform3fARB(colorFilterUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); - - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_REPLACE); - LLGLDepthTest depth(GL_FALSE); - - /// Draw a screen space quad - drawOrthoQuad(screenW, screenH, QUAD_NORMAL); - gPostColorFilterProgram.unbind(); - -} - -void LLPostProcess::createColorFilterShader(void) -{ - /// Define uniform names - colorFilterUniforms["RenderTexture"] = 0; - colorFilterUniforms["brightness"] = 0; - colorFilterUniforms["contrast"] = 0; - colorFilterUniforms["contrastBase"] = 0; - colorFilterUniforms["saturation"] = 0; - colorFilterUniforms["lumWeights"] = 0; -} - -void LLPostProcess::applyNightVisionShader(void) -{ - // KL re-enabled and moved back to newview - gPostNightVisionProgram.bind(); - - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); - - getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject); - U32 sceneRenderTexture = mSceneRenderTexture->getTexName() ; // KL - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture); - glUniform1iARB(nightVisionUniforms["RenderTexture"], 0); - - gGL.getTexUnit(1)->activate(); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - U32 noiseTexture = mNoiseTexture->getTexName(); //KL - gGL.getTexUnit(1)->bindManual(LLTexUnit::TT_TEXTURE, noiseTexture); - glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1); - - - glUniform1fARB(nightVisionUniforms["brightMult"], tweaks.getBrightMult()); - glUniform1fARB(nightVisionUniforms["noiseStrength"], tweaks.getNoiseStrength()); - noiseTextureScale = 0.01f + ((101.f - tweaks.getNoiseSize()) / 100.f); - noiseTextureScale *= (screenH / NOISE_SIZE); - - - glUniform3fARB(nightVisionUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); - - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_REPLACE); - LLGLDepthTest depth(GL_FALSE); - - /// Draw a screen space quad - drawOrthoQuad(screenW, screenH, QUAD_NOISE); - gPostNightVisionProgram.unbind(); - gGL.getTexUnit(0)->activate(); - -} - -void LLPostProcess::createNightVisionShader(void) -{ - /// Define uniform names - nightVisionUniforms["RenderTexture"] = 0; - nightVisionUniforms["NoiseTexture"] = 0; - nightVisionUniforms["brightMult"] = 0; - nightVisionUniforms["noiseStrength"] = 0; - nightVisionUniforms["lumWeights"] = 0; - - createNoiseTexture(mNoiseTexture); -} - -void LLPostProcess::applyBloomShader(void) -{ - -} - -void LLPostProcess::createBloomShader(void) -{ - createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); - - /// Create Bloom Extract Shader - bloomExtractUniforms["RenderTexture"] = 0; - bloomExtractUniforms["extractLow"] = 0; - bloomExtractUniforms["extractHigh"] = 0; - bloomExtractUniforms["lumWeights"] = 0; - - /// Create Bloom Blur Shader - bloomBlurUniforms["RenderTexture"] = 0; - bloomBlurUniforms["bloomStrength"] = 0; - bloomBlurUniforms["texelSize"] = 0; - bloomBlurUniforms["blurDirection"] = 0; - bloomBlurUniforms["blurWidth"] = 0; -} - -void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog) -{ - /// Find uniform locations and insert into map - std::map<const char *, GLuint>::iterator i; - for (i = uniforms.begin(); i != uniforms.end(); ++i){ - i->second = glGetUniformLocationARB(prog, i->first); - } -} - -void LLPostProcess::doEffects(void) -{ - /// Save GL State - glPushAttrib(GL_ALL_ATTRIB_BITS); - glPushClientAttrib(GL_ALL_ATTRIB_BITS); - - /// Copy the screen buffer to the render texture - { - U32 tex = mSceneRenderTexture->getTexName() ; - copyFrameBuffer(tex, screenW, screenH); - } - - /// Clear the frame buffer. - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - /// Change to an orthogonal view - viewOrthogonal(screenW, screenH); - - checkError(); - applyShaders(); - - LLGLSLShader::bindNoShader(); - checkError(); - - /// Change to a perspective view - viewPerspective(); - - /// Reset GL State - glPopClientAttrib(); - glPopAttrib(); - checkError(); -} - -void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height) -{ - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture); - glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); -} - -void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type) -{ - - float noiseX = 0.f; - float noiseY = 0.f; - float screenRatio = 1.0f; - - if (type == QUAD_NOISE){ - noiseX = ((float) rand() / (float) RAND_MAX); - noiseY = ((float) rand() / (float) RAND_MAX); - screenRatio = (float) width / (float) height; - } - - - glBegin(GL_QUADS); - if (type != QUAD_BLOOM_EXTRACT){ - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height); - } else { - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height * 2.0f); - } - if (type == QUAD_NOISE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, - noiseX, - noiseTextureScale + noiseY); - } else if (type == QUAD_BLOOM_COMBINE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, (GLfloat) height * 0.5f); - } - glVertex2f(0.f, (GLfloat) screenH - height); - - if (type != QUAD_BLOOM_EXTRACT){ - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); - } else { - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); - } - if (type == QUAD_NOISE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, - noiseX, - noiseY); - } else if (type == QUAD_BLOOM_COMBINE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, 0.f); - } - glVertex2f(0.f, (GLfloat) height + (screenH - height)); - - - if (type != QUAD_BLOOM_EXTRACT){ - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, 0.f); - } else { - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, 0.f); - } - if (type == QUAD_NOISE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, - screenRatio * noiseTextureScale + noiseX, - noiseY); - } else if (type == QUAD_BLOOM_COMBINE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, 0.f); - } - glVertex2f((GLfloat) width, (GLfloat) height + (screenH - height)); - - - if (type != QUAD_BLOOM_EXTRACT){ - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, (GLfloat) height); - } else { - glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, (GLfloat) height * 2.0f); - } - if (type == QUAD_NOISE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, - screenRatio * noiseTextureScale + noiseX, - noiseTextureScale + noiseY); - } else if (type == QUAD_BLOOM_COMBINE){ - glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, (GLfloat) height * 0.5f); - } - glVertex2f((GLfloat) width, (GLfloat) screenH - height); - glEnd(); - -} - -void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height) -{ - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f ); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); -} - -void LLPostProcess::viewPerspective(void) -{ - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - glPopMatrix(); -} - -void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height) -{ - viewPerspective(); - viewOrthogonal(width, height); -} - -void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height) -{ - std::vector<GLubyte> data(width * height * 4, 0) ; - - texture = new LLImageGL(FALSE) ; - if(texture->createGLTexture()) - { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture->getTexName()); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - } -} - -void LLPostProcess::createNoiseTexture(LLPointer<LLImageGL>& texture) -{ - std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE); - for (unsigned int i = 0; i < NOISE_SIZE; i++){ - for (unsigned int k = 0; k < NOISE_SIZE; k++){ - buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); - } - } - - texture = new LLImageGL(FALSE) ; - if(texture->createGLTexture()) - { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName()); - LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); - } -} - -bool LLPostProcess::checkError(void) -{ - GLenum glErr; - bool retCode = false; - - glErr = glGetError(); - while (glErr != GL_NO_ERROR) - { - // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl; - char const * err_str_raw = (const char *) gluErrorString(glErr); - - if(err_str_raw == NULL) - { - std::ostringstream err_builder; - err_builder << "unknown error number " << glErr; - mShaderErrorString = err_builder.str(); - } - else - { - mShaderErrorString = err_str_raw; - } - - retCode = true; - glErr = glGetError(); - } - return retCode; -} - -void LLPostProcess::checkShaderError(GLhandleARB shader) -{ - GLint infologLength = 0; - GLint charsWritten = 0; - GLchar *infoLog; - - checkError(); // Check for OpenGL errors - - glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength); - - checkError(); // Check for OpenGL errors - - if (infologLength > 0) - { - infoLog = (GLchar *)malloc(infologLength); - if (infoLog == NULL) - { - /// Could not allocate infolog buffer - return; - } - glGetInfoLogARB(shader, infologLength, &charsWritten, infoLog); - // shaderErrorLog << (char *) infoLog << std::endl; - mShaderErrorString = (char *) infoLog; - free(infoLog); - } - checkError(); // Check for OpenGL errors -} \ No newline at end of file diff --git a/linden/indra/newview/llpostprocess.h b/linden/indra/newview/llpostprocess.h deleted file mode 100644 index d6926e48c..000000000 --- a/linden/indra/newview/llpostprocess.h +++ /dev/null @@ -1,274 +0,0 @@ -/** - * @file llpostprocess.h - * @brief LLPostProcess class definition - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_POSTPROCESS_H -#define LL_POSTPROCESS_H - -#include <map> -#include <fstream> -#include "llgl.h" -#include "llglheaders.h" - -class LLPostProcess -{ -public: - - typedef enum _QuadType { - QUAD_NORMAL, - QUAD_NOISE, - QUAD_BLOOM_EXTRACT, - QUAD_BLOOM_COMBINE - } QuadType; - - /// GLSL Shader Encapsulation Struct - typedef std::map<const char *, GLuint> glslUniforms; - - struct PostProcessTweaks : public LLSD { - inline PostProcessTweaks() : LLSD(LLSD::emptyMap()) - { - } - - inline LLSD & brightMult() { - return (*this)["brightness_multiplier"]; - } - - inline LLSD & noiseStrength() { - return (*this)["noise_strength"]; - } - - inline LLSD & noiseSize() { - return (*this)["noise_size"]; - } - - inline LLSD & extractLow() { - return (*this)["extract_low"]; - } - - inline LLSD & extractHigh() { - return (*this)["extract_high"]; - } - - inline LLSD & bloomWidth() { - return (*this)["bloom_width"]; - } - - inline LLSD & bloomStrength() { - return (*this)["bloom_strength"]; - } - - inline LLSD & brightness() { - return (*this)["brightness"]; - } - - inline LLSD & contrast() { - return (*this)["contrast"]; - } - - inline LLSD & contrastBaseR() { - return (*this)["contrast_base"][0]; - } - - inline LLSD & contrastBaseG() { - return (*this)["contrast_base"][1]; - } - - inline LLSD & contrastBaseB() { - return (*this)["contrast_base"][2]; - } - - inline LLSD & contrastBaseIntensity() { - return (*this)["contrast_base"][3]; - } - - inline LLSD & saturation() { - return (*this)["saturation"]; - } - - inline LLSD & useNightVisionShader() { - return (*this)["enable_night_vision"]; - } - - inline LLSD & useBloomShader() { - return (*this)["enable_bloom"]; - } - - inline LLSD & useColorFilter() { - return (*this)["enable_color_filter"]; - } - - - inline F32 getBrightMult() const { - return F32((*this)["brightness_multiplier"].asReal()); - } - - inline F32 getNoiseStrength() const { - return F32((*this)["noise_strength"].asReal()); - } - - inline F32 getNoiseSize() const { - return F32((*this)["noise_size"].asReal()); - } - - inline F32 getExtractLow() const { - return F32((*this)["extract_low"].asReal()); - } - - inline F32 getExtractHigh() const { - return F32((*this)["extract_high"].asReal()); - } - - inline F32 getBloomWidth() const { - return F32((*this)["bloom_width"].asReal()); - } - - inline F32 getBloomStrength() const { - return F32((*this)["bloom_strength"].asReal()); - } - - inline F32 getBrightness() const { - return F32((*this)["brightness"].asReal()); - } - - inline F32 getContrast() const { - return F32((*this)["contrast"].asReal()); - } - - inline F32 getContrastBaseR() const { - return F32((*this)["contrast_base"][0].asReal()); - } - - inline F32 getContrastBaseG() const { - return F32((*this)["contrast_base"][1].asReal()); - } - - inline F32 getContrastBaseB() const { - return F32((*this)["contrast_base"][2].asReal()); - } - - inline F32 getContrastBaseIntensity() const { - return F32((*this)["contrast_base"][3].asReal()); - } - - inline F32 getSaturation() const { - return F32((*this)["saturation"].asReal()); - } - - }; - - bool initialized; - PostProcessTweaks tweaks; - - // the map of all availible effects - LLSD mAllEffects; - -private: - LLPointer<LLImageGL> mSceneRenderTexture ; - LLPointer<LLImageGL> mNoiseTexture ; - LLPointer<LLImageGL> mTempBloomTexture ; - - - -public: - LLPostProcess(void); - - ~LLPostProcess(void); - - void apply(unsigned int width, unsigned int height); - void invalidate() ; - - /// Perform global initialization for this class. - static void initClass(void); - - // Cleanup of global data that's only inited once per class. - static void cleanupClass(); - - void setSelectedEffect(std::string const & effectName); - - inline std::string const & getSelectedEffect(void) const { - return mSelectedEffectName; - } - - void saveEffect(std::string const & effectName); - -private: - /// read in from file - std::string mShaderErrorString; - unsigned int screenW; - unsigned int screenH; - - float noiseTextureScale; - - /// Shader Uniforms - glslUniforms nightVisionUniforms; - glslUniforms bloomExtractUniforms; - glslUniforms bloomBlurUniforms; - glslUniforms colorFilterUniforms; - - // the name of currently selected effect in mAllEffects - //invariant: tweaks == mAllEffects[mSelectedEffectName] - std::string mSelectedEffectName; - - /// General functions - void initialize(unsigned int width, unsigned int height); - void doEffects(void); - void applyShaders(void); - bool shadersEnabled(void); - - /// Night Vision Functions - void createNightVisionShader(void); - void applyNightVisionShader(void); - - /// Bloom Functions - void createBloomShader(void); - void applyBloomShader(void); - - /// Color Filter Functions - void createColorFilterShader(void); - void applyColorFilterShader(void); - - /// OpenGL Helper Functions - void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog); - void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height); - void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height); - void createNoiseTexture(LLPointer<LLImageGL>& texture); - bool checkError(void); - void checkShaderError(GLhandleARB shader); - void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type); - void viewOrthogonal(unsigned int width, unsigned int height); - void changeOrthogonal(unsigned int width, unsigned int height); - void viewPerspective(void); -}; - -extern LLPostProcess * gPostProcess; - - -#endif // LL_POSTPROCESS_H diff --git a/linden/indra/newview/llpreview.cpp b/linden/indra/newview/llpreview.cpp index 019bd5fca..f679a7505 100644 --- a/linden/indra/newview/llpreview.cpp +++ b/linden/indra/newview/llpreview.cpp @@ -641,7 +641,6 @@ void LLPreview::setAssetId(const LLUUID& asset_id) LLViewerObject* object = gObjectList.findObject(mObjectUUID); if(NULL == object) { - llwarns << "LLPreview::setAssetId() called on unrecognized object, UUID : " << mObjectUUID << llendl; return; } object->updateViewerInventoryAsset(item, asset_id); diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index 44ac8fd5a..16f79ec58 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -766,7 +766,7 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab } else { - llwarns << "LLSelectMgr::add face " << face << " out-of-range" << llendl; + llerrs << "LLSelectMgr::add face " << face << " out-of-range" << llendl; return; } @@ -1189,7 +1189,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) } else { - llwarns << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl; + llerrs << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl; return; } @@ -1212,7 +1212,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) else { // ...out of range face - llwarns << "LLSelectMgr::remove - TE " << te << " out of range" << llendl; + llerrs << "LLSelectMgr::remove - TE " << te << " out of range" << llendl; } updateSelectionCenter(); @@ -1711,7 +1711,7 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright) } sendfunc(fullbright); getSelection()->applyToObjects(&sendfunc); } -/* + void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url) { U8 media_flags = LLTextureEntry::MF_NONE; @@ -1754,7 +1754,7 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& } sendfunc(media_type, media_url); getSelection()->applyToObjects(&sendfunc); } -*/ + void LLSelectMgr::selectionSetGlow(F32 glow) { struct f1 : public LLSelectedTEFunctor @@ -3359,7 +3359,7 @@ void LLSelectMgr::packPermissionsHead(void* user_data) /* void LLSelectMgr::sendSelect() { - llwarns << "Not implemented" << llendl; + llerrs << "Not implemented" << llendl; } */ @@ -4183,7 +4183,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name, break; default: - llwarns << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl; + llerrs << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl; } // bail if nothing selected @@ -4590,6 +4590,11 @@ extern LLGLdouble gGLModelView[16]; void LLSelectMgr::updateSilhouettes() { + if (!mRenderSilhouettes || !LLSelectMgr::sRenderSelectionHighlights) + { + return; + } + S32 num_sils_genned = 0; LLVector3d cameraPos = gAgent.getCameraPositionGlobal(); @@ -5803,7 +5808,8 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) } if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) || - (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove())) + (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove()) || + (gSavedSettings.getBOOL("SelectCopyableOnly") && !object->permCopy())) { // only select my own objects return FALSE; diff --git a/linden/indra/newview/llselectmgr.h b/linden/indra/newview/llselectmgr.h index 0c57f7b65..c19d33d26 100644 --- a/linden/indra/newview/llselectmgr.h +++ b/linden/indra/newview/llselectmgr.h @@ -503,7 +503,7 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr> void selectionSetTexGen( U8 texgen ); void selectionSetShiny( U8 shiny ); void selectionSetFullbright( U8 fullbright ); -// void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); + void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); void selectionSetClickAction(U8 action); void selectionSetIncludeInSearch(bool include_in_search); void selectionSetGlow(const F32 glow); diff --git a/linden/indra/newview/llsky.cpp b/linden/indra/newview/llsky.cpp index b779aa0f8..ac7e865de 100644 --- a/linden/indra/newview/llsky.cpp +++ b/linden/indra/newview/llsky.cpp @@ -422,20 +422,6 @@ void LLSky::updateFog(const F32 distance) void LLSky::updateCull() { - /*if (mVOSkyp.notNull() && mVOSkyp->mDrawable.notNull()) - { - gPipeline.markVisible(mVOSkyp->mDrawable); - } - else - { - llinfos << "No sky drawable!" << llendl; - }*/ - - /*if (mVOGroundp.notNull() && mVOGroundp->mDrawable.notNull()) - { - gPipeline.markVisible(mVOGroundp->mDrawable); - }*/ - // *TODO: do culling for wl sky properly -Brad } diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index 34ed292c6..c1d5ff309 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp @@ -48,7 +48,6 @@ #include "llrender.h" #include "lloctree.h" #include "llvoavatar.h" -#include "lltextureatlas.h" const F32 SG_OCCLUSION_FUDGE = 0.25f; #define SG_DISCARD_TOLERANCE 0.01f @@ -96,7 +95,7 @@ void sg_assert(BOOL expr) #if LL_OCTREE_PARANOIA_CHECK if (!expr) { - llwarns << "Octree invalid!" << llendl; + llerrs << "Octree invalid!" << llendl; } #endif } @@ -282,10 +281,10 @@ S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3 LLSpatialGroup::~LLSpatialGroup() { - /*if (sNoDelete) + if (sNoDelete) { - llwarns << "Illegal deletion of LLSpatialGroup!" << llendl; - }*/ + llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; + } if (isState(DEAD)) { @@ -303,129 +302,6 @@ LLSpatialGroup::~LLSpatialGroup() LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); clearDrawMap(); - clearAtlasList() ; -} - -BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp) -{ - S8 type = atlasp->getComponents() - 1 ; - for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) - { - if(atlasp == *iter) - { - return TRUE ; - } - } - return FALSE ; -} - -void LLSpatialGroup::addAtlas(LLTextureAtlas* atlasp, S8 recursive_level) -{ - if(!hasAtlas(atlasp)) - { - mAtlasList[atlasp->getComponents() - 1].push_back(atlasp) ; - atlasp->addSpatialGroup(this) ; - } - - --recursive_level; - if(recursive_level)//levels propagating up. - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - parent->addAtlas(atlasp, recursive_level) ; - } - } -} - -void LLSpatialGroup::removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group, S8 recursive_level) -{ - mAtlasList[atlasp->getComponents() - 1].remove(atlasp) ; - if(remove_group) - { - atlasp->removeSpatialGroup(this) ; - } - - --recursive_level; - if(recursive_level)//levels propagating up. - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - parent->removeAtlas(atlasp, recursive_level) ; - } - } -} - -void LLSpatialGroup::clearAtlasList() -{ - std::list<LLTextureAtlas*>::iterator iter ; - for(S8 i = 0 ; i < 4 ; i++) - { - if(mAtlasList[i].size() > 0) - { - for(iter = mAtlasList[i].begin(); iter != mAtlasList[i].end() ; ++iter) - { - ((LLTextureAtlas*)*iter)->removeSpatialGroup(this) ; - } - mAtlasList[i].clear() ; - } - } -} - -LLTextureAtlas* LLSpatialGroup::getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level) -{ - S8 type = ncomponents - 1 ; - if(mAtlasList[type].size() > 0) - { - for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) - { - if(!((LLTextureAtlas*)*iter)->isFull(to_be_reserved)) - { - return *iter ; - } - } - } - - --recursive_level; - if(recursive_level) - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - return parent->getAtlas(ncomponents, to_be_reserved, recursive_level) ; - } - } - return NULL ; -} - -void LLSpatialGroup::setCurUpdatingSlot(LLTextureAtlasSlot* slotp) -{ - mCurUpdatingSlotp = slotp; - - //if(!hasAtlas(mCurUpdatingSlotp->getAtlas())) - //{ - // addAtlas(mCurUpdatingSlotp->getAtlas()) ; - //} -} - -LLTextureAtlasSlot* LLSpatialGroup::getCurUpdatingSlot(LLViewerImage* imagep, S8 recursive_level) -{ - if(gFrameCount && mCurUpdatingTime == gFrameCount && mCurUpdatingTexture == imagep) - { - return mCurUpdatingSlotp ; - } - - //--recursive_level ; - //if(recursive_level) - //{ - // LLSpatialGroup* parent = getParent() ; - // if(parent) - // { - // return parent->getCurUpdatingSlot(imagep, recursive_level) ; - // } - //} - return NULL ; } void LLSpatialGroup::clearDrawMap() @@ -472,7 +348,7 @@ void LLSpatialGroup::validate() LLSpatialPartition* part = drawable->asPartition(); if (!part) { - llwarns << "Drawable reports it is a spatial bridge but not a partition." << llendl; + llerrs << "Drawable reports it is a spatial bridge but not a partition." << llendl; } LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); group->validate(); @@ -535,7 +411,7 @@ class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> if (mInheritedMask && !group->isState(mInheritedMask)) { - llwarns << "Spatial group failed inherited mask test." << llendl; + llerrs << "Spatial group failed inherited mask test." << llendl; } if (group->isState(LLSpatialGroup::DIRTY)) @@ -551,7 +427,7 @@ class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> { if (!parent->isState(state)) { - llwarns << "Spatial group failed parent state check." << llendl; + llerrs << "Spatial group failed parent state check." << llendl; } parent = parent->getParent(); } @@ -572,39 +448,39 @@ void validate_draw_info(LLDrawInfo& params) #if LL_OCTREE_PARANOIA_CHECK if (params.mVertexBuffer.isNull()) { - llwarns << "Draw batch has no vertex buffer." << llendl; + llerrs << "Draw batch has no vertex buffer." << llendl; } //bad range if (params.mStart >= params.mEnd) { - llwarns << "Draw batch has invalid range." << llendl; + llerrs << "Draw batch has invalid range." << llendl; } if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts()) { - llwarns << "Draw batch has buffer overrun error." << llendl; + llerrs << "Draw batch has buffer overrun error." << llendl; } if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices()) { - llwarns << "Draw batch has index buffer ovverrun error." << llendl; + llerrs << "Draw batch has index buffer ovverrun error." << llendl; } //bad indices - U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); // KL 16 indices for SD not 32 + U32* indicesp = (U32*) params.mVertexBuffer->getIndicesPointer(); if (indicesp) { for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) { - if (indicesp[i] < (U16)params.mStart) //KL + if (indicesp[i] < params.mStart) { - llwarns << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; + llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; } - if (indicesp[i] > (U16)params.mEnd) // KL + if (indicesp[i] > params.mEnd) { - llwarns << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; + llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; } } } @@ -664,7 +540,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc drawablep->setSpatialGroup(this); validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY | DISCARD_QUERY); - gPipeline.markRebuild(this, TRUE); if (drawablep->isSpatialBridge()) { mBridgeList.push_back((LLSpatialBridge*) drawablep); @@ -697,23 +572,22 @@ void LLSpatialGroup::rebuildMesh() void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - /*if (!gPipeline.hasRenderType(mDrawableType)) + if (!gPipeline.hasRenderType(mDrawableType)) { return; - }*/ + } + + if (!LLPipeline::sSkipUpdate && group->changeLOD()) + { + group->mLastUpdateDistance = group->mDistance; + group->mLastUpdateViewAngle = group->mViewAngle; + } if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) { - /*if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && mRenderByGroup) - { - llwarns << "WTF?" << llendl; - }*/ return; } - group->mLastUpdateDistance = group->mDistance; - group->mLastUpdateViewAngle = group->mViewAngle; - LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); group->clearDrawMap(); @@ -751,7 +625,6 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->clearState(LLSpatialGroup::GEOM_DIRTY); } - void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) { @@ -790,11 +663,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO drawablep = *i; minMax = drawablep->getSpatialExtents(); - update_min_max(newMin, newMax, minMax[0]); - update_min_max(newMin, newMax, minMax[1]); - //bin up the object - /*for (U32 i = 0; i < 3; i++) + for (U32 i = 0; i < 3; i++) { if (minMax[0].mV[i] < newMin.mV[i]) { @@ -804,7 +674,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO { newMax.mV[i] = minMax[1].mV[i]; } - }*/ + } } mObjectBounds[0] = (newMin + newMax) * 0.5f; @@ -868,10 +738,6 @@ LLSpatialGroup* LLSpatialGroup::getParent() return NULL; } - if(!mOctreeNode) - { - return NULL; - } OctreeNode* parent = mOctreeNode->getOctParent(); if (parent) @@ -897,8 +763,6 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { drawablep->setSpatialGroup(NULL); setState(GEOM_DIRTY); - gPipeline.markRebuild(this, TRUE); - if (drawablep->isSpatialBridge()) { for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i) @@ -935,7 +799,6 @@ void LLSpatialGroup::shift(const LLVector3 &offset) //if (!mSpatialPartition->mRenderByGroup) { setState(GEOM_DIRTY); - gPipeline.markRebuild(this, TRUE); } if (mOcclusionVerts) @@ -1085,11 +948,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds), mViewAngle(0.f), - mLastUpdateViewAngle(-1.f), - mAtlasList(4), - mCurUpdatingTime(0), - mCurUpdatingSlotp(NULL), - mCurUpdatingTexture (NULL) + mLastUpdateViewAngle(-1.f) { sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -1097,7 +956,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : sg_assert(mOctreeNode->getListenerCount() == 0); mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); - gPipeline.markRebuild(this, TRUE); mBounds[0] = LLVector3(node->getCenter()); mBounds[1] = LLVector3(node->getSize()); @@ -1117,7 +975,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #if !LL_RELEASE_FOR_DOWNLOAD if (isState(LLSpatialGroup::OBJECT_DIRTY)) { - llwarns << "Spatial group dirty on distance update." << llendl; + llerrs << "Spatial group dirty on distance update." << llendl; } #endif if (!getData().empty() && !LLSpatialPartition::sFreezeState) @@ -1156,7 +1014,6 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, //not setting this node to dirty would be a very good thing group->setState(LLSpatialGroup::ALPHA_DIRTY); - gPipeline.markRebuild(group, FALSE); } } } @@ -1193,18 +1050,6 @@ F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); } -F32 LLSpatialGroup::getUpdateUrgency() const -{ - if (!isVisible()) - { - return 0.f; - } - else - { - return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance; - } -} - BOOL LLSpatialGroup::needsUpdate() { return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; @@ -1312,8 +1157,6 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo void LLSpatialGroup::destroyGL() { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); - gPipeline.markRebuild(this, TRUE); - mLastUpdateTime = gFrameTimeSeconds; mVertexBuffer = NULL; mBufferMap.clear(); @@ -1517,8 +1360,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) -: mRenderByGroup(render_by_group) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); mOcclusionEnabled = TRUE; @@ -1530,7 +1372,7 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage = buffer_usage; mDepthMask = FALSE; mSlopRatio = 0.25f; - //mRenderByGroup = TRUE; + mRenderByGroup = TRUE; mInfiniteFarClip = FALSE; LLGLNamePool::registerPool(&sQueryPool); @@ -1826,76 +1668,13 @@ class LLOctreeCullVisExtents: public LLOctreeCullShadow return false; } - virtual void traverse(const LLSpatialGroup::TreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (earlyFail(group)) - { - return; - } - - if (mRes == 2) - { - //fully in, don't traverse further (won't effect extents - } - else if (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) - { //don't need to do frustum check - LLSpatialGroup::OctreeTraveler::traverse(n); - } - else - { - mRes = frustumCheck(group); - - if (mRes) - { //at least partially in, run on down - LLSpatialGroup::OctreeTraveler::traverse(n); - } - - mRes = 0; - } - } - virtual void processGroup(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) - { - llwarns << "WTF?" << llendl; - } - - if (mRes < 2) - { - - if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) == 2) - { - mEmpty = FALSE; - update_min_max(mMin, mMax, group->mObjectExtents[0]); - update_min_max(mMin, mMax, group->mObjectExtents[1]); - } - else - { - if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) - { //megaprims and water edge patches be damned! - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) - { - LLDrawable* drawable = i->get(); - const LLVector3* ext = drawable->getSpatialExtents(); - - if (mCamera->AABBInFrustum((ext[1]+ext[0])*0.5f, (ext[1]-ext[0])*0.5f)) - { - mEmpty = FALSE; - update_min_max(mMin, mMax, ext[0]); - update_min_max(mMin, mMax, ext[1]); - } - } - } - } - } - else - { + if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) + { //megaprims and water edge patches be damned! mEmpty = FALSE; - update_min_max(mMin, mMax, group->mExtents[0]); - update_min_max(mMin, mMax, group->mExtents[1]); + update_min_max(mMin, mMax, group->mObjectExtents[0]); + update_min_max(mMin, mMax, group->mObjectExtents[1]); } } @@ -2674,39 +2453,6 @@ void renderBatchSize(LLDrawInfo* params) pushVerts(params, LLVertexBuffer::MAP_VERTEX); } -void renderShadowFrusta(LLDrawInfo* params) -{ - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ADD); - - LLVector3 center = (params->mExtents[1]+params->mExtents[0])*0.5f; - LLVector3 size = (params->mExtents[1]-params->mExtents[0])*0.5f; - - if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size)) - { - glColor3f(1,0,0); - pushVerts(params, LLVertexBuffer::MAP_VERTEX); - } - if (gPipeline.mShadowCamera[5].AABBInFrustum(center, size)) - { - glColor3f(0,1,0); - pushVerts(params, LLVertexBuffer::MAP_VERTEX); - } - if (gPipeline.mShadowCamera[6].AABBInFrustum(center, size)) - { - glColor3f(0,0,1); - pushVerts(params, LLVertexBuffer::MAP_VERTEX); - } - if (gPipeline.mShadowCamera[7].AABBInFrustum(center, size)) - { - glColor3f(1,0,1); - pushVerts(params, LLVertexBuffer::MAP_VERTEX); - } - - gGL.setSceneBlendType(LLRender::BT_ALPHA); -} - - void renderLights(LLDrawable* drawablep) { if (!drawablep->isLight()) @@ -2842,9 +2588,6 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> //draw tight fit bounding boxes for spatial group if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) { - group->rebuildGeom(); - group->rebuildMesh(); - renderOctree(group); stop_glerror(); } @@ -2852,9 +2595,6 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> //render visibility wireframe if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { - group->rebuildGeom(); - group->rebuildMesh(); - gGL.flush(); glPushMatrix(); gGLLastMatrix = NULL; @@ -2880,19 +2620,6 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> LLVector3 nodeCenter = group->mBounds[0]; LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); - group->rebuildGeom(); - group->rebuildMesh(); - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) - { - if (!group->getData().empty()) - { - gGL.color3f(0,0,1); - drawBoxOutline(group->mObjectBounds[0], - group->mObjectBounds[1]); - } - } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) { LLDrawable* drawable = *i; @@ -2902,16 +2629,6 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> renderBoundingBox(drawable); } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BUILD_QUEUE)) - { - if (drawable->isState(LLDrawable::IN_REBUILD_Q2)) - { - gGL.color4f(0.6f, 0.6f, 0.1f, 1.f); - const LLVector3* ext = drawable->getSpatialExtents(); - drawBoxOutline((ext[0]+ext[1])*0.5f, (ext[1]-ext[0])*0.5f); - } - } - if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { renderTexturePriority(drawable); @@ -2932,9 +2649,9 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> renderRaycast(drawable); } - // LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); + LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get()); - /* if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) + if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) { renderAvatarCollisionVolumes(avatar); } @@ -2942,7 +2659,7 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET)) { renderAgentTarget(avatar); - } */ + } } @@ -2960,10 +2677,6 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> { renderBatchSize(draw_info); } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - renderShadowFrusta(draw_info); - } } } } @@ -3014,7 +2727,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } -void LLSpatialPartition::renderDebug() // KL SD version +void LLSpatialPartition::renderDebug() { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | LLPipeline::RENDER_DEBUG_OCCLUSION | @@ -3025,8 +2738,8 @@ void LLSpatialPartition::renderDebug() // KL SD version LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | LLPipeline::RENDER_DEBUG_RAYCAST | - LLPipeline::RENDER_DEBUG_BUILD_QUEUE | - LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | + LLPipeline::RENDER_DEBUG_AGENT_TARGET)) { return; } @@ -3061,12 +2774,6 @@ void LLSpatialPartition::renderDebug() // KL SD version render_debug.traverse(mOctree); } -void LLSpatialGroup::drawObjectBox(LLColor4 col) -{ - gGL.color4fv(col.mV); - drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); -} - BOOL LLSpatialPartition::isVisible(const LLVector3& v) { @@ -3211,12 +2918,11 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, con } LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLImageGL* gl_texture, LLViewerImage* texture, LLVertexBuffer* buffer, + LLViewerImage* texture, LLVertexBuffer* buffer, BOOL fullbright, U8 bump, BOOL particle, F32 part_size) : mVertexBuffer(buffer), - mTexture(gl_texture), - mViewerTexture(texture), + mTexture(texture), mTextureMatrix(NULL), mModelMatrix(NULL), mStart(start), @@ -3236,22 +2942,22 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, if (mStart >= mVertexBuffer->getRequestedVerts() || mEnd >= mVertexBuffer->getRequestedVerts()) { - llwarns << "Invalid draw info vertex range." << llendl; + llerrs << "Invalid draw info vertex range." << llendl; } if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) { - llwarns << "Invalid draw info index range." << llendl; + llerrs << "Invalid draw info index range." << llendl; } } LLDrawInfo::~LLDrawInfo() { - /*if (LLSpatialGroup::sNoDelete) + if (LLSpatialGroup::sNoDelete) { - llwarns << "LLDrawInfo deleted illegally!" << llendl; - }*/ + llerrs << "LLDrawInfo deleted illegally!" << llendl; + } if (mFace) { @@ -3456,7 +3162,7 @@ void LLCullResult::assertDrawMapsEmpty() { if (mRenderMapSize[i] != 0) { - llwarns << "Stale LLDrawInfo's in LLCullResult!" << llendl; + llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl; } } } diff --git a/linden/indra/newview/llspatialpartition.h b/linden/indra/newview/llspatialpartition.h index deb8b0eea..be0163b2b 100644 --- a/linden/indra/newview/llspatialpartition.h +++ b/linden/indra/newview/llspatialpartition.h @@ -52,8 +52,6 @@ class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; -class LLTextureAtlas; -class LLTextureAtlasSlot; S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); @@ -68,13 +66,12 @@ class LLDrawInfo : public LLRefCount public: LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLImageGL* gl_image, LLViewerImage* image, LLVertexBuffer* buffer, + LLViewerImage* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); LLPointer<LLVertexBuffer> mVertexBuffer; - LLPointer<LLImageGL> mTexture; - LLPointer<LLViewerImage> mViewerTexture; + LLPointer<LLViewerImage> mTexture; LLColor4U mGlowColor; S32 mDebugColor; const LLMatrix4* mTextureMatrix; @@ -162,13 +159,11 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t; typedef std::set<LLPointer<LLSpatialGroup> > sg_set_t; - typedef std::list<LLPointer<LLSpatialGroup> > sg_list_t; typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t; typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t; typedef std::map<U32, drawmap_elem_t > draw_map_t; typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t; - typedef std::map<LLPointer<LLImageGL>, buffer_list_t> buffer_texture_map_t; // KL render-pipeline -// typedef std::map<LLPointer<LLViewerImage>, buffer_list_t> buffer_texture_map_t; // KL standard + typedef std::map<LLPointer<LLViewerImage>, buffer_list_t> buffer_texture_map_t; typedef std::map<U32, buffer_texture_map_t> buffer_map_t; typedef LLOctreeListener<LLDrawable> BaseType; @@ -188,14 +183,6 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> } }; - struct CompareUpdateUrgency - { - bool operator()(const LLPointer<LLSpatialGroup> lhs, const LLPointer<LLSpatialGroup> rhs) - { - return lhs->getUpdateUrgency() > rhs->getUpdateUrgency(); - } - }; - struct CompareDepthGreater { bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs) @@ -222,10 +209,6 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> IMAGE_DIRTY = 0x00004000, OCCLUSION_DIRTY = 0x00008000, MESH_DIRTY = 0x00010000, - NEW_DRAWINFO = 0x00020000, - IN_BUILD_Q1 = 0x00040000, - IN_BUILD_Q2 = 0x00080000, - } eSpatialState; typedef enum @@ -269,7 +252,6 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> void updateDistance(LLCamera& camera); BOOL needsUpdate(); - F32 getUpdateUrgency() const; BOOL changeLOD(); void rebuildGeom(); void rebuildMesh(); @@ -279,8 +261,6 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> element_list& getData() { return mOctreeNode->getData(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } - void drawObjectBox(LLColor4 col); - //LISTENER FUNCTIONS virtual void handleInsertion(const TreeNode* node, LLDrawable* face); virtual void handleRemoval(const TreeNode* node, LLDrawable* face); @@ -289,36 +269,6 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable> virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); -//------------------- -//for atlas use -//------------------- - //atlas - void setCurUpdatingTime(U32 t) {mCurUpdatingTime = t ;} - U32 getCurUpdatingTime() const { return mCurUpdatingTime ;} - - void setCurUpdatingSlot(LLTextureAtlasSlot* slotp) ; - LLTextureAtlasSlot* getCurUpdatingSlot(LLViewerImage* imagep, S8 recursive_level = 3) ; - - void setCurUpdatingTexture(LLViewerImage* tex){ mCurUpdatingTexture = tex ;} - LLViewerImage* getCurUpdatingTexture() const { return mCurUpdatingTexture ;} - - BOOL hasAtlas(LLTextureAtlas* atlasp) ; - LLTextureAtlas* getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level = 3) ; - void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; - void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; - void clearAtlasList() ; -private: - U32 mCurUpdatingTime ; - //do not make the below two to use LLPointer - //because mCurUpdatingTime invalidates them automatically. - LLTextureAtlasSlot* mCurUpdatingSlotp ; - LLViewerImage* mCurUpdatingTexture ; - - std::vector< std::list<LLTextureAtlas*> > mAtlasList ; -//------------------- -//end for atlas use -//------------------- - protected: virtual ~LLSpatialGroup(); @@ -377,7 +327,7 @@ class LLSpatialPartition: public LLGeometryManager public: static BOOL sFreezeState; //if true, no spatialgroup state updates will be made - LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage); + LLSpatialPartition(U32 data_mask, U32 mBufferUsage = GL_STATIC_DRAW_ARB); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -423,7 +373,7 @@ class LLSpatialPartition: public LLGeometryManager BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; - const BOOL mRenderByGroup; + BOOL mRenderByGroup; U32 mLODSeed; U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) U32 mVertexDataMask; @@ -442,7 +392,7 @@ class LLSpatialBridge : public LLDrawable, public LLSpatialPartition public: typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t; - LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); + LLSpatialBridge(LLDrawable* root, U32 data_mask); virtual BOOL isSpatialBridge() const { return TRUE; } diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index a03ce1dd0..bd227721f 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -3735,7 +3735,7 @@ void init_start_screen(S32 location_id) } raw->expandToPowerOfTwo(); - gStartImageGL->createGLTexture(0, raw); + gStartImageGL->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); } diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index f6ef9c7a3..578b565fc 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp @@ -149,7 +149,7 @@ LLSurface::~LLSurface() } else { - llwarns << "Terrain pool not empty!" << llendl; + llerrs << "Terrain pool not empty!" << llendl; } } @@ -238,7 +238,6 @@ void LLSurface::createSTexture() if (!mSTexturep) { // Fill with dummy gray data. - // GL NOT ACTIVE HERE LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3); U8 *default_texture = raw->getData(); for (S32 i = 0; i < sTextureSize; i++) @@ -256,7 +255,6 @@ void LLSurface::createSTexture() gGL.getTexUnit(0)->bind(mSTexturep.get()); mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); gImageList.addImage(mSTexturep); - } } @@ -280,7 +278,7 @@ void LLSurface::createWaterTexture() mWaterTexturep = new LLViewerImage(raw, FALSE); mWaterTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mWaterTexturep); + gGL.getTexUnit(0)->bind(mWaterTexturep.get()); mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); gImageList.addImage(mWaterTexturep); } @@ -632,8 +630,6 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent) BOOL LLSurface::idleUpdate(F32 max_update_time) { -//SG2: LLMemType mt_ius(LLMemType::MTYPE_IDLE_UPDATE_SURFACE); - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN)) { return FALSE; @@ -1138,12 +1134,12 @@ LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const { if ((x < 0) || (x >= mPatchesPerEdge)) { - llwarns << "Asking for patch out of bounds" << llendl; + llerrs << "Asking for patch out of bounds" << llendl; return NULL; } if ((y < 0) || (y >= mPatchesPerEdge)) { - llwarns << "Asking for patch out of bounds" << llendl; + llerrs << "Asking for patch out of bounds" << llendl; return NULL; } @@ -1287,11 +1283,6 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, } } - if (!mWaterTexturep->getHasGLTexture()) - { - mWaterTexturep->createGLTexture(0, raw); - } - mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); return TRUE; } diff --git a/linden/indra/newview/llsurfacepatch.cpp b/linden/indra/newview/llsurfacepatch.cpp index 04b732a89..5fac5fd1e 100644 --- a/linden/indra/newview/llsurfacepatch.cpp +++ b/linden/indra/newview/llsurfacepatch.cpp @@ -712,7 +712,17 @@ BOOL LLSurfacePatch::updateTexture() if (mVObjp) { mVObjp->dirtyGeom(); - gPipeline.markGLRebuild(mVObjp); + } + updateCompositionStats(); + F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; + if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], + tex_patch_size, tex_patch_size)) + { + mSTexUpdate = FALSE; + + // Also generate the water texture + mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], + tex_patch_size, tex_patch_size); return TRUE; } } @@ -725,28 +735,6 @@ BOOL LLSurfacePatch::updateTexture() } } -void LLSurfacePatch::updateGL() // KL SD -{ - F32 meters_per_grid = getSurface()->getMetersPerGrid(); - F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); - - LLViewerRegion *regionp = getSurface()->getRegion(); - LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); - - LLVLComposition* comp = regionp->getComposition(); - - updateCompositionStats(); - F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], - tex_patch_size, tex_patch_size)) - { - mSTexUpdate = FALSE; - - // Also generate the water texture - mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], - tex_patch_size, tex_patch_size); - } -} // KL void LLSurfacePatch::dirtyZ() { diff --git a/linden/indra/newview/llsurfacepatch.h b/linden/indra/newview/llsurfacepatch.h index 1f9658d4a..7e84f7f6c 100644 --- a/linden/indra/newview/llsurfacepatch.h +++ b/linden/indra/newview/llsurfacepatch.h @@ -90,7 +90,6 @@ class LLSurfacePatch void updateCameraDistanceRegion( const LLVector3 &pos_region); void updateVisibility(); - void updateGL(); void dirtyZ(); // Dirty the z values of this patch void setHasReceivedData(); diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp index fb5be846d..5175cbb77 100644 --- a/linden/indra/newview/lltexlayer.cpp +++ b/linden/indra/newview/lltexlayer.cpp @@ -813,19 +813,14 @@ void LLTexLayerSet::requestUpdate() if( mUpdatesEnabled ) { createComposite(); - if (mComposite) - { - mComposite->requestUpdate(); - } + mComposite->requestUpdate(); } } void LLTexLayerSet::requestUpload() { - if (mComposite) - { - mComposite->requestUpload(); - } + createComposite(); + mComposite->requestUpload(); } void LLTexLayerSet::cancelUpload() @@ -839,15 +834,6 @@ void LLTexLayerSet::cancelUpload() void LLTexLayerSet::createComposite() { if( !mComposite ) - { - gPipeline.markGLRebuild(this); - } - //updateGL(); // KL -} - -void LLTexLayerSet::updateGL() -{ - if (!mComposite) { S32 width = mInfo->mWidth; S32 height = mInfo->mHeight; @@ -879,7 +865,7 @@ void LLTexLayerSet::setUpdatesEnabled( BOOL b ) void LLTexLayerSet::updateComposite() { createComposite(); - //mComposite->updateImmediate(); //KL exception here this needs fixing for S19 + mComposite->updateImmediate(); } LLTexLayerSetBuffer* LLTexLayerSet::getComposite() @@ -2118,7 +2104,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height ) // Create the GL texture, and then hang onto it for future use. if( mNeedsCreateTexture ) { - mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0); + mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerImageBoostLevel::TEXLAYER_CACHE); mNeedsCreateTexture = FALSE; gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -2574,7 +2560,7 @@ LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL i image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); } - image_gl->createGLTexture(0, image_raw, 0); + image_gl->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); gGL.getTexUnit(0)->bind(image_gl); image_gl->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/linden/indra/newview/lltexlayer.h b/linden/indra/newview/lltexlayer.h index b841fa3b0..020ba86f1 100644 --- a/linden/indra/newview/lltexlayer.h +++ b/linden/indra/newview/lltexlayer.h @@ -249,7 +249,7 @@ class LLTexLayerSetBuffer : public LLDynamicTexture // LLTexLayerSet // An ordered set of texture layers that get composited into a single texture. //----------------------------------------------------------------------------- -class LLTexLayerSet : public LLGLUpdate +class LLTexLayerSet { friend class LLTexLayerSetBuffer; public: @@ -284,7 +284,7 @@ class LLTexLayerSet : public LLGLUpdate LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } BOOL isVisible() const { return mIsVisible; } - /*virtual*/ void updateGL(); + public: static BOOL sHasCaches; diff --git a/linden/indra/newview/lltextureatlasmanager.cpp b/linden/indra/newview/lltextureatlasmanager.cpp deleted file mode 100644 index df6a39de4..000000000 --- a/linden/indra/newview/lltextureatlasmanager.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/** - * @file lltextureatlasmanager.cpp - * @brief LLTextureAtlasManager class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" -#include "llerror.h" -#include "llmath.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h" -#include "llspatialpartition.h" - -const S8 MAX_NUM_EMPTY_ATLAS = 2 ; -const F32 MIN_ATLAS_FULLNESS = 0.6f ; - -//********************************************************************************************* -//implementation of class LLTextureAtlasInfo -//********************************************************************************************* -LLTextureAtlasSlot::LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) : - mAtlasp(atlasp), - mGroupp(groupp), - mCol(col), - mRow(row), - mReservedSlotWidth(slot_width), - mValid(FALSE), - mUpdatedTime(0), - mTexCoordOffset(xoffset, yoffset), - mTexCoordScale(1.f, 1.f) -{ - llassert_always(mAtlasp || mGroupp || mReservedSlotWidth) ; -} - -LLTextureAtlasSlot::~LLTextureAtlasSlot() -{ - if(mAtlasp) - { - mAtlasp->releaseSlot(mCol, mRow, mReservedSlotWidth) ; - if(mAtlasp->isEmpty()) - { - LLTextureAtlasManager::getInstance()->releaseAtlas(mAtlasp) ; - } - mAtlasp = NULL ; - } -} - -//void LLTextureAtlasSlot::setAtlas(LLTextureAtlas* atlasp) -//{ -// mAtlasp = atlasp ; -//} -//void LLTextureAtlasSlot::setSlotPos(S16 col, S16 row) -//{ -// mCol = col ; -// mRow = row ; -//} -//void LLTextureAtlasSlot::setSlotWidth(S8 width) -//{ -// //slot is a square with each edge length a power-of-two number -// mReservedSlotWidth = width ; -//} -//void LLTextureAtlasSlot::setTexCoordOffset(F32 xoffset, F32 yoffset) -//{ -// mTexCoordOffset.mV[0] = xoffset ; -// mTexCoordOffset.mV[1] = yoffset ; -//} - -void LLTextureAtlasSlot::setSpatialGroup(LLSpatialGroup* groupp) -{ - mGroupp = groupp ; -} -void LLTextureAtlasSlot::setTexCoordScale(F32 xscale, F32 yscale) -{ - mTexCoordScale.mV[0] = xscale ; - mTexCoordScale.mV[1] = yscale ; -} -//********************************************************************************************* -//END of implementation of class LLTextureAtlasInfo -//********************************************************************************************* - -//********************************************************************************************* -//implementation of class LLTextureAtlasManager -//********************************************************************************************* -LLTextureAtlasManager::LLTextureAtlasManager() : - mAtlasMap(4), - mEmptyAtlasMap(4) -{ -} - -LLTextureAtlasManager::~LLTextureAtlasManager() -{ - for(S32 i = 0 ; i < 4 ; i++) - { - for(ll_texture_atlas_list_t::iterator j = mAtlasMap[i].begin() ; j != mAtlasMap[i].end() ; ++j) - { - *j = NULL ; - } - for(ll_texture_atlas_list_t::iterator j = mEmptyAtlasMap[i].begin() ; j != mEmptyAtlasMap[i].end() ; ++j) - { - *j = NULL ; - } - - mAtlasMap[i].clear() ; - mEmptyAtlasMap[i].clear() ; - } - mAtlasMap.clear() ; - mEmptyAtlasMap.clear() ; -} - -//return TRUE if qualified -BOOL LLTextureAtlasManager::canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) -{ - if(ncomponents < 1 || ncomponents > 4) - { - return FALSE ; - } - //only support GL_TEXTURE_2D - if(GL_TEXTURE_2D != target) - { - return FALSE ; - } - //real image size overflows - if(w < 8 || w > LLTextureAtlas::sMaxSubTextureSize || h < 8 || h > LLTextureAtlas::sMaxSubTextureSize) - { - return FALSE ; - } - - //if non-power-of-two number - if((w & (w - 1)) || (h & (h - 1))) - { - return FALSE ; - } - - return TRUE ; -} - -void LLTextureAtlasManager::releaseAtlas(LLTextureAtlas* atlasp) -{ - LLSpatialGroup* groupp = atlasp->getLastSpatialGroup() ; - while(groupp) - { - groupp->removeAtlas(atlasp, FALSE) ; - atlasp->removeLastSpatialGroup() ; - - groupp = atlasp->getLastSpatialGroup() ; - } - - S8 type = atlasp->getComponents() - 1 ; - //insert to the empty list - if(mEmptyAtlasMap[type].size() < MAX_NUM_EMPTY_ATLAS) - { - mEmptyAtlasMap[type].push_back(atlasp) ; - } - - //delete the atlasp - mAtlasMap[type].remove(atlasp) ; -} - -// -//this function reserves an appropriate slot from atlas pool for an image. -//return non-NULL if succeeds. -//Note: -//1, this function does not check if the image this slot assigned for qualifies for atlas or not, -// call LLTextureAtlasManager::canAddToAtlas(...) to do the check before calling this function. -//2, this function also dose not check if the image is already in atlas. It always assigns a new slot anyway. -//3, this function tries to group sub-textures from same spatial group into ONE atlas to improve render batching. -// -LLPointer<LLTextureAtlasSlot> LLTextureAtlasManager::reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, - LLSpatialGroup* groupp, LLViewerImage* imagep) -{ - if(!groupp) - { - //do not insert to atlas if does not have a group. - return NULL ; - } - - //bits_len must <= 8 and is a power of two number, i.e.: must be one of these numbers: 1, 2, 4, 8. - if(sub_texture_size > LLTextureAtlas::sMaxSubTextureSize) - { - sub_texture_size = LLTextureAtlas::sMaxSubTextureSize ; - } - S8 bits_len = sub_texture_size / LLTextureAtlas::sSlotSize ; - if(bits_len < 1) - { - bits_len = 1 ; - } - - S16 col = -1, row = -1; - S8 total_bits = bits_len * bits_len ; - - //insert to the atlas reserved by the same spatial group - LLPointer<LLTextureAtlas> atlasp = groupp->getAtlas(ncomponents, total_bits) ; - if(atlasp.notNull()) - { - if(!atlasp->getNextAvailableSlot(bits_len, col, row)) - { - //failed - atlasp = NULL ; - } - } - - //search an atlas to fit for 'size' - if(!atlasp) - { - S8 atlas_index = ncomponents - 1 ; - ll_texture_atlas_list_t::iterator iter = mAtlasMap[atlas_index].begin() ; - for(; iter != mAtlasMap[atlas_index].end(); ++iter) - { - LLTextureAtlas* cur = (LLTextureAtlas*)*iter ; - if(cur->getFullness() < MIN_ATLAS_FULLNESS)//this atlas is empty enough for this group to insert more sub-textures later if necessary. - { - if(cur->getNextAvailableSlot(bits_len, col, row)) - { - atlasp = cur ; - groupp->addAtlas(atlasp) ; - break ; - } - } - } - } - - //create a new atlas if necessary - if(!atlasp) - { - if(mEmptyAtlasMap[ncomponents - 1].size() > 0) - { - //there is an empty one - atlasp = mEmptyAtlasMap[ncomponents - 1].back() ; - mEmptyAtlasMap[ncomponents - 1].pop_back() ; - } - else - { - atlasp = new LLTextureAtlas(ncomponents, 16) ; - } - mAtlasMap[ncomponents - 1].push_back(atlasp) ; - atlasp->getNextAvailableSlot(bits_len, col, row) ; - groupp->addAtlas(atlasp) ; - } - - F32 xoffset, yoffset ; - atlasp->getTexCoordOffset(col, row, xoffset, yoffset) ; - LLPointer<LLTextureAtlasSlot> slot_infop = new LLTextureAtlasSlot(atlasp, groupp, col, row, xoffset, yoffset, bits_len) ; - - return slot_infop ; -} - -//********************************************************************************************* -//END of implementation of class LLTextureAtlasManager -//********************************************************************************************* diff --git a/linden/indra/newview/lltextureatlasmanager.h b/linden/indra/newview/lltextureatlasmanager.h deleted file mode 100644 index 70689bf33..000000000 --- a/linden/indra/newview/lltextureatlasmanager.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file lltextureatlasmanager.h - * @brief LLTextureAtlasManager base class. - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - - -#ifndef LL_TEXTUREATLASMANAGER_H -#define LL_TEXTUREATLASMANAGER_H - -#include "llmemory.h" - -class LLSpatialGroup ; -class LLViewerImage ; - -//just use it as a structure. -class LLTextureAtlasSlot : public LLRefCount -{ -public: - LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) ; - -protected: - virtual ~LLTextureAtlasSlot(); - -public: - - // - //do not allow to change those values - // - //void setAtlas(LLTextureAtlas* atlasp) ; - //void setSlotPos(S16 col, S16 row) ; - //void setSlotWidth(S8 width) ; - //void setTexCoordOffset(F32 xoffser, F32 yoffset) ; - // - - void setSpatialGroup(LLSpatialGroup* groupp) ; - void setTexCoordScale(F32 xscale, F32 yscale) ; - void setValid() {mValid = TRUE ;} - - LLTextureAtlas* getAtlas()const {return mAtlasp;} - LLSpatialGroup* getSpatialGroup() const {return mGroupp ;} - S16 getSlotCol()const {return mCol;} - S16 getSlotRow()const {return mRow;} - S8 getSlotWidth()const{return mReservedSlotWidth;} - BOOL isValid()const { return mValid;} - const LLVector2* getTexCoordOffset()const {return &mTexCoordOffset;} - const LLVector2* getTexCoordScale() const {return &mTexCoordScale;} - - void setUpdatedTime(U32 t) {mUpdatedTime = t;} - U32 getUpdatedTime()const {return mUpdatedTime;} - -private: - LLTextureAtlas* mAtlasp; - S16 mCol ;//col of the slot - S16 mRow ;//row of the slot - S8 mReservedSlotWidth ; //slot is a square with each edge length a power-of-two number - LLSpatialGroup* mGroupp ; - BOOL mValid ; - - LLVector2 mTexCoordOffset ; - LLVector2 mTexCoordScale ; - - U32 mUpdatedTime ; -} ; - -class LLTextureAtlasManager : public LLSingleton<LLTextureAtlasManager> -{ -private: - typedef std::list<LLPointer<LLTextureAtlas> > ll_texture_atlas_list_t ; - -public: - LLTextureAtlasManager(); - ~LLTextureAtlasManager(); - - LLPointer<LLTextureAtlasSlot> reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, - LLSpatialGroup* groupp, LLViewerImage* imagep) ; - void releaseAtlas(LLTextureAtlas* atlasp); - - BOOL canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) ; - -private: - std::vector<ll_texture_atlas_list_t> mAtlasMap ; - std::vector<ll_texture_atlas_list_t> mEmptyAtlasMap ; //delay some empty atlases deletion to avoid possible creation of new atlas immediately. -}; - -#endif diff --git a/linden/indra/newview/lltextureview.cpp b/linden/indra/newview/lltextureview.cpp index 903a6e5e1..04cebf580 100644 --- a/linden/indra/newview/lltextureview.cpp +++ b/linden/indra/newview/lltextureview.cpp @@ -57,16 +57,14 @@ extern F32 texmem_lower_bound_scale; LLTextureView *gTextureView = NULL; -LLTextureSizeView *gTextureSizeView = NULL; -LLTextureSizeView *gTextureCategoryView = NULL; //static std::set<LLViewerImage*> LLTextureView::sDebugImages; //////////////////////////////////////////////////////////////////////////// -static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download]"); -static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download]"); +static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max"); +static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max"); static std::string title_string2("State"); static std::string title_string3("Pkt Bnd"); static std::string title_string4(" W x H (Dis) Mem"); @@ -203,14 +201,13 @@ void LLTextureBar::draw() } else { - tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x) %1.2f", + tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)", uuid_str.c_str(), mImagep->mMaxVirtualSize, mImagep->mDesiredDiscardLevel, mImagep->mRequestedDiscardLevel, mImagep->getDecodePriority(), - mImagep->mFetchPriority, - mImagep->mDownloadProgress); + mImagep->mFetchPriority); } LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(), @@ -256,7 +253,7 @@ void LLTextureBar::draw() // Draw the progress bar. S32 bar_width = 100; - S32 bar_left = 330; + S32 bar_left = 260; left = bar_left; right = left + bar_width; @@ -265,7 +262,7 @@ void LLTextureBar::draw() F32 data_progress = mImagep->mDownloadProgress; - if (data_progress > 0.0f && data_progress <= 1.0f) + if (data_progress > 0.0f) { // Downloaded bytes right = left + llfloor(data_progress * (F32)bar_width); @@ -275,16 +272,6 @@ void LLTextureBar::draw() gl_rect_2d(left, top, right, bottom); } } - else if (data_progress > 1.0f) - { - // Small cached textures generate this oddity. SNOW-168 - right = left + bar_width; - if (right > left) - { - gGL.color4f(0.f, 0.33f, 0.f, 0.75f); - gl_rect_2d(left, top, right, bottom); - } - } S32 pip_width = 6; S32 pip_space = 14; @@ -399,9 +386,9 @@ class LLGLTexMemBar : public LLView void LLGLTexMemBar::draw() { - S32 bound_mem = (LLViewerImage::sBoundTextureMemoryInBytes >> 20); + S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes); S32 max_bound_mem = LLViewerImage::sMaxBoundTextureMemInMegaBytes; - S32 total_mem = (LLViewerImage::sTotalTextureMemoryInBytes >> 20); + S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sTotalTextureMemoryInBytes); S32 max_total_mem = LLViewerImage::sMaxTotalTextureMemInMegaBytes; F32 discard_bias = LLViewerImage::sDesiredDiscardBias; S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); @@ -491,25 +478,28 @@ void LLGLTexMemBar::draw() #endif //---------------------------------------------------------------------------- - text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d RAW:%d HTP:%d BW: %.0f/%.0f", + text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d RAW:%d HTP:%d", gImageList.getNumImages(), - LLAppViewer::getTextureFetch()->getNumRequests(), - LLAppViewer::getTextureFetch()->getNumDeletes(), - LLAppViewer::getTextureFetch()->mPacketCount, - LLAppViewer::getTextureFetch()->mBadPacketCount, - LLAppViewer::getTextureCache()->getNumReads(), - LLAppViewer::getTextureCache()->getNumWrites(), + LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), + LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, + LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(), LLLFSThread::sLocal->getPending(), LLAppViewer::getImageDecodeThread()->getPending(), LLImageRaw::sRawImageCount, - LLAppViewer::getTextureFetch()->getNumHTTPRequests(), - LLAppViewer::getTextureFetch()->getTextureBandwidth(), - gSavedSettings.getF32("ThrottleBandwidthKBPS")); + LLAppViewer::getTextureFetch()->getNumHTTPRequests()); LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*2, text_color, LLFontGL::LEFT, LLFontGL::TOP); - left = 600; + + left = 550; + F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth(); + F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); + color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color; + color[VALPHA] = text_color[VALPHA]; + text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth); + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*2, + color, LLFontGL::LEFT, LLFontGL::TOP); S32 dx1 = 0; if (LLAppViewer::getTextureFetch()->mDebugPause) @@ -576,7 +566,7 @@ class LLGLTexSizeBar void setTop(S32 loaded, S32 bound, F32 scale) {mTopLoaded = loaded ; mTopBound = bound; mScale = scale ;} void draw(); - BOOL handleHover(S32 x, S32 y, MASK mask) ; + BOOL handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) ; private: S32 mIndex ; @@ -589,19 +579,16 @@ class LLGLTexSizeBar F32 mScale ; }; -BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask) +BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) { -#if !LL_RELEASE_FOR_DOWNLOAD if(y > mBottom && (y < mBottom + (S32)(mTopLoaded * mScale) || y < mBottom + (S32)(mTopBound * mScale))) { - LLImageGL::setCurTexSizebar(mIndex); + LLImageGL::setCurTexSizebar(mIndex, set_pick_size); } -#endif return TRUE ; } void LLGLTexSizeBar::draw() { -#if !LL_RELEASE_FOR_DOWNLOAD LLGLSUIDefault gls_ui; if(LLImageGL::sCurTexSizeBar == mIndex) @@ -622,7 +609,6 @@ void LLGLTexSizeBar::draw() F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ; gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ; -#endif } //////////////////////////////////////////////////////////////////////////// @@ -927,7 +913,31 @@ LLTextureSizeView::~LLTextureSizeView() } void LLTextureSizeView::draw() { -#if !LL_RELEASE_FOR_DOWNLOAD + if(mType == TEXTURE_MEM_OVER_SIZE) + { + drawTextureSizeGraph(); + } + else + { + drawTextureCategoryGraph() ; + } + + LLView::draw(); +} + +BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) +{ + if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) + { + mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ; + } + + return TRUE ; +} + +//draw real-time texture mem bar over size +void LLTextureSizeView::drawTextureSizeGraph() +{ if(mTextureSizeBar.size() == 0) { S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); @@ -948,29 +958,16 @@ void LLTextureSizeView::draw() mTextureSizeBar[i]->draw() ; } LLImageGL::resetCurTexSizebar(); - - LLView::draw(); -#endif -} - -BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) -{ - if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) - { - mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask) ; - } - - return TRUE ; } //draw background of texture size bar graph F32 LLTextureSizeView::drawTextureSizeDistributionGraph() { + //scale F32 scale = 1.0f ; -#if !LL_RELEASE_FOR_DOWNLOAD + LLGLSUIDefault gls_ui; - //scale { S32 count = 0 ; for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++) @@ -1058,9 +1055,138 @@ F32 LLTextureSizeView::drawTextureSizeDistributionGraph() //title text = llformat("Texture Size Distribution") ; + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, + text_color, LLFontGL::LEFT, LLFontGL::TOP); + return scale ; +} + +//draw real-time texture mem bar over category +void LLTextureSizeView::drawTextureCategoryGraph() +{ + if(mTextureSizeBar.size() == 0) + { + S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); + mTextureSizeBar.resize(LLImageGL::sTextureMemByCategory.size()) ; + mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; + + for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) + { + mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth , + line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ; + } + } + + F32 size_bar_scale = drawTextureCategoryDistributionGraph() ; + for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) + { + mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[i] >> 20, LLImageGL::sTextureMemByCategoryBound[i] >> 20, size_bar_scale) ; + mTextureSizeBar[i]->draw() ; + } + LLImageGL::resetCurTexSizebar(); +} + +//draw background for TEXTURE_MEM_OVER_CATEGORY +F32 LLTextureSizeView::drawTextureCategoryDistributionGraph() +{ + //scale + F32 scale = 4.0f ; + + LLGLSUIDefault gls_ui; + + { + S32 count = 0 ; + for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++) + { + S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ; + if(tmp > count) + { + count = tmp ; + } + } + if(count > mTextureSizeBarRect.getHeight() * 0.25f) + { + scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ; + } + } + + S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); + S32 left = mTextureSizeBarRect.mLeft ; + S32 bottom = mTextureSizeBarRect.mBottom ; + S32 right = mTextureSizeBarRect.mRight ; + S32 top = mTextureSizeBarRect.mTop ; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + //background rect + gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; + + //-------------------------------------------------- + gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); + gl_line_2d(left, bottom, right, bottom) ; //x axis + gl_line_2d(left, bottom, left, top) ; //y axis + + //ruler + //-------------------------------------------------- + gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); + for(S32 i = bottom + 50 ; i <= top ; i += 50) + { + gl_line_2d(left, i, right, i) ; + } + + //texts + //-------------------------------------------------- + F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; + std::string text; + + //------- + //x axis: size label + static char category[LLViewerImageBoostLevel::MAX_GL_IMAGE_CATEGORY][4] = + {"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Tbp", "Scr", "Fnt", "Bmp", "Dyn", "Tlc", "Mdi", "ALT", "Oth" } ; + + text = llformat("%s", category[0]) ; + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, + text_color, LLFontGL::LEFT, LLFontGL::TOP); + for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) + { + text = llformat("%s", category[i]) ; + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, + text_color, LLFontGL::LEFT, LLFontGL::TOP); + } + //------- + + //y axis: number label + for(S32 i = bottom + 50 ; i <= top ; i += 50) + { + text = llformat("%d", (S32)((i - bottom) / scale)) ; + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , + text_color, LLFontGL::LEFT, LLFontGL::TOP); + LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , + text_color, LLFontGL::LEFT, LLFontGL::TOP); + } + + text = llformat("MB") ; + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 , + text_color, LLFontGL::LEFT, LLFontGL::TOP); + //-------------------------------------------------- + F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; + gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; + text = llformat("Loaded") ; + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, + loaded_color, + LLFontGL::LEFT, LLFontGL::TOP); + + F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; + gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; + text = llformat("Bound") ; + LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, + bound_color, LLFontGL::LEFT, LLFontGL::TOP); + + //-------------------------------------------------- + + //title + text = llformat("Texture Category Distribution") ; LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, text_color, LLFontGL::LEFT, LLFontGL::TOP); -#endif return scale ; } diff --git a/linden/indra/newview/lltoolpie.h b/linden/indra/newview/lltoolpie.h index 54bf4094a..001886f72 100644 --- a/linden/indra/newview/lltoolpie.h +++ b/linden/indra/newview/lltoolpie.h @@ -86,6 +86,7 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie> LLPickInfo mPick; U8 mClickAction; LLSafeHandle<LLObjectSelection> mLeftClickSelection; +protected: LLPointer<LLViewerObject> mClickActionObject; }; diff --git a/linden/indra/newview/llviewercamera.cpp b/linden/indra/newview/llviewercamera.cpp index 6cef2af27..dade65f1a 100644 --- a/linden/indra/newview/llviewercamera.cpp +++ b/linden/indra/newview/llviewercamera.cpp @@ -769,8 +769,8 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0; - if ( !in_frustum && all_verts || - in_frustum && !all_verts) + if (( !in_frustum && all_verts) || + (in_frustum && !all_verts)) { return !all_verts; } diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 4c9c0983f..1531e6c03 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -90,7 +90,7 @@ std::string gCurrentVersion; extern BOOL gResizeScreenTexture; extern BOOL gDebugGL; -//extern BOOL gAuditTexture; +extern BOOL gAuditTexture; //////////////////////////////////////////////////////////////////////////// // Listeners @@ -418,12 +418,12 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue) LLVOAvatar::sUseImpostors = newvalue.asBoolean(); return true; } -/* + static bool handleAuditTextureChanged(const LLSD& newvalue) { gAuditTexture = newvalue.asBoolean(); return true; -}*/ +} static bool handleRenderDebugGLChanged(const LLSD& newvalue) { @@ -528,11 +528,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); - - gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); - gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); - gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); - gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("EnableRippleWater")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); @@ -544,9 +539,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _1)); gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _1)); gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1)); - gSavedSettings.getControl("RenderDeferredShadow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); - gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); - gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1)); gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _1)); gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1)); @@ -592,7 +584,7 @@ void settings_setup_listeners() gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _1)); -// gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); + gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index 5e1cf8094..5316337b2 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -128,11 +128,6 @@ void display_startup() return; } - gPipeline.updateGL(); - - // Update images? - gImageList.updateImages(0.01f); - LLGLSDefault gls_default; // Required for HTML update in login screen @@ -604,9 +599,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.updateGeom(max_geom_update_time); stop_glerror(); - gPipeline.updateGL(); - stop_glerror(); - gFrameStats.start(LLFrameStats::UPDATE_CULL); S32 water_clip = 0; if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && @@ -697,8 +689,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } - LLVertexBuffer::unbind(); // KL - LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); @@ -729,7 +719,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); - gPipeline.generateHighlight(*LLViewerCamera::getInstance()); } ////////////////////////////////////// @@ -754,9 +743,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) gImageList.updateImages(max_image_decode_time); - - //remove dead textures from GL KL is it req? - LLImageGL::deleteDeadTextures(); stop_glerror(); } llpushcallstacks ; @@ -911,7 +897,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) /// and then display it again with compositor effects. /// Using render to texture would be faster/better, but I don't have a /// grasp of their full display stack just yet. - gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); // KL + // gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { @@ -927,8 +913,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) render_ui(); } - gPipeline.rebuildGroups(); - LLSpatialGroup::sNoDelete = FALSE; } @@ -1015,15 +999,6 @@ void render_hud_attachments() gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); gPipeline.stateSort(hud_cam, result); diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index 93c17a2b8..400fb2f1f 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp @@ -60,8 +60,6 @@ #include "pipeline.h" #include "llappviewer.h" #include "llface.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h" #include "llviewercamera.h" /////////////////////////////////////////////////////////////////////////////// @@ -104,7 +102,7 @@ void LLViewerImage::initClass() sNullImagep = new LLImageGL(1,1,3,TRUE); LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3); raw->clear(0x77, 0x77, 0x77, 0xFF); - sNullImagep->createGLTexture(0, raw); + sNullImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); #if 1 LLPointer<LLViewerImage> imagep = new LLViewerImage(IMG_DEFAULT); @@ -133,7 +131,7 @@ void LLViewerImage::initClass() } } } - imagep->createGLTexture(0, image_raw); + imagep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); image_raw = NULL; gImageList.addImage(imagep); imagep->dontDiscard(); @@ -143,48 +141,48 @@ void LLViewerImage::initClass() sSmokeImagep = gImageList.getImage(IMG_SMOKE, TRUE, TRUE); sSmokeImagep->setNoDelete() ; -#if !LL_RELEASE_FOR_DOWNLOAD - sDefaultTexturep = new LLImageGL() ; - image_raw = new LLImageRaw(dim,dim,3); - data = image_raw->getData(); - for (S32 i = 0; i<dim; i++) + if(gAuditTexture) { - for (S32 j = 0; j<dim; j++) + sDefaultTexturep = new LLImageGL() ; + image_raw = new LLImageRaw(dim,dim,3); + data = image_raw->getData(); + for (S32 i = 0; i<dim; i++) { - const S32 border = 2; - if (i<border || j<border || i>=(dim-border) || j>=(dim-border)) - { - *data++ = 0xff; - *data++ = 0xff; - *data++ = 0xff; - } - else + for (S32 j = 0; j<dim; j++) { - *data++ = 0xff; - *data++ = 0xff; - *data++ = 0x00; + const S32 border = 2; + if (i<border || j<border || i>=(dim-border) || j>=(dim-border)) + { + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0xff; + } + else + { + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0x00; + } } } + sDefaultTexturep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + image_raw = NULL; + sDefaultTexturep->dontDiscard(); } - sDefaultTexturep->createGLTexture(0, image_raw); - image_raw = NULL; - sDefaultTexturep->dontDiscard(); -#endif } // static void LLViewerImage::cleanupClass() { stop_glerror(); + LLImageGL::cleanupClass() ; + sNullImagep = NULL; sDefaultImagep = NULL; sSmokeImagep = NULL; sMissingAssetImagep = NULL; - sWhiteImagep = NULL; - -#if !LL_RELEASE_FOR_DOWNLOAD - LLImageGL::sDefaultTexturep = NULL ; -#endif + sWhiteImagep = NULL; + sDefaultTexturep = NULL ; } // tuning params @@ -233,7 +231,12 @@ void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) } sDesiredDiscardBias = llclamp(sDesiredDiscardBias, sDesiredDiscardBiasMin, sDesiredDiscardBiasMax); - LLImageGL::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ; + F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; + F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); + sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ; + + LLViewerImage::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && + (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; } // static @@ -379,7 +382,6 @@ LLViewerImage::~LLViewerImage() void LLViewerImage::cleanup() { mFaceList.clear() ; - for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); iter != mLoadedCallbackList.end(); ) { @@ -409,192 +411,6 @@ void LLViewerImage::reinit(BOOL usemipmaps /* = TRUE */) setSize(0,0,0); } -void LLViewerImage::resetFaceAtlas() -{ - //Nothing should be done here. -} - -//invalidate all atlas slots for this image. -void LLViewerImage::invalidateAtlas(BOOL rebuild_geom) -{ - for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) - { - if(*iter) - { - LLFace* facep = (LLFace*)*iter ; - facep->removeAtlas() ; - if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup()) - { - facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY); - } - } - } -} - -BOOL LLViewerImage::insertToAtlas() -{ - if(mFaceList.size() < 1) - { - return FALSE ; - } - if(!canAddToAtlas()) - { - return FALSE ; - } - if(getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= getDiscardLevelInAtlas()) - { - return FALSE ; - } - if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), getTexTarget())) - { - return FALSE ; - } - - BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image. - S32 raw_w = mRawImage->getWidth() ; - S32 raw_h = mRawImage->getHeight() ; - F32 xscale = 1.0f, yscale = 1.0f ; - LLPointer<LLTextureAtlasSlot> slot_infop; - LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer. - LLSpatialGroup* groupp ; - LLFace* facep; - - //if the atlas slot pointers for some faces are null, process them later. - ll_face_list_t waiting_list ; - - for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) - { - if(*iter) - { - facep = (LLFace*)*iter ; - - //face can not use atlas. - if(!facep->canUseAtlas()) - { - if(facep->getAtlasInfo()) - { - facep->removeAtlas() ; - } - ret = FALSE ; - continue ; - } - - //the atlas slot is updated - slot_infop = facep->getAtlasInfo() ; - groupp = facep->getDrawable()->getSpatialGroup() ; - - if(slot_infop) - { - if(slot_infop->getSpatialGroup() != groupp) - { - if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot - { - facep->setAtlasInfo(cur_slotp) ; - facep->setAtlasInUse(TRUE) ; - continue ; - } - else //do not forget to update slot_infop->getSpatialGroup(). - { - LLSpatialGroup* gp = slot_infop->getSpatialGroup() ; - gp->setCurUpdatingTime(gFrameCount) ; - gp->setCurUpdatingTexture(this) ; - gp->setCurUpdatingSlot(slot_infop) ; - } - } - else //same group - { - if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated - { - facep->setAtlasInUse(TRUE) ; - continue ; - } - } - } - else - { - //if the slot is null, wait to process them later. - waiting_list.push_back(facep) ; - continue ; - } - - //---------- - //insert to atlas - if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) - { - //the texture does not qualify to add to atlas, do not bother to try for other faces. - //invalidateAtlas(); - return FALSE ; - } - - //update texture scale - slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; - slot_infop->setTexCoordScale(xscale, yscale) ; - slot_infop->setValid() ; - slot_infop->setUpdatedTime(gFrameCount) ; - - //update spatial group atlas info - groupp->setCurUpdatingTime(gFrameCount) ; - groupp->setCurUpdatingTexture(this) ; - groupp->setCurUpdatingSlot(slot_infop) ; - - //make the face to switch to the atlas. - facep->setAtlasInUse(TRUE) ; - } - } - - //process the waiting_list - for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) - { - facep = (LLFace*)*iter ; - groupp = facep->getDrawable()->getSpatialGroup() ; - - //check if this texture already inserted to atlas for this group - if((cur_slotp = groupp->getCurUpdatingSlot(this))) - { - facep->setAtlasInfo(cur_slotp) ; - facep->setAtlasInUse(TRUE) ; - continue ; - } - - //need to reserve a slot from atlas - slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ; - - facep->setAtlasInfo(slot_infop) ; - - groupp->setCurUpdatingTime(gFrameCount) ; - groupp->setCurUpdatingTexture(this) ; - groupp->setCurUpdatingSlot(slot_infop) ; - - //slot allocation failed. - if(!slot_infop || !slot_infop->getAtlas()) - { - ret = FALSE ; - facep->setAtlasInUse(FALSE) ; - continue ; - } - - //insert to atlas - if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) - { - //the texture does not qualify to add to atlas, do not bother to try for other faces. - ret = FALSE ; - //invalidateAtlas(); - break ; - } - - //update texture scale - slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; - slot_infop->setTexCoordScale(xscale, yscale) ; - slot_infop->setValid() ; - slot_infop->setUpdatedTime(gFrameCount) ; - - //make the face to switch to the atlas. - facep->setAtlasInUse(TRUE) ; - } - - return ret ; -} - /////////////////////////////////////////////////////////////////////////////// // ONLY called from LLViewerImageList void LLViewerImage::destroyTexture() @@ -616,7 +432,7 @@ void LLViewerImage::addToCreateTexture() if(isForSculptOnly()) { //just update some variables, not to create a real GL texture. - createGLTexture(mRawDiscardLevel, mRawImage, 0) ; + createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE) ; mNeedsCreateTexture = FALSE ; destroyRawImage(); } @@ -679,7 +495,7 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) mNeedsCreateTexture = FALSE; if (mRawImage.isNull()) { - llwarns << "LLViewerImage trying to create texture with no Raw Image" << llendl; + llerrs << "LLViewerImage trying to create texture with no Raw Image" << llendl; } // llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", // mRawDiscardLevel, @@ -703,25 +519,32 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) mOrigHeight = mFullHeight; } - if (LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) + bool size_okay = true; + + U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel; + U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel; + if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE ) { - if(!(res = insertToAtlas())) - { - res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); - resetFaceAtlas() ; - } + llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl; + size_okay = false; } - else + if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) { // A non power-of-two image was uploaded (through a non standard client) + llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl; + size_okay = false; + } + + if( !size_okay ) + { + // An inappropriately-sized image was uploaded (through a non standard client) // We treat these images as missing assets which causes them to // be renderd as 'missing image' and to stop requesting data setIsMissingAsset(); destroyRawImage(); return FALSE; } - if (mRawImage->getComponents()>4) { LL_DEBUGS("Openjpeg")<<"broken raw image" << LL_ENDL; @@ -730,6 +553,7 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) return FALSE; } + res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); } // @@ -831,7 +655,6 @@ void LLViewerImage::processTextureStats() S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); mTexelsPerImage = (F32)fullwidth * fullheight; - F32 discard_level = 0.f; // If we know the output width and height, we can force the discard @@ -839,8 +662,7 @@ void LLViewerImage::processTextureStats() // data than we need to. if (mBoostLevel == LLViewerImageBoostLevel::BOOST_UI || mBoostLevel == LLViewerImageBoostLevel::BOOST_PREVIEW || - mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF || - mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_BAKED_SELF) + mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF) // JAMESDEBUG what about AVATAR_BAKED_SELF? { discard_level = 0; // full res } @@ -855,6 +677,12 @@ void LLViewerImage::processTextureStats() } else { + if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 1.0f) + { + //if is a big image and not being used recently, nor close to the view point, do not load hi-res data. + mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerImage::sMinLargeImageSize) ; + } + if ((mCalculatedDiscardLevel >= 0.f) && (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) { @@ -877,7 +705,6 @@ void LLViewerImage::processTextureStats() discard_level += sCameraMovingDiscardBias ; } discard_level = floorf(discard_level); -// discard_level -= (gImageList.mVideoMemorySetting>>1); // more video ram = higher detail F32 min_discard = 0.f; if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) @@ -899,12 +726,15 @@ void LLViewerImage::processTextureStats() if ((sDesiredDiscardBias > 0.0f) && (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) { - if ( (sBoundTextureMemoryInBytes >> 20) > sMaxBoundTextureMemInMegaBytes*texmem_middle_bound_scale) + // Limit the amount of GL memory bound each frame + if ( (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && + (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown() ; } // Only allow GL to have 2x the video card memory - else if (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel) + else if ( (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale) && + (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown() ; } @@ -926,7 +756,7 @@ void LLViewerImage::updateVirtualSize() if(facep->getDrawable()->isRecentlyVisible()) { addTextureStats(facep->getVirtualSize()) ; - //setAdditionalDecodePriority(facep->getImportanceToCamera()) ; + setAdditionalDecodePriority(facep->getImportanceToCamera()) ; } } } @@ -966,7 +796,6 @@ void LLViewerImage::switchToCachedImage() mNeedsCreateTexture = TRUE; } } - //============================================================================ F32 LLViewerImage::calcDecodePriority() @@ -988,6 +817,13 @@ F32 LLViewerImage::calcDecodePriority() } S32 cur_discard = getDiscardLevel(); + + //no need to update if the texture reaches its highest res and the memory is sufficient. + //if(LLViewerImage::sFreezeImageScalingDown && !cur_discard) + //{ + // return -5.0f ; + //} + bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); F32 pixel_priority = fsqrtf(mMaxVirtualSize); const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame @@ -1006,6 +842,14 @@ F32 LLViewerImage::calcDecodePriority() { priority = -1.0f ; } + else if (!isJustBound() && mCachedRawImageReady) + { + priority = -1.0f; + } + else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel) + { + priority = -1.0f; + } else if (mDesiredDiscardLevel > mMaxDiscardLevel) { // Don't decode anything we don't need @@ -1066,6 +910,7 @@ F32 LLViewerImage::calcDecodePriority() ddiscard-=2; } ddiscard = llclamp(ddiscard, 0, 4); + priority = ddiscard*100000.f; } if (priority > 0.0f) @@ -1097,7 +942,7 @@ F32 LLViewerImage::calcDecodePriority() //static F32 LLViewerImage::maxDecodePriority() { - return 6000000.f; // KL 2000000 in render pipeline + return 6000000.f; } void LLViewerImage::setDecodePriority(F32 priority) @@ -1124,7 +969,10 @@ void LLViewerImage::setBoostLevel(S32 level) { mBoostLevel = level; - + if(gAuditTexture) + { + setCategory(mBoostLevel); + } if(mBoostLevel != LLViewerImageBoostLevel::BOOST_NONE) { @@ -1174,15 +1022,11 @@ bool LLViewerImage::updateFetch() return false; // process any raw image data in callbacks before replacing } - mFetchState = 0; - mFetchPriority = 0; - mFetchDeltaTime = 999999.f; - mRequestDeltaTime = 999999.f; S32 current_discard = getDiscardLevel(); S32 desired_discard = getDesiredDiscardLevel(); F32 decode_priority = getDecodePriority(); decode_priority = llmax(decode_priority, 0.0f); - //decode_priority = llmin(decode_priority, maxDecodePriority()); + decode_priority = llmin(decode_priority, maxDecodePriority()); if (mIsFetching) { @@ -1215,6 +1059,7 @@ bool LLViewerImage::updateFetch() if (mRawImage.notNull()) { mRawDiscardLevel = fetch_discard; + if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) { @@ -1333,6 +1178,10 @@ bool LLViewerImage::updateFetch() { make_request = false; } + else if (!isJustBound() && mCachedRawImageReady) + { + make_request = false; + } else { if (mIsFetching) @@ -1367,13 +1216,14 @@ bool LLViewerImage::updateFetch() w, h, c, desired_discard, needsAux()); if (fetch_request_created) - { + { mHasFetcher = TRUE; mIsFetching = TRUE; mRequestedDiscardLevel = desired_discard; + mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, - mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); - } + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); + } // if createRequest() failed, we're finishing up a request for this UUID, // wait for it to complete @@ -1445,12 +1295,12 @@ BOOL LLViewerImage::forceFetch() w, h, c, desired_discard, needsAux()); if (fetch_request_created) - { + { mHasFetcher = TRUE; mIsFetching = TRUE; // Set the image's decode priority to maxDecodePriority() too, or updateFetch() will set // the request priority to 0 and terminate the fetch before we even started (SNOW-203). - // gImageList.bumpToMaxDecodePriority(this); // Kl force immediate update?? + gImageList.bumpToMaxDecodePriority(this); mRequestedDiscardLevel = desired_discard ; mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, @@ -1623,8 +1473,8 @@ bool LLViewerImage::doLoadedCallbacks() destroyRawImage(); readBackRawImage(gl_discard); - //llassert_always(mRawImage.notNull()); - //llassert_always(!mNeedsAux || mAuxRawImage.notNull()); + llassert_always(mRawImage.notNull()); + llassert_always(!mNeedsAux || mAuxRawImage.notNull()); } // @@ -1786,18 +1636,7 @@ bool LLViewerImage::bindDefaultImage(S32 stage) //virtual void LLViewerImage::forceImmediateUpdate() { - //only immediately update a deleted texture which is now being re-used. - if(!isDeleted()) - { - return ; - } - //if already called forceImmediateUpdate() - if(mInImageList && mDecodePriority == LLViewerImage::maxDecodePriority()) - { - return ; - } - - gImageList.forceImmediateUpdate(this) ; + gImageList.bumpToMaxDecodePriority(this) ; return ; } @@ -1808,7 +1647,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) llassert_always(mComponents > 0); if (mRawImage.notNull()) { - llwarns << "called with existing mRawImage" << llendl; + llerrs << "called with existing mRawImage" << llendl; mRawImage = NULL; } @@ -1826,7 +1665,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) sRawCount++; mIsRawImageValid = TRUE; - + return mRawImage; } diff --git a/linden/indra/newview/llviewerimage.h b/linden/indra/newview/llviewerimage.h index 7d646be36..c82b68bae 100644 --- a/linden/indra/newview/llviewerimage.h +++ b/linden/indra/newview/llviewerimage.h @@ -41,13 +41,11 @@ #include <map> #include <list> - +class LLFace; #define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 #define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. class LLViewerImage; -class LLTextureAtlas ; -class LLFace ; typedef void (*loaded_callback_func)( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); @@ -263,29 +261,8 @@ class LLViewerImage : public LLImageGL void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } // Host we think might have this image, used for baked av textures. - void setTargetHost(LLHost host) { mTargetHost = host; } LLHost getTargetHost() const { return mTargetHost; } - enum - { - BOOST_NONE = 0, - BOOST_AVATAR_BAKED = 1, - BOOST_AVATAR = 2, - BOOST_CLOUDS = 3, - BOOST_SCULPTED = 4, - - BOOST_HIGH = 10, - BOOST_TERRAIN = 11, // has to be high priority for minimap / low detail - BOOST_SELECTED = 12, - BOOST_HUD = 13, - BOOST_AVATAR_BAKED_SELF = 14, - BOOST_UI = 15, - BOOST_PREVIEW = 16, - BOOST_MAP = 17, - BOOST_MAP_LAYER = 18, - BOOST_AVATAR_SELF = 19, // needed for baking avatar - BOOST_MAX_LEVEL - }; void setBoostLevel(S32 level); S32 getBoostLevel() { return mBoostLevel; } @@ -318,10 +295,6 @@ class LLViewerImage : public LLImageGL S32 getOriginalWidth() { return mOrigWidth; } S32 getOriginalHeight() { return mOrigHeight; } - BOOL insertToAtlas() ; - void resetFaceAtlas() ; - void invalidateAtlas(BOOL rebuild_geom = FALSE); - BOOL isForSculptOnly() const ; void setForSculpt(); @@ -340,7 +313,6 @@ class LLViewerImage : public LLImageGL void addFace(LLFace* facep) ; void removeFace(LLFace* facep) ; - BOOL isReferenced()const {return mFaceList.size() > 0 ; } friend class LocalBitmap; // tag: vaa emerald local_asset_browser @@ -446,7 +418,6 @@ class LLViewerImage : public LLImageGL typedef std::list<LLFace*> ll_face_list_t ; ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture - BOOL mInCreationList ; public: static const U32 sCurrentFileVersion; // Default textures diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp index 7642e8079..e0f37c97c 100644 --- a/linden/indra/newview/llviewerimagelist.cpp +++ b/linden/indra/newview/llviewerimagelist.cpp @@ -199,6 +199,7 @@ static std::string get_texture_list_name() void LLViewerImageList::doPrefetchImages() { +#if 1 if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point @@ -226,7 +227,7 @@ void LLViewerImageList::doPrefetchImages() image->addTextureStats((F32)pixel_area); } } - +#endif } @@ -485,7 +486,7 @@ void LLViewerImageList::removeImageFromList(LLViewerImage *image) { llinfos << "Image is not in mUUIDMap!" << llendl ; } - llwarns << "LLViewerImageList::removeImageFromList - Image not in list" << llendl; + llerrs << "LLViewerImageList::removeImageFromList - Image not in list" << llendl; } llverify(mImageList.erase(image) == 1); image->mInImageList = FALSE; @@ -534,8 +535,7 @@ void LLViewerImageList::deleteImage(LLViewerImage *image) void LLViewerImageList::dirtyImage(LLViewerImage *image) { - //mDirtyTextureList.insert(image); - image->invalidateAtlas(TRUE) ; // KL + mDirtyTextureList.insert(image); } //////////////////////////////////////////////////////////////////////////// @@ -547,21 +547,25 @@ void LLViewerImageList::updateImages(F32 max_time) sNumImagesStat.addValue(sNumImages); sNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); - sGLTexMemStat.addValue((F32)(LLImageGL::sGlobalTextureMemoryInBytes >> 20)); - sGLBoundMemStat.addValue((F32)(LLImageGL::sBoundTextureMemoryInBytes >> 20)); - sRawMemStat.addValue((F32)(LLImageRaw::sGlobalRawMemory >> 20)); - sFormattedMemStat.addValue((F32)(LLImageFormatted::sGlobalFormattedMemory >> 20)); - + sGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); + sGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); + sRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); + sFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); + llpushcallstacks ; + updateImagesDecodePriorities(); + llpushcallstacks ; + F32 total_max_time = max_time; max_time -= updateImagesFetchTextures(max_time); + llpushcallstacks ; - max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); + max_time = llmax(max_time, total_max_time*.25f); // at least 25% of max_time max_time -= updateImagesCreateTextures(max_time); + llpushcallstacks ; - max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); - llpushcallstacks ; + if (!mDirtyTextureList.empty()) { LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY); @@ -735,7 +739,7 @@ F32 LLViewerImageList::updateImagesCreateTextures(F32 max_time) return create_timer.getElapsedTimeF32(); } -void LLViewerImageList::forceImmediateUpdate(LLViewerImage* imagep) +void LLViewerImageList::bumpToMaxDecodePriority(LLViewerImage* imagep) { if(!imagep) { @@ -743,6 +747,11 @@ void LLViewerImageList::forceImmediateUpdate(LLViewerImage* imagep) } if(imagep->mInImageList) { + if (imagep->getDecodePriority() == LLViewerImage::maxDecodePriority()) + { + // Already at maximum. + return; + } removeImageFromList(imagep); } @@ -1019,16 +1028,13 @@ LLPointer<LLImageJ2C> LLViewerImageList::convertToUploadFile(LLPointer<LLImageRa return compressedImage; } - -const S32 MIN_VIDEO_RAM = 32; -const S32 MAX_VIDEO_RAM = 512; // 512MB max for performance reasons. // Returns min setting for TextureMemory (in MB) S32 LLViewerImageList::getMinVideoRamSetting() { - S32 system_ram = (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20); + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); //min texture mem sets to 64M if total physical mem is more than 1.5GB - return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM; + return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ; } //static @@ -1055,14 +1061,14 @@ S32 LLViewerImageList::getMaxVideoRamSetting(bool get_recommended) llwarns << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << llendl; } - S32 system_ram = (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20); // In MB + S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB //llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl; if (get_recommended) max_texmem = llmin(max_texmem, (S32)(system_ram/2)); else max_texmem = llmin(max_texmem, (S32)(system_ram)); - max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM); + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); return max_texmem; } @@ -1107,9 +1113,9 @@ void LLViewerImageList::updateMaxResidentTexMem(S32 mem) mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2); } - if (mMaxTotalTextureMemInMegaBytes > (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20) - 128) + if (mMaxTotalTextureMemInMegaBytes > (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()) - 128) { - mMaxTotalTextureMemInMegaBytes = (gSysMemory.getPhysicalMemoryClamped() >> 20) - 128 ; + mMaxTotalTextureMemInMegaBytes = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()) - 128 ; } llinfos << "Total Video Memory set to: " << vb_mem << " MB" << llendl; diff --git a/linden/indra/newview/llviewerimagelist.h b/linden/indra/newview/llviewerimagelist.h index f82d9f3eb..561e8e5f4 100644 --- a/linden/indra/newview/llviewerimagelist.h +++ b/linden/indra/newview/llviewerimagelist.h @@ -112,7 +112,7 @@ class LLViewerImageList LLGLenum primary_format = 0, const LLUUID& force_id = LLUUID::null ); - + // Request image from a specific host, used for baked avatar textures. // Implemented in header in case someone changes default params above. JC LLViewerImage* getImageFromHost(const LLUUID& image_id, LLHost host) @@ -129,7 +129,7 @@ class LLViewerImageList // Using image stats, determine what images are necessary, and perform image updates. void updateImages(F32 max_time); - void forceImmediateUpdate(LLViewerImage* imagep) ; + void bumpToMaxDecodePriority(LLViewerImage* imagep) ; // Decode and create textures for all images currently in list. void decodeAllImages(F32 max_decode_time); diff --git a/linden/indra/newview/llviewerjointmesh.cpp b/linden/indra/newview/llviewerjointmesh.cpp index dc08bcdc2..b6f0dafae 100644 --- a/linden/indra/newview/llviewerjointmesh.cpp +++ b/linden/indra/newview/llviewerjointmesh.cpp @@ -523,9 +523,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) //---------------------------------------------------------------- if (!gRenderForSelect) { - /* if (is_dummy) + if (is_dummy) glColor4fv(LLVOAvatar::getDummyColor().mV); - else */ + else glColor4fv(mColor.mV); } @@ -557,7 +557,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture(), TRUE); // KL SD + gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture()); } else { @@ -565,7 +565,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) // Ignore the warning if that's the case. if (!gSavedSettings.getBOOL("RenderUnloadedAvatar")) { - //llwarns << "Layerset without composite" << llendl; + llwarns << "Layerset without composite" << llendl; } gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT)); } @@ -574,7 +574,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if ( !is_dummy && mTexture.notNull() ) { old_mode = mTexture->getAddressMode(); - gGL.getTexUnit(0)->bind(mTexture.get(), TRUE); // KL SD + gGL.getTexUnit(0)->bind(mTexture.get()); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } else diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 8857170c1..8c5cf6a14 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -938,7 +938,9 @@ void LLViewerMediaImpl::update() x_pos, y_pos, width, - height); + height, + TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) + } mMediaSource->resetDirty(); diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 3d3399a9c..a4057640a 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -1412,14 +1412,14 @@ void init_debug_avatar_menu(LLMenuGL* menu) //menu->append(new LLMenuItemToggleGL("Show Attachment Points", &LLVOAvatar::sShowAttachmentPoints)); //diabling collision plane due to DEV-14477 -brad //menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane)); - /*menu->append(new LLMenuItemCheckGL("Show Collision Skeleton", + menu->append(new LLMenuItemCheckGL("Show Collision Skeleton", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)); menu->append(new LLMenuItemCheckGL("Display Agent Target", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, - (void*)LLPipeline::RENDER_DEBUG_AGENT_TARGET));*/ + (void*)LLPipeline::RENDER_DEBUG_AGENT_TARGET)); menu->append(new LLMenuItemToggleGL( "Debug Rotation", &LLVOAvatar::sDebugAvatarRotation)); menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments)); menu->append(new LLMenuItemCallGL("Refresh Appearance", handle_rebake_textures, NULL, NULL, 'R', MASK_ALT | MASK_CONTROL )); @@ -10463,7 +10463,7 @@ class LLAdvancedCheckShowCollisionPlane : public view_listener_t // SHOW COLLISION SKELETON // ///////////////////////////// -/* + class LLAdvancedToggleShowCollisionSkeleton : public view_listener_t { bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) @@ -10484,13 +10484,13 @@ class LLAdvancedCheckShowCollisionSkeleton : public view_listener_t } }; -*/ + ////////////////////////// // DISPLAY AGENT TARGET // ////////////////////////// -/* + class LLAdvancedToggleDisplayAgentTarget : public view_listener_t { bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) @@ -10511,7 +10511,7 @@ class LLAdvancedCheckDisplayAgentTarget : public view_listener_t } }; -*/ + /////////////////////////// // DEBUG AVATAR ROTATION // @@ -11378,10 +11378,10 @@ void initialize_menus() addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis"); // addMenu(new LLAdvancedToggleShowCollisionPlane(), "Advanced.ToggleShowCollisionPlane"); // addMenu(new LLAdvancedCheckShowCollisionPlane(), "Advanced.CheckShowCollisionPlane"); -// addMenu(new LLAdvancedToggleShowCollisionSkeleton(), "Advanced.ToggleShowCollisionSkeleton"); -// addMenu(new LLAdvancedCheckShowCollisionSkeleton(), "Advanced.CheckShowCollisionSkeleton"); -// addMenu(new LLAdvancedToggleDisplayAgentTarget(), "Advanced.ToggleDisplayAgentTarget"); -// addMenu(new LLAdvancedCheckDisplayAgentTarget(), "Advanced.CheckDisplayAgentTarget"); + addMenu(new LLAdvancedToggleShowCollisionSkeleton(), "Advanced.ToggleShowCollisionSkeleton"); + addMenu(new LLAdvancedCheckShowCollisionSkeleton(), "Advanced.CheckShowCollisionSkeleton"); + addMenu(new LLAdvancedToggleDisplayAgentTarget(), "Advanced.ToggleDisplayAgentTarget"); + addMenu(new LLAdvancedCheckDisplayAgentTarget(), "Advanced.CheckDisplayAgentTarget"); addMenu(new LLAdvancedToggleDebugAvatarRotation(), "Advanced.ToggleDebugAvatarRotation"); addMenu(new LLAdvancedCheckDebugAvatarRotation(), "Advanced.CheckDebugAvatarRotation"); addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments"); diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index bd5abe2af..4ab0957ed 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp @@ -2787,11 +2787,6 @@ BOOL LLViewerObject::updateGeometry(LLDrawable *drawable) return TRUE; } -void LLViewerObject::updateGL() -{ - -} - void LLViewerObject::updateFaceSize(S32 idx) { @@ -2896,7 +2891,7 @@ F32 LLViewerObject::getMidScale() const } -void LLViewerObject::updateTextures(LLAgent &agent) +void LLViewerObject::updateTextures() { } @@ -3741,7 +3736,6 @@ S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color) else if (color != tep->getColor()) { retval = LLPrimitive::setTEColor(te, color); - //setChanged(TEXTURE); if (mDrawable.notNull() && retval) { // These should only happen on updates which are not the initial update. @@ -3980,7 +3974,7 @@ LLViewerImage *LLViewerObject::getTEImage(const U8 face) const } } - llwarns << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; + llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; return NULL; } @@ -4166,11 +4160,6 @@ void LLViewerObject::updateText() } } -LLVOAvatar* LLViewerObject::asAvatar() -{ - return NULL; -} - BOOL LLViewerObject::isParticleSource() const { return !mPartSourcep.isNull() && !mPartSourcep->isDead(); @@ -4385,14 +4374,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow gAudiop->cleanupAudioSource(mAudioSourcep); mAudioSourcep = NULL; } -/* - if (mAudioSourcep && mAudioSourcep->isMuted() && - mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid) - { - //llinfos << "Already having this sound as muted sound, ignoring" << llendl; - return; - } -*/ + getAudioSource(owner_id); if (mAudioSourcep) @@ -4486,11 +4468,7 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para new_block = new LLSculptParams(); break; } - case LLNetworkData::PARAMS_LIGHT_IMAGE: - { - new_block = new LLLightImageParams(); - break; - } + default: { llinfos << "Unknown param type." << llendl; @@ -4581,7 +4559,7 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_ bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin) { ExtraParameter* param = getExtraParameterEntryCreate(param_type); - if (param && param->in_use != in_use) + if (param->in_use != in_use) { param->in_use = in_use; parameterChanged(param_type, param->data, in_use, local_origin); @@ -4997,7 +4975,7 @@ U32 LLViewerObject::getPartitionType() const return LLViewerRegion::PARTITION_NONE; } -void LLViewerObject::dirtySpatialGroup(BOOL priority) const +void LLViewerObject::dirtySpatialGroup() const { if (mDrawable) { @@ -5005,7 +4983,6 @@ void LLViewerObject::dirtySpatialGroup(BOOL priority) const if (group) { group->dirtyGeom(); - gPipeline.markRebuild(group, priority); } } } diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h index a227f2d22..33e8da2c5 100644 --- a/linden/indra/newview/llviewerobject.h +++ b/linden/indra/newview/llviewerobject.h @@ -74,7 +74,6 @@ class LLViewerPartSourceScript; class LLViewerRegion; class LLViewerObjectMedia; class LLVOInventoryListener; -class LLVOAvatar; typedef enum e_object_update_type { @@ -117,7 +116,7 @@ struct LLMaterialExportInfo //============================================================================ -class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate +class LLViewerObject : public LLPrimitive, public LLRefCount { protected: ~LLViewerObject(); // use unref() @@ -144,8 +143,6 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate BOOL isOrphaned() const { return mOrphaned; } BOOL isParticleSource() const; - virtual LLVOAvatar* asAvatar(); - static void initVOClasses(); static void cleanupVOClasses(); @@ -192,12 +189,11 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate S32 getNumFaces() const { return mNumFaces; } // Graphical stuff for objects - maybe broken out into render class later? - virtual void updateTextures(LLAgent &agent); + virtual void updateTextures(); virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object virtual LLDrawable* createDrawable(LLPipeline *pipeline); virtual BOOL updateGeometry(LLDrawable *drawable); - virtual void updateGL(); virtual void updateFaceSize(S32 idx); virtual BOOL updateLOD(); virtual BOOL setDrawableParent(LLDrawable* parentp); @@ -222,7 +218,6 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } - virtual BOOL hasLightTexture() const { return FALSE; } // This method returns true if the object is over land owned by // the agent. @@ -473,7 +468,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate virtual S32 getLOD() const { return 3; } virtual U32 getPartitionType() const; - virtual void dirtySpatialGroup(BOOL priority = FALSE) const; + virtual void dirtySpatialGroup() const; virtual void dirtyMesh(); virtual LLNetworkData* getParameterEntry(U16 param_type) const; diff --git a/linden/indra/newview/llviewerobjectlist.cpp b/linden/indra/newview/llviewerobjectlist.cpp index 517bb868d..78ce247cd 100644 --- a/linden/indra/newview/llviewerobjectlist.cpp +++ b/linden/indra/newview/llviewerobjectlist.cpp @@ -629,7 +629,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) // Update distance & gpw objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area - objectp->updateTextures(agent); // Update the image levels of textures for this object. + objectp->updateTextures(); // Update the image levels of textures for this object. } } diff --git a/linden/indra/newview/llviewerobjectlist.h b/linden/indra/newview/llviewerobjectlist.h index a77c33db0..07920cbaa 100644 --- a/linden/indra/newview/llviewerobjectlist.h +++ b/linden/indra/newview/llviewerobjectlist.h @@ -44,6 +44,7 @@ // project includes #include "llviewerobject.h" +class LLCamera; class LLNetMap; class LLDebugBeacon; diff --git a/linden/indra/newview/llviewerparceloverlay.cpp b/linden/indra/newview/llviewerparceloverlay.cpp index 935e3e60a..0bcd8f395 100644 --- a/linden/indra/newview/llviewerparceloverlay.cpp +++ b/linden/indra/newview/llviewerparceloverlay.cpp @@ -71,7 +71,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges mTexture = new LLImageGL(FALSE); mImageRaw = new LLImageRaw(mParcelGridsPerEdge, mParcelGridsPerEdge, OVERLAY_IMG_COMPONENTS); - mTexture->createGLTexture(0, mImageRaw, 0); + mTexture->createGLTexture(0, mImageRaw, 0, TRUE, LLViewerImageBoostLevel::OTHER); gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(mTexture); mTexture->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -593,7 +593,7 @@ void LLViewerParcelOverlay::addPropertyLine( break; default: - llwarns << "Invalid edge in addPropertyLine" << llendl; + llerrs << "Invalid edge in addPropertyLine" << llendl; return; } diff --git a/linden/indra/newview/llviewershadermgr.cpp b/linden/indra/newview/llviewershadermgr.cpp index 8648271e7..69f7bd8b1 100644 --- a/linden/indra/newview/llviewershadermgr.cpp +++ b/linden/indra/newview/llviewershadermgr.cpp @@ -113,8 +113,6 @@ LLGLSLShader gDeferredAvatarProgram; LLGLSLShader gDeferredAvatarAlphaProgram; LLGLSLShader gDeferredLightProgram; LLGLSLShader gDeferredMultiLightProgram; -LLGLSLShader gDeferredSpotLightProgram; -LLGLSLShader gDeferredMultiSpotLightProgram; LLGLSLShader gDeferredSunProgram; LLGLSLShader gDeferredBlurLightProgram; LLGLSLShader gDeferredSoftenProgram; @@ -122,12 +120,6 @@ LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAlphaProgram; LLGLSLShader gDeferredFullbrightProgram; -LLGLSLShader gDeferredGIProgram; -LLGLSLShader gDeferredPostGIProgram; -LLGLSLShader gDeferredPostProgram; - -LLGLSLShader gLuminanceGatherProgram; - //current avatar shader parameter pointer GLint gAvatarMatrixParam; @@ -159,9 +151,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredMultiLightProgram); mShaderList.push_back(&gDeferredAlphaProgram); mShaderList.push_back(&gDeferredFullbrightProgram); - mShaderList.push_back(&gDeferredPostGIProgram); - mShaderList.push_back(&gDeferredPostProgram); - mShaderList.push_back(&gDeferredGIProgram); mShaderList.push_back(&gDeferredWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); } @@ -231,32 +220,13 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) mReservedUniforms.push_back("shadowMap1"); mReservedUniforms.push_back("shadowMap2"); mReservedUniforms.push_back("shadowMap3"); - mReservedUniforms.push_back("shadowMap4"); - mReservedUniforms.push_back("shadowMap5"); - mReservedUniforms.push_back("normalMap"); mReservedUniforms.push_back("positionMap"); mReservedUniforms.push_back("diffuseRect"); mReservedUniforms.push_back("specularRect"); mReservedUniforms.push_back("noiseMap"); - mReservedUniforms.push_back("lightFunc"); mReservedUniforms.push_back("lightMap"); - mReservedUniforms.push_back("luminanceMap"); - mReservedUniforms.push_back("giLightMap"); - mReservedUniforms.push_back("sunLightMap"); - mReservedUniforms.push_back("localLightMap"); - mReservedUniforms.push_back("projectionMap"); - mReservedUniforms.push_back("diffuseGIMap"); - mReservedUniforms.push_back("specularGIMap"); - mReservedUniforms.push_back("normalGIMap"); - mReservedUniforms.push_back("minpGIMap"); - mReservedUniforms.push_back("maxpGIMap"); - mReservedUniforms.push_back("depthGIMap"); - mReservedUniforms.push_back("lastDiffuseGIMap"); - mReservedUniforms.push_back("lastNormalGIMap"); - mReservedUniforms.push_back("lastMinpGIMap"); - mReservedUniforms.push_back("lastMaxpGIMap"); - + mWLUniforms.push_back("camPosLocal"); mTerrainUniforms.reserve(5); @@ -784,9 +754,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects() } } - - // KL enabling loading of postprocess shaders until we fix - // ATI may still have issues +#if 0 + // disabling loading of postprocess shaders until we fix + // ATI sampler2DRect compatibility. //load Color Filter Shader if (success) @@ -827,7 +797,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gPostNightVisionProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms); } - + #endif return success; @@ -844,8 +814,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTerrainProgram.unload(); gDeferredLightProgram.unload(); gDeferredMultiLightProgram.unload(); - gDeferredSpotLightProgram.unload(); - gDeferredMultiSpotLightProgram.unload(); gDeferredSunProgram.unload(); gDeferredBlurLightProgram.unload(); gDeferredSoftenProgram.unload(); @@ -855,10 +823,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.unload(); gDeferredAlphaProgram.unload(); gDeferredFullbrightProgram.unload(); - gDeferredPostGIProgram.unload(); - gDeferredPostProgram.unload(); - gLuminanceGatherProgram.unload(); - gDeferredGIProgram.unload(); gDeferredWaterProgram.unload(); return FALSE; } @@ -927,26 +891,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredMultiLightProgram.createShader(NULL, NULL); } - if (success) - { - gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; - gDeferredSpotLightProgram.mShaderFiles.clear(); - gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredSpotLightProgram.createShader(NULL, NULL); - } - - if (success) - { - gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; - gDeferredMultiSpotLightProgram.mShaderFiles.clear(); - gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); - } - if (success) { gDeferredSunProgram.mName = "Deferred Sun Shader"; @@ -996,36 +940,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredFullbrightProgram.createShader(NULL, NULL); } - if (success) - { - gDeferredPostGIProgram.mName = "Deferred Post GI Shader"; - gDeferredPostGIProgram.mShaderFiles.clear(); - gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredPostGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostGIProgram.createShader(NULL, NULL); - } - - if (success) - { - gDeferredPostProgram.mName = "Deferred Post Shader"; - gDeferredPostProgram.mShaderFiles.clear(); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostProgram.createShader(NULL, NULL); - } - - if (success) - { - gDeferredGIProgram.mName = "Deferred GI Shader"; - gDeferredGIProgram.mShaderFiles.clear(); - gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredGIProgram.createShader(NULL, NULL); - } - if (success) { // load water shader @@ -1108,16 +1022,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms); } - if (success) - { - gLuminanceGatherProgram.mName = "Luminance Gather Shader"; - gLuminanceGatherProgram.mShaderFiles.clear(); - gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceV.glsl", GL_VERTEX_SHADER_ARB)); - gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER_ARB)); - gLuminanceGatherProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gLuminanceGatherProgram.createShader(NULL, NULL); - } - return success; } diff --git a/linden/indra/newview/llviewershadermgr.h b/linden/indra/newview/llviewershadermgr.h index bb5077906..a743966d9 100644 --- a/linden/indra/newview/llviewershadermgr.h +++ b/linden/indra/newview/llviewershadermgr.h @@ -116,30 +116,12 @@ class LLViewerShaderMgr: public LLShaderMgr DEFERRED_SHADOW1, DEFERRED_SHADOW2, DEFERRED_SHADOW3, - DEFERRED_SHADOW4, - DEFERRED_SHADOW5, DEFERRED_NORMAL, DEFERRED_POSITION, DEFERRED_DIFFUSE, DEFERRED_SPECULAR, DEFERRED_NOISE, - DEFERRED_LIGHTFUNC, DEFERRED_LIGHT, - DEFERRED_LUMINANCE, - DEFERRED_GI_LIGHT, - DEFERRED_SUN_LIGHT, - DEFERRED_LOCAL_LIGHT, - DEFERRED_PROJECTION, - DEFERRED_GI_DIFFUSE, - DEFERRED_GI_SPECULAR, - DEFERRED_GI_NORMAL, - DEFERRED_GI_MIN_POS, - DEFERRED_GI_MAX_POS, - DEFERRED_GI_DEPTH, - DEFERRED_GI_LAST_DIFFUSE, - DEFERRED_GI_LAST_NORMAL, - DEFERRED_GI_LAST_MIN_POS, - DEFERRED_GI_LAST_MAX_POS, END_RESERVED_UNIFORMS } eGLSLReservedUniforms; @@ -344,23 +326,16 @@ extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTreeProgram; extern LLGLSLShader gDeferredLightProgram; extern LLGLSLShader gDeferredMultiLightProgram; -extern LLGLSLShader gDeferredSpotLightProgram; -extern LLGLSLShader gDeferredMultiSpotLightProgram; extern LLGLSLShader gDeferredSunProgram; -extern LLGLSLShader gDeferredGIProgram; extern LLGLSLShader gDeferredBlurLightProgram; extern LLGLSLShader gDeferredAvatarProgram; extern LLGLSLShader gDeferredSoftenProgram; extern LLGLSLShader gDeferredShadowProgram; -extern LLGLSLShader gDeferredPostGIProgram; -extern LLGLSLShader gDeferredPostProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; extern LLGLSLShader gDeferredFullbrightProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; -extern LLGLSLShader gLuminanceGatherProgram; - //current avatar shader parameter pointer extern GLint gAvatarMatrixParam; diff --git a/linden/indra/newview/llviewerstats.h b/linden/indra/newview/llviewerstats.h index 9107ad6ee..b176632d0 100644 --- a/linden/indra/newview/llviewerstats.h +++ b/linden/indra/newview/llviewerstats.h @@ -196,7 +196,7 @@ class LLViewerStats : public LLSingleton<LLViewerStats> F64 mLastTimeDiff; // used for time stat updates }; -static const F32 SEND_STATS_PERIOD = 3000.0f; +static const F32 SEND_STATS_PERIOD = 300.0f; // The following are from (older?) statistics code found in appviewer. void init_statistics(); diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index 2ed2f37eb..f4b738f0f 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -473,27 +473,6 @@ class LLDebugText ypos += y_inc; - { - std::ostringstream ostr; - ostr << "Shadow error: " << gPipeline.mShadowError; - addText(xpos, ypos, ostr.str()); - ypos += y_inc; - } - - { - std::ostringstream ostr; - ostr << "Shadow FOV: " << gPipeline.mShadowFOV; - addText(xpos, ypos, ostr.str()); - ypos += y_inc; - } - - { - std::ostringstream ostr; - ostr << "Shadow Splits: " << gPipeline.mSunClipPlanes; - addText(xpos, ypos, ostr.str()); - ypos += y_inc; - } - LLVertexBuffer::sBindCount = LLImageGL::sBindCount = LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; @@ -1351,6 +1330,7 @@ LLViewerWindow::LLViewerWindow( // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. + LLImageGL::initClass(LLViewerImageBoostLevel::MAX_GL_IMAGE_CATEGORY) ; gImageList.init(); LLViewerImage::initClass(); gBumpImageList.init(); @@ -1463,7 +1443,7 @@ void LLViewerWindow::initBase() llassert( !gConsole ); gConsole = new LLConsole( "console", - //gSavedSettings.getS32("ConsoleBufferSize"), + gSavedSettings.getS32("ConsoleBufferSize"), getChatConsoleRect(), gSavedSettings.getS32("ChatFontSize"), gSavedSettings.getF32("ChatPersistTime") ); @@ -2546,6 +2526,7 @@ BOOL LLViewerWindow::handlePerFrameHover() mMouseInWindow = TRUE; } + S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]); S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]); @@ -2570,7 +2551,7 @@ BOOL LLViewerWindow::handlePerFrameHover() mCurrentMouseDelta.set(dx, dy); mouse_vel.setVec((F32) dx, (F32) dy); } - + mMouseVelocityStat.addValue(mouse_vel.magVec()); if (gNoRender) @@ -2833,21 +2814,16 @@ BOOL LLViewerWindow::handlePerFrameHover() gFloaterView->setRect(floater_rect); } - { // snap floaters to top of chat bar/button strip LLView* chatbar_and_buttons = gOverlayBar->getChild<LLView>("chatbar_and_buttons", TRUE); - S32 top, left; - S32 chatbar_and_buttons_x = chatbar_and_buttons->getLocalBoundingRect().mLeft; - S32 chatbar_and_buttons_y = chatbar_and_buttons->getLocalBoundingRect().mTop; - // find top of chatbar and state buttons, if either are visible if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull()) { - // convert top/left corner of chatbar/buttons container to - // gFloaterView-relative coordinates + // convert top/left corner of chatbar/buttons container to gFloaterView-relative coordinates + S32 top, left; chatbar_and_buttons->localPointToOtherView( - chatbar_and_buttons_x, - chatbar_and_buttons_y, + chatbar_and_buttons->getLocalBoundingRect().mLeft, + chatbar_and_buttons->getLocalBoundingRect().mTop, &left, &top, gFloaterView); @@ -2855,9 +2831,10 @@ BOOL LLViewerWindow::handlePerFrameHover() } else if (gToolBar->getVisible()) { + S32 top, left; gToolBar->localPointToOtherView( - chatbar_and_buttons_x, - chatbar_and_buttons_y, + gToolBar->getLocalBoundingRect().mLeft, + gToolBar->getLocalBoundingRect().mTop, &left, &top, gFloaterView); @@ -2867,7 +2844,7 @@ BOOL LLViewerWindow::handlePerFrameHover() { gFloaterView->setSnapOffsetBottom(0); } - } + // Always update console LLRect console_rect = getChatConsoleRect(); console_rect.mBottom = gHUDView->getRect().mBottom + getChatConsoleBottomPad(); @@ -2875,8 +2852,8 @@ BOOL LLViewerWindow::handlePerFrameHover() gConsole->setRect(console_rect); } - mLastMousePoint = mCurrentMousePoint; + // last ditch force of edit menu to selection manager if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) { @@ -2939,6 +2916,7 @@ BOOL LLViewerWindow::handlePerFrameHover() &gDebugRaycastBinormal); } + // per frame picking - for tooltips and changing cursor over interactive objects static S32 previous_x = -1; static S32 previous_y = -1; @@ -2981,6 +2959,7 @@ BOOL LLViewerWindow::handlePerFrameHover() previous_x = x; previous_y = y; + return handled; } @@ -4078,7 +4057,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei { if(image_width > window_width || image_height > window_height) //need to enlarge the scene { - if (!LLPipeline::sRenderDeferred && gGLManager.mHasFramebufferObject && !show_ui) + if (gGLManager.mHasFramebufferObject && !show_ui) { GLint max_size = 0; glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size); @@ -4167,17 +4146,10 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei else { const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); - if (LLPipeline::sRenderDeferred) - { - display(do_rebuild, scale_factor, subfield, FALSE); - } - else - { display(do_rebuild, scale_factor, subfield, TRUE); // Required for showing the GUI in snapshots? See DEV-16350 for details. JC render_ui(scale_factor, subfield); } - } S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width); // handle fractional rows diff --git a/linden/indra/newview/llvlcomposition.cpp b/linden/indra/newview/llvlcomposition.cpp index f96665b87..535c504ea 100644 --- a/linden/indra/newview/llvlcomposition.cpp +++ b/linden/indra/newview/llvlcomposition.cpp @@ -460,10 +460,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } } - if (!texturep->getHasGLTexture()) - { - texturep->createGLTexture(0, raw); - } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32(); LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin); diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index cd90c5917..6522a8b40 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -704,7 +704,6 @@ BOOL LLVOAvatar::sDebugInvisible = FALSE; BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; BOOL LLVOAvatar::sShowAnimationDebug = FALSE; BOOL LLVOAvatar::sShowFootPlane = FALSE; -BOOL LLVOAvatar::sShowCollisionVolumes = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; BOOL LLVOAvatar::sUseImpostors = FALSE; @@ -741,7 +740,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mTyping(FALSE), mMeshValid(FALSE), mVisible(FALSE), - mMeshTexturesDirty(FALSE), mWindFreq(0.f), mRipplePhase( 0.f ), mBelowWater(FALSE), @@ -802,7 +800,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mBakedTextureData[i].mLastTextureIndex = IMG_DEFAULT_AVATAR; mBakedTextureData[i].mTexLayerSet = NULL; mBakedTextureData[i].mIsLoaded = false; - //mBakedTextureData[i].mIsUsed = false; // KL SG + mBakedTextureData[i].mIsUsed = false; mBakedTextureData[i].mMaskTexName = 0; mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i); } @@ -858,11 +856,9 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mRippleTimeLast = 0.f; mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c"); - - // GL NOT ACTIVE HERE - //gGL.getTexUnit(0)->bind(mShadowImagep.get()); - //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - + gGL.getTexUnit(0)->bind(mShadowImagep.get()); + mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); + mInAir = FALSE; mStepOnLand = TRUE; @@ -1299,7 +1295,7 @@ void LLVOAvatar::resetImpostors() // static void LLVOAvatar::deleteCachedImages(bool clearAll) { -/* if(gAuditTexture) +if(gAuditTexture) { S32 total_tex_size = sScratchTexBytes ; S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; @@ -1341,7 +1337,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) total_tex_size -= 4 * tex_size ; } } -*/ + if (LLTexLayerSet::sHasCaches) { lldebugs << "Deleting layer set caches" << llendl; @@ -1866,11 +1862,6 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info) return TRUE; } -LLVOAvatar* LLVOAvatar::asAvatar() // KL SD -{ - return this; -} - //----------------------------------------------------------------------------- // LLVOAvatar::startDefaultMotions() //----------------------------------------------------------------------------- @@ -1933,7 +1924,7 @@ void LLVOAvatar::buildCharacter() LLTimer timer; BOOL status = loadAvatar(); - // stop_glerror(); + stop_glerror(); if (gNoRender) { @@ -2043,7 +2034,7 @@ void LLVOAvatar::buildCharacter() processAnimationStateChanges(); mIsBuilt = TRUE; -// stop_glerror(); + stop_glerror(); //------------------------------------------------------------------------- // build the attach and detach menus @@ -5050,7 +5041,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color) //------------------------------------------------------------------------ // LLVOAvatar::updateTextures() //------------------------------------------------------------------------ -void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version +void LLVOAvatar::updateTextures() { BOOL render_avatar = TRUE; @@ -5069,7 +5060,6 @@ void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version } std::vector<bool> layer_baked; - // GL NOT ACTIVE HERE - *TODO for (U32 i = 0; i < mBakedTextureData.size(); i++) { layer_baked.push_back(isTextureDefined(mBakedTextureData[i].mTextureIndex)); @@ -5152,7 +5142,13 @@ void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version if (texture_dict->mIsLocalTexture) { addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); + // SNOW-8 : temporary snowglobe1.0 fix for baked textures + if (render_avatar && !gGLManager.mIsDisabled ) + { + // bind the texture so that its boost level won't be slammed + gGL.getTexUnit(0)->bind(imagep); } + } else if (texture_dict->mIsBakedTexture) { if (layer_baked[baked_index]) @@ -5398,7 +5394,7 @@ void LLVOAvatar::processAnimationStateChanges() } } - //stop_glerror(); + stop_glerror(); } @@ -6383,15 +6379,6 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) } -void LLVOAvatar::updateGL() -{ - if (mMeshTexturesDirty) - { - updateMeshTextures(); - mMeshTexturesDirty = FALSE; - } -} - //----------------------------------------------------------------------------- // updateGeometry() //----------------------------------------------------------------------------- @@ -7429,20 +7416,12 @@ BOOL LLVOAvatar::bindScratchTexture( LLGLenum format ) if( *last_bind_time != LLImageGL::sLastFrameTime ) { *last_bind_time = LLImageGL::sLastFrameTime; -// #if !LL_RELEASE_FOR_DOWNLOAD -// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ; -// #else - LLImageGL::updateBoundTexMem(texture_bytes); -// #endif + LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; } } else { -// #if !LL_RELEASE_FOR_DOWNLOAD -// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ; -// #else - LLImageGL::updateBoundTexMem(texture_bytes); -// #endif + LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) ); } @@ -7464,8 +7443,7 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) { case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; -// Support for GL_EXT_paletted_texture is deprecated -// case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; + case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; case GL_RGB: components = 3; internal_format = GL_RGB8; break; case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; @@ -7507,11 +7485,11 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) LLVOAvatar::sScratchTexBytes += *texture_bytes; LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes; -/* + if(gAuditTexture) { LLImageGL::incTextureCounterStatic(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; - }*/ + } return name; } @@ -7614,7 +7592,6 @@ void LLVOAvatar::updateMeshTextures() use_lkg_baked_layer[i] = (!is_layer_baked[i] && (mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) && mBakedTextureData[i].mTexLayerSet - && mBakedTextureData[i].mTexLayerSet->getComposite() // KL SD && !mBakedTextureData[i].mTexLayerSet->getComposite()->isInitialized()); if (use_lkg_baked_layer[i]) { @@ -7648,7 +7625,7 @@ void LLVOAvatar::updateMeshTextures() if (use_lkg_baked_layer[i] && !self_customizing ) { LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureData[i].mLastTextureIndex, target_host ); - //mBakedTextureData[i].mIsUsed = TRUE; + mBakedTextureData[i].mIsUsed = TRUE; for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) { mBakedTextureData[i].mMeshes[k]->setTexture( baked_img ); @@ -7678,7 +7655,7 @@ void LLVOAvatar::updateMeshTextures() { mBakedTextureData[i].mTexLayerSet->createComposite(); mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( TRUE ); - // mBakedTextureData[i].mIsUsed = FALSE; + mBakedTextureData[i].mIsUsed = FALSE; for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) { mBakedTextureData[i].mMeshes[k]->setLayerSet( mBakedTextureData[i].mTexLayerSet ); @@ -7699,13 +7676,9 @@ void LLVOAvatar::updateMeshTextures() mBakedTextureData[BAKED_HAIR].mMeshes[i]->setTexture( hair_img ); } mHasBakedHair = FALSE; - } - else - { - for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++) - { - mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f ); } + else + { mHasBakedHair = TRUE; } @@ -7837,7 +7810,7 @@ void LLVOAvatar::clearChat() S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index ) { // If the texture is not local, we don't care and treat it as fully loaded - if (!isIndexLocalTexture(index)) return FALSE; // KL SD version + if (!isIndexLocalTexture(index)) return 0; LocalTextureData &local_tex_data = mLocalTextureData[index]; if (index >= 0 @@ -7979,7 +7952,7 @@ bool LLVOAvatar::hasPendingBakedUploads() { for (U32 i = 0; i < mBakedTextureData.size(); i++) { - bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite() && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); + bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); if (upload_pending) { return true; @@ -8514,8 +8487,7 @@ void LLVOAvatar::onFirstTEMessageReceived() } } - mMeshTexturesDirty = TRUE; // updateMeshTextures(); - gPipeline.markGLRebuild(this); + updateMeshTextures(); } } @@ -8578,22 +8550,20 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // (isTextureDefined(TEX_SKIRT_BAKED) ? "SKIRT " : "skirt " ) << (getTEImage(TEX_SKIRT_BAKED)->getID()) << std::endl << // (isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl << // (isTextureDefined(TEX_EYES_BAKED) ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ; - + if( !mFirstTEMessageReceived ) { onFirstTEMessageReceived(); } setCompositeUpdatesEnabled( FALSE ); - mMeshTexturesDirty = TRUE; - gPipeline.markGLRebuild(this); // KL SD needing work in S19? if (!mIsSelf) { releaseUnnecessaryTextures(); } - - //updateMeshTextures(); // enables updates for laysets without baked textures. + + updateMeshTextures(); // enables updates for laysets without baked textures. // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); @@ -8879,7 +8849,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) if (id == image_baked->getID()) { mBakedTextureData[i].mIsLoaded = true; - //mBakedTextureData[i].mIsUsed = true; + mBakedTextureData[i].mIsUsed = true; mBakedTextureData[i].mLastTextureIndex = id; for (U32 k = 0; k < mBakedTextureData[i].mMeshes.size(); k++) { @@ -9788,9 +9758,9 @@ BOOL LLVOAvatar::updateLOD() LLFace* facep = mDrawable->getFace(0); if (facep->mVertexBuffer.isNull() || - (LLVertexBuffer::sEnableVBOs && + LLVertexBuffer::sEnableVBOs && ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) != - (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))) + (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))) { mDirtyMesh = TRUE; } diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index ff07d81e7..0c32244e6 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h @@ -88,8 +88,6 @@ class LLVOAvatar : /*virtual*/ void markDead(); void startDefaultMotions(); - /*virtual*/ LLVOAvatar* asAvatar(); // KL SD - static void updateImpostors(); //-------------------------------------------------------------------- @@ -139,7 +137,7 @@ class LLVOAvatar : LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); - /*virtual*/ void updateTextures(LLAgent &agent); // KL SD + /*virtual*/ void updateTextures(); // If setting a baked texture, need to request it from a non-local sim. /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); /*virtual*/ void onShift(const LLVector3& shift_vector); @@ -157,8 +155,6 @@ class LLVOAvatar : /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - /*virtual*/ void updateGL(); - /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); BOOL updateJointLODs(); @@ -478,7 +474,6 @@ class LLVOAvatar : LLFrameTimer mTypingTimer; //-------------------------------------------------------------------- - BOOL mMeshTexturesDirty; // wind rippling in clothes //-------------------------------------------------------------------- public: @@ -575,7 +570,6 @@ class LLVOAvatar : static BOOL sShowAnimationDebug; // show animation debug info static BOOL sUseImpostors; //use impostors for far away avatars static BOOL sShowFootPlane; // show foot collision plane reported by server - static BOOL sShowCollisionVolumes; // show skeletal collision volumes // KL SD static BOOL sVisibleInFirstPerson; static S32 sNumLODChangesThisFrame; static S32 sNumVisibleChatBubbles; @@ -777,7 +771,7 @@ class LLVOAvatar : LLUUID mLastTextureIndex; LLTexLayerSet* mTexLayerSet; bool mIsLoaded; - //bool mIsUsed; // KL SG + bool mIsUsed; LLVOAvatarDefines::ETextureIndex mTextureIndex; U32 mMaskTexName; // Stores pointers to the joint meshes that this baked texture deals with diff --git a/linden/indra/newview/llvoclouds.cpp b/linden/indra/newview/llvoclouds.cpp index 019b6b4bc..a489f9177 100644 --- a/linden/indra/newview/llvoclouds.cpp +++ b/linden/indra/newview/llvoclouds.cpp @@ -101,7 +101,7 @@ void LLVOClouds::setPixelAreaAndAngle(LLAgent &agent) mPixelArea = 1500*100; } -void LLVOClouds::updateTextures(LLAgent &agent) +void LLVOClouds::updateTextures() { getTEImage(0)->addTextureStats(mPixelArea); } @@ -123,10 +123,7 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) return TRUE; } - if (drawable->isVisible()) - { - dirtySpatialGroup(TRUE); - } + dirtySpatialGroup(); LLFace *facep; diff --git a/linden/indra/newview/llvoclouds.h b/linden/indra/newview/llvoclouds.h index f70ea5b9e..52e5a681e 100644 --- a/linden/indra/newview/llvoclouds.h +++ b/linden/indra/newview/llvoclouds.h @@ -65,7 +65,7 @@ class LLVOClouds : public LLAlphaObject /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. F32 getPartSize(S32 idx); - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area void updateFaceSize(S32 idx) { } diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index 8f4c0de4f..f73887226 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -337,7 +337,7 @@ void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent) // BUG could speed this up by caching the relative_position and range calculations -void LLVOGrass::updateTextures(LLAgent &agent) +void LLVOGrass::updateTextures() { if (getTEImage(0)) { diff --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index 86e4b954a..25fa04cad 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -72,7 +72,7 @@ class LLVOGrass : public LLAlphaObject LLStrider<U16>& indicesp); void updateFaceSize(S32 idx) { } - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ BOOL updateLOD(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area diff --git a/linden/indra/newview/llvoground.cpp b/linden/indra/newview/llvoground.cpp index fe19e1815..0ef0196cc 100644 --- a/linden/indra/newview/llvoground.cpp +++ b/linden/indra/newview/llvoground.cpp @@ -71,7 +71,7 @@ BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } -void LLVOGround::updateTextures(LLAgent &agent) +void LLVOGround::updateTextures() { } diff --git a/linden/indra/newview/llvoground.h b/linden/indra/newview/llvoground.h index f485bd0aa..b58ebae33 100644 --- a/linden/indra/newview/llvoground.h +++ b/linden/indra/newview/llvoground.h @@ -51,7 +51,7 @@ class LLVOGround : public LLStaticViewerObject // Graphical stuff for objects - maybe broken out into render class // later? - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvopartgroup.cpp b/linden/indra/newview/llvopartgroup.cpp index b04036623..a0f80689e 100644 --- a/linden/indra/newview/llvopartgroup.cpp +++ b/linden/indra/newview/llvopartgroup.cpp @@ -108,7 +108,7 @@ void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) } } -void LLVOPartGroup::updateTextures(LLAgent &agent) +void LLVOPartGroup::updateTextures() { // Texture stats for particles need to be updated in a different way... } @@ -154,11 +154,6 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) group = drawable->getSpatialGroup(); } - if (group && group->isVisible()) - { - dirtySpatialGroup(TRUE); - } - if (!num_parts) { if (group && drawable->getNumFaces()) @@ -191,12 +186,13 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) S32 count=0; mDepth = 0.f; S32 i = 0 ; + LLVector3 camera_agent = getCameraPosition(); for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++) { const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; LLVector3 part_pos_agent(part->mPosAgent); - LLVector3 at(part_pos_agent - LLViewerCamera::getInstance()->getOrigin()); + LLVector3 at(part_pos_agent - camera_agent); F32 camera_dist_squared = at.lengthSquared(); F32 inv_camera_dist_squared; @@ -319,7 +315,7 @@ void LLVOPartGroup::getGeometry(S32 idx, up *= 0.5f*part.mScale.mV[1]; - const LLVector3& normal = -LLViewerCamera::getInstance()->getXAxis(); + LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); *verticesp++ = part_pos_agent + up - right; *verticesp++ = part_pos_agent - up - right; @@ -356,12 +352,12 @@ U32 LLVOPartGroup::getPartitionType() const } LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; mPartitionType = LLViewerRegion::PARTITION_PARTICLE; - // mBufferUsage = GL_DYNAMIC_DRAW_ARB; // KL SD hybrid code + mBufferUsage = GL_DYNAMIC_DRAW_ARB; mSlopRatio = 0.f; mLODPeriod = 1; } @@ -485,9 +481,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) U32 end = start + facep->getGeomCount()-1; U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); - LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), - facep->getTexture(), - buffer, fullbright); + LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), buffer, fullbright); info->mExtents[0] = group->mObjectExtents[0]; info->mExtents[1] = group->mObjectExtents[1]; info->mVSize = vsize; diff --git a/linden/indra/newview/llvopartgroup.h b/linden/indra/newview/llvopartgroup.h index 3dc329299..18583b4be 100644 --- a/linden/indra/newview/llvopartgroup.h +++ b/linden/indra/newview/llvopartgroup.h @@ -61,7 +61,7 @@ class LLVOPartGroup : public LLAlphaObject virtual U32 getPartitionType() const; /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvosky.cpp b/linden/indra/newview/llvosky.cpp index 817a510d0..8639b60af 100644 --- a/linden/indra/newview/llvosky.cpp +++ b/linden/indra/newview/llvosky.cpp @@ -293,7 +293,7 @@ void LLSkyTex::create(const F32 brightness) void LLSkyTex::createGLImage(S32 which) { - mImageGL[which]->createGLTexture(0, mImageRaw[which]); + mImageGL[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerImageBoostLevel::OTHER); mImageGL[which]->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -1102,10 +1102,10 @@ BOOL LLVOSky::updateSky() mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]); if ( mForceUpdate - || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD) + || ((dot_lighting < LIGHT_DIRECTION_THRESHOLD) || (delta_color.length() > COLOR_CHANGE_THRESHOLD) || !mInitialized) - && !direction.isExactlyZero())) + && !direction.isExactlyZero()) { mLastLightingDirection = direction; mLastTotalAmbient = mTotalAmbient; @@ -1187,7 +1187,7 @@ BOOL LLVOSky::updateSky() return TRUE; } -void LLVOSky::updateTextures(LLAgent &agent) +void LLVOSky::updateTextures() { if (mSunTexturep) { diff --git a/linden/indra/newview/llvosky.h b/linden/indra/newview/llvosky.h index 492557f6b..137082481 100644 --- a/linden/indra/newview/llvosky.h +++ b/linden/indra/newview/llvosky.h @@ -493,7 +493,7 @@ class LLVOSky : public LLStaticViewerObject // Graphical stuff for objects - maybe broken out into render class // later? - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvosurfacepatch.cpp b/linden/indra/newview/llvosurfacepatch.cpp index 7aa573944..1671880ba 100644 --- a/linden/indra/newview/llvosurfacepatch.cpp +++ b/linden/indra/newview/llvosurfacepatch.cpp @@ -134,7 +134,7 @@ void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent) } -void LLVOSurfacePatch::updateTextures(LLAgent &agent) +void LLVOSurfacePatch::updateTextures() { } @@ -177,19 +177,11 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) } -void LLVOSurfacePatch::updateGL() -{ - if (mPatchp) - { - mPatchp->updateGL(); - } -} - BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN); - dirtySpatialGroup(TRUE); + dirtySpatialGroup(); S32 min_comp, max_comp, range; min_comp = lltrunc(mPatchp->getMinComposition()); @@ -1021,12 +1013,12 @@ U32 LLVOSurfacePatch::getPartitionType() const } LLTerrainPartition::LLTerrainPartition() -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK) { mOcclusionEnabled = FALSE; - //mRenderByGroup = FALSE; // KL not for SD hybrid code + mRenderByGroup = FALSE; mInfiniteFarClip = TRUE; - //mBufferUsage = GL_DYNAMIC_DRAW_ARB; // and here too! + mBufferUsage = GL_DYNAMIC_DRAW_ARB; mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN; mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } diff --git a/linden/indra/newview/llvosurfacepatch.h b/linden/indra/newview/llvosurfacepatch.h index aaf4d41fa..d3b144774 100644 --- a/linden/indra/newview/llvosurfacepatch.h +++ b/linden/indra/newview/llvosurfacepatch.h @@ -64,7 +64,6 @@ class LLVOSurfacePatch : public LLStaticViewerObject virtual U32 getPartitionType() const; /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); - /*virtual*/ void updateGL(); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); /*virtual*/ void updateFaceSize(S32 idx); @@ -75,7 +74,7 @@ class LLVOSurfacePatch : public LLStaticViewerObject LLStrider<LLVector2> &texCoords1p, LLStrider<U16> &indicesp); - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); diff --git a/linden/indra/newview/llvotextbubble.cpp b/linden/indra/newview/llvotextbubble.cpp index de69aac03..5943f9be9 100644 --- a/linden/indra/newview/llvotextbubble.cpp +++ b/linden/indra/newview/llvotextbubble.cpp @@ -116,7 +116,7 @@ BOOL LLVOTextBubble::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } -void LLVOTextBubble::updateTextures(LLAgent &agent) +void LLVOTextBubble::updateTextures() { // Update the image levels of all textures... diff --git a/linden/indra/newview/llvotextbubble.h b/linden/indra/newview/llvotextbubble.h index 45d4df2a7..7f84dbf63 100644 --- a/linden/indra/newview/llvotextbubble.h +++ b/linden/indra/newview/llvotextbubble.h @@ -44,7 +44,7 @@ class LLVOTextBubble : public LLAlphaObject /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index 9ec002dfe..6a59253a9 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -482,7 +482,7 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) #endif } -void LLVOTree::updateTextures(LLAgent &agent) +void LLVOTree::updateTextures() { if (mTreeImagep) { @@ -1318,9 +1318,9 @@ U32 LLVOTree::getPartitionType() const } LLTreePartition::LLTreePartition() -: LLSpatialPartition(0, FALSE, 0) +: LLSpatialPartition(0) { - // mRenderByGroup = FALSE; // SD hybrid + mRenderByGroup = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; mSlopRatio = 0.f; diff --git a/linden/indra/newview/llvotree.h b/linden/indra/newview/llvotree.h index 7804ab3f9..855c612b8 100644 --- a/linden/indra/newview/llvotree.h +++ b/linden/indra/newview/llvotree.h @@ -69,7 +69,7 @@ class LLVOTree : public LLViewerObject // Graphical stuff for objects - maybe broken out into render class later? /*virtual*/ void render(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvotreenew.h b/linden/indra/newview/llvotreenew.h index 02f6d3a05..4960d909c 100644 --- a/linden/indra/newview/llvotreenew.h +++ b/linden/indra/newview/llvotreenew.h @@ -156,7 +156,7 @@ class LLVOTreeNew : public LLViewerObject /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ void render(LLAgent &agent); - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index 77c9c332d..13a07049f 100644 --- a/linden/indra/newview/llvovolume.cpp +++ b/linden/indra/newview/llvovolume.cpp @@ -54,7 +54,6 @@ #include "llspatialpartition.h" #include "llhudmanager.h" #include "llflexibleobject.h" - #include "llsky.h" #include "lltexturefetch.h" #include "llviewercamera.h" @@ -68,9 +67,6 @@ const S32 MIN_QUIET_FRAMES_COALESCE = 30; const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; -const F32 MAX_LOD_DISTANCE = 24.f; -const S32 MAX_SCULPT_REZ = 128; - BOOL gAnimateTextures = TRUE; extern BOOL gHideSelectedObjects; @@ -95,7 +91,6 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mNumFaces = 0; mLODChanged = FALSE; mSculptChanged = FALSE; - mSpotLightPriority = 0.f; } LLVOVolume::~LLVOVolume() @@ -219,7 +214,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, std::string mask; mask = gDirUtilp->getDirDelimiter() + "*.slc"; gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), mask); -// llwarns << "Bogus TE data in " << getID() << ", crashing!" << llendl; +// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl; llwarns << "Bogus TE data in " << getID() << llendl; } else if (res2 & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR)) @@ -319,6 +314,11 @@ void LLVOVolume::animateTextures() te->getScale(&scale_s, &scale_t); } + LLVector3 scale(scale_s, scale_t, 1.f); + LLVector3 trans(off_s+0.5f, off_t+0.5f, 0.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); + if (!facep->mTextureMatrix) { facep->mTextureMatrix = new LLMatrix4(); @@ -326,43 +326,7 @@ void LLVOVolume::animateTextures() LLMatrix4& tex_mat = *facep->mTextureMatrix; tex_mat.setIdentity(); - LLVector3 trans ; - - if(facep->isAtlasInUse()) - { - // - //if use atlas for animated texture - //apply the following transform to the animation matrix. - // - - F32 tcoord_xoffset = 0.f ; - F32 tcoord_yoffset = 0.f ; - F32 tcoord_xscale = 1.f ; - F32 tcoord_yscale = 1.f ; - if(facep->isAtlasInUse()) - { - const LLVector2* tmp = facep->getTexCoordOffset() ; - tcoord_xoffset = tmp->mV[0] ; - tcoord_yoffset = tmp->mV[1] ; - - tmp = facep->getTexCoordScale() ; - tcoord_xscale = tmp->mV[0] ; - tcoord_yscale = tmp->mV[1] ; - } - trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); - - tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); - } - else //non atlas - { - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); - } - - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); - + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); tex_mat.rotate(quat); LLMatrix4 mat; @@ -439,28 +403,30 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) return TRUE; } -void LLVOVolume::updateTextures(LLAgent &agent) // KL sd +void LLVOVolume::updateTextures() { const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds - if (mDrawable.notNull() && mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) + if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) { - if (mDrawable->isVisible()) - { - updateTextures(); - } + updateTextureVirtualSize(); } } -void LLVOVolume::updateTextures() +void LLVOVolume::updateTextureVirtualSize() { // Update the pixel area of all faces + if(mDrawable.isNull() || !mDrawable->isVisible()) + { + return ; + } + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) { return; } - if (LLViewerImage::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible()) + if (LLViewerImage::sDontLoadVolumeTextures || LLAppViewer::getTextureFetch()->mDebugPause) { return; } @@ -477,14 +443,15 @@ void LLVOVolume::updateTextures() LLFace* face = mDrawable->getFace(i); const LLTextureEntry *te = face->getTextureEntry(); LLViewerImage *imagep = face->getTexture(); - if (!imagep || !te || + if (!imagep || !te || face->mExtents[0] == face->mExtents[1]) { continue; } F32 vsize; - + F32 old_size = face->getVirtualSize(); + if (isHUDAttachment()) { F32 area = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); @@ -494,24 +461,21 @@ void LLVOVolume::updateTextures() } else { - vsize = getTextureVirtualSize(face); + vsize = face->getTextureVirtualSize(); } - mPixelArea = llmax(mPixelArea, face->getPixelArea()); - - F32 old_size = face->getVirtualSize(); + mPixelArea = llmax(mPixelArea, face->getPixelArea()); if (face->mTextureMatrix != NULL) { - if (vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE || - vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE) + if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || + (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE); } } face->setVirtualSize(vsize); - // imagep->addTextureStats(vsize); if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { if (vsize < min_vsize) min_vsize = vsize; @@ -539,46 +503,46 @@ void LLVOVolume::updateTextures() mSculptTexture = gImageList.getImage(id); if (mSculptTexture.notNull()) { - S32 lod = llmin(mLOD, 3); - F32 lodf = ((F32)(lod + 1.0f)/4.f); - F32 tex_size = lodf * MAX_SCULPT_REZ; - mSculptTexture->addTextureStats(2.f * tex_size * tex_size); mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), (S32)LLViewerImageBoostLevel::BOOST_SCULPTED)); - } - - S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture - S32 current_discard = mSculptLevel; + mSculptTexture->setForSculpt() ; + + if(!mSculptTexture->isCachedRawImageReady()) + { + S32 lod = llmin(mLOD, 3); + F32 lodf = ((F32)(lod + 1.0f)/4.f); + F32 tex_size = lodf * LLViewerImage::sMaxSculptRez ; + mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); + + //if the sculpty very close to the view point, load first + { + LLVector3 lookAt = getPositionAgent() - LLViewerCamera::getInstance()->getOrigin(); + F32 dist = lookAt.normVec() ; + F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; + mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ; + } + } + + S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture + S32 current_discard = mSculptLevel; - if (texture_discard >= 0 && //texture has some data available - (texture_discard < current_discard || //texture has more data than last rebuild - current_discard < 0)) //no previous rebuild - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); - mSculptChanged = TRUE; - } + if (texture_discard >= 0 && //texture has some data available + (texture_discard < current_discard || //texture has more data than last rebuild + current_discard < 0)) //no previous rebuild + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); + mSculptChanged = TRUE; + } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) { setDebugText(llformat("T%d C%d V%d\n%dx%d", - texture_discard, current_discard, getVolume()->getSculptLevel(), - mSculptTexture->getHeight(), mSculptTexture->getWidth())); + texture_discard, current_discard, getVolume()->getSculptLevel(), + mSculptTexture->getHeight(), mSculptTexture->getWidth())); } + } } - if (getLightTextureID().notNull()) - { - LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - LLUUID id = params->getLightTexture(); - mLightTexture = gImageList.getImage(id); - if (mLightTexture.notNull()) - { - F32 rad = getLightRadius(); - mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), - LLVector3(rad,rad,rad), - *LLViewerCamera::getInstance())); - } - } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { @@ -599,36 +563,6 @@ void LLVOVolume::updateTextures() } } -F32 LLVOVolume::getTextureVirtualSize(LLFace* face) -{ - //get area of circle around face - LLVector3 center = face->getPositionAgent(); - LLVector3 size = (face->mExtents[1] - face->mExtents[0]) * 0.5f; - - F32 face_area = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); - - face->setPixelArea(face_area); - - if (face_area <= 0) - { - return 0.f; - } - - //get area of circle in texture space - LLVector2 tdim = face->mTexExtents[1] - face->mTexExtents[0]; - F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; - if (texel_area <= 0) - { - // Probably animated, use default - texel_area = 1.f; - } - - //apply texel area to face area to get accurate ratio - face_area /= llclamp(texel_area, 1.f/64.f, 16.f); - - return face_area; -} - BOOL LLVOVolume::isActive() const { return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()); @@ -765,31 +699,21 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() -{ - U16 sculpt_height = 0; - U16 sculpt_width = 0; - S8 sculpt_components = 0; - const U8* sculpt_data = NULL; - +{ if (mSculptTexture.notNull()) - { - S32 discard_level; - S32 desired_discard = 0; // lower discard levels have MUCH less resolution - - discard_level = desired_discard; + { + U16 sculpt_height = 0; + U16 sculpt_width = 0; + S8 sculpt_components = 0; + const U8* sculpt_data = NULL; + + S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; + LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; S32 max_discard = mSculptTexture->getMaxDiscardLevel(); if (discard_level > max_discard) discard_level = max_discard; // clamp to the best we can do - S32 best_discard = mSculptTexture->getDiscardLevel(); - if (discard_level < best_discard) - discard_level = best_discard; // clamp to what we have - - if (best_discard == -1) - discard_level = -1; // and if we have nothing, set to nothing - - S32 current_discard = getVolume()->getSculptLevel(); if(current_discard < -2) { @@ -811,28 +735,17 @@ void LLVOVolume::sculpt() if (current_discard == discard_level) // no work to do here return; - LLPointer<LLImageRaw> raw_image = new LLImageRaw(); - BOOL is_valid = mSculptTexture->readBackRaw(discard_level, raw_image, FALSE); - - sculpt_height = raw_image->getHeight(); - sculpt_width = raw_image->getWidth(); - sculpt_components = raw_image->getComponents(); - - if(is_valid) - { - is_valid = mSculptTexture->isValidForSculpt(discard_level, sculpt_width, sculpt_height, sculpt_components) ; - } - if(!is_valid) + if(!raw_image) { sculpt_width = 0; sculpt_height = 0; sculpt_data = NULL ; } else - { - if (raw_image->getDataSize() < sculpt_height * sculpt_width * sculpt_components) - llwarns << "Sculpt: image data size = " << raw_image->getDataSize() - << " < " << sculpt_height << " x " << sculpt_width << " x " <<sculpt_components << llendl; + { + sculpt_height = raw_image->getHeight(); + sculpt_width = raw_image->getWidth(); + sculpt_components = raw_image->getComponents(); sculpt_data = raw_image->getData(); } @@ -864,7 +777,7 @@ BOOL LLVOVolume::calcLOD() } //update face texture sizes on lod calculation - // updateTextureVirtualSize(); + updateTextureVirtualSize(); S32 cur_detail = 0; @@ -1318,15 +1231,28 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color) S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) { - S32 res = LLViewerObject::setTEColor(te, color); - if (res && mDrawable.notNull()) + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) { - //gPipeline.markTextured(mDrawable); - mDrawable->setState(LLDrawable::REBUILD_COLOR); - dirtyMesh(); - //mFaceMappingChanged = TRUE; + llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; } - return res; + else if (color != tep->getColor()) + { + if (color.mV[3] != tep->getColor().mV[3]) + { + gPipeline.markTextured(mDrawable); + } + retval = LLPrimitive::setTEColor(te, color); + if (mDrawable.notNull() && retval) + { + // These should only happen on updates which are not the initial update. + mDrawable->setState(LLDrawable::REBUILD_COLOR); + dirtyMesh(); + } + } + + return retval; } S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap) @@ -1392,7 +1318,7 @@ S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump) gPipeline.markTextured(mDrawable); mFaceMappingChanged = TRUE; } - return res; + return res; } S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) @@ -1461,40 +1387,6 @@ void LLVOVolume::updateTEData() //---------------------------------------------------------------------------- -void LLVOVolume::setLightTextureID(LLUUID id) -{ - if (id.notNull()) - { - if (!hasLightTexture()) - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); - } - LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block && param_block->getLightTexture() != id) - { - param_block->setLightTexture(id); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - } - } - else - { - if (hasLightTexture()) - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); - } - } -} - -void LLVOVolume::setSpotLightParams(LLVector3 params) -{ - LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block && param_block->getParams() != params) - { - param_block->setParams(params); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - } -} - void LLVOVolume::setIsLight(BOOL is_light) { if (is_light != getIsLight()) @@ -1621,77 +1513,6 @@ LLColor3 LLVOVolume::getLightColor() const } } -LLUUID LLVOVolume::getLightTextureID() const -{ - const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block) - { - return param_block->getLightTexture(); - } - - return LLUUID::null; -} - - -LLVector3 LLVOVolume::getSpotLightParams() const -{ - const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block) - { - return param_block->getParams(); - } - - return LLVector3(); -} - -F32 LLVOVolume::getSpotLightPriority() const -{ - return mSpotLightPriority; -} - -void LLVOVolume::updateSpotLightPriority() -{ - LLVector3 pos = mDrawable->getPositionAgent(); - LLVector3 at(0,0,-1); - at *= getRenderRotation(); - - F32 r = getLightRadius()*0.5f; - - pos += at * r; - - at = LLViewerCamera::getInstance()->getAtAxis(); - - pos -= at * r; - - mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); - // KL needed for S19? - if (mLightTexture.notNull()) - { - mLightTexture->addTextureStats(mSpotLightPriority); - mLightTexture->setBoostLevel(LLViewerImageBoostLevel::BOOST_CLOUDS); - } -} - - -LLViewerImage* LLVOVolume::getLightTexture() -{ - LLUUID id = getLightTextureID(); - - if (id.notNull()) - { - if (mLightTexture.isNull() || id != mLightTexture->getID()) - { - mLightTexture = gImageList.getImage(id); - } - } - else - { - mLightTexture = NULL; - } - - return mLightTexture; -} - F32 LLVOVolume::getLightIntensity() const { const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); @@ -1783,16 +1604,6 @@ BOOL LLVOVolume::isSculpted() const return FALSE; } -BOOL LLVOVolume::hasLightTexture() const -{ - if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - return TRUE; - } - - return FALSE; -} - BOOL LLVOVolume::isVolumeGlobal() const { if (mVolumeImpl) @@ -2245,9 +2056,9 @@ U32 LLVOVolume::getPartitionType() const } LLVolumePartition::LLVolumePartition() -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) // KL +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, FALSE) { - mLODPeriod = 32; // KL 32 in SD + mLODPeriod = 16; mDepthMask = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_VOLUME; @@ -2256,10 +2067,10 @@ LLVolumePartition::LLVolumePartition() } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) -: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK) // KL SD +: LLSpatialBridge(drawablep, LLVOVolume::VERTEX_DATA_MASK) { mDepthMask = FALSE; - mLODPeriod = 32; // KL 32 in SD + mLODPeriod = 16; mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; @@ -2314,7 +2125,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); - LLImageGL* tex = facep->getGLTexture(); // LLViewerImage* tex = facep->getTexture(); // KL SD + LLViewerImage* tex = facep->getTexture(); U8 glow = 0; @@ -2325,7 +2136,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (facep->mVertexBuffer.isNull()) { - llwarns << "WTF?" << llendl; + llerrs << "WTF?" << llendl; } if (idx >= 0 && @@ -2356,7 +2167,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset,tex, - (LLImageGL*)facep->getTexture() == tex ? facep->getTexture() : NULL, facep->mVertexBuffer, fullbright, bump); draw_info->mGroup = group; draw_info->mVSize = facep->getVirtualSize(); @@ -2449,11 +2259,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); llassert_always(vobj); - vobj->updateTextures(); + vobj->updateTextureVirtualSize(); vobj->preRebuild(); - drawablep->clearState(LLDrawable::HAS_ALPHA); // KL SD - //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -2522,7 +2330,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { - drawablep->setState(LLDrawable::HAS_ALPHA); // KL SD alpha_faces.push_back(facep); } } @@ -2546,7 +2353,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { //doesn't need normal - //facep->setState(LLFace::FULLBRIGHT); + facep->setState(LLFace::FULLBRIGHT); fullbright_faces.push_back(facep); } } @@ -2556,14 +2363,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //needs normal + binormal bump_faces.push_back(facep); } - else if (te->getShiny() && LLPipeline::sRenderBump || + else if ((te->getShiny() && LLPipeline::sRenderBump) || !te->getFullbright()) { //needs normal simple_faces.push_back(facep); } else { //doesn't need normal - // facep->setState(LLFace::FULLBRIGHT); + facep->setState(LLFace::FULLBRIGHT); fullbright_faces.push_back(facep); } } @@ -2611,7 +2418,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (LLPipeline::sDelayVBUpdate) { - group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); // KL SD + group->setState(LLSpatialGroup::MESH_DIRTY); } mFaceList.clear(); @@ -2619,7 +2426,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) // KL SD + if (group->isState(LLSpatialGroup::MESH_DIRTY)) { S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ; @@ -2697,7 +2504,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } } - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); // KL SD + group->clearState(LLSpatialGroup::MESH_DIRTY); } } @@ -2723,7 +2530,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: LLSpatialGroup::buffer_map_t buffer_map; - LLImageGL* last_tex = NULL;// LLViewerImage* last_tex = NULL; // KL SD + LLViewerImage* last_tex = NULL; S32 buffer_index = 0; if (distance_sort) @@ -2735,7 +2542,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //pull off next face LLFace* facep = *face_iter; - LLImageGL* tex = facep->getGLTexture(); // LLViewerImage* tex = facep->getTexture(); // KL SD + LLViewerImage* tex = facep->getTexture(); if (distance_sort) { @@ -2760,7 +2567,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: ++i; while (i != faces.end() && - (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getGLTexture() == tex))) // KL SD getTexture + (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) { facep = *i; @@ -2843,11 +2650,6 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); - if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) // KL SD - { //paranoia check to make sure GL doesn't try to read non-existant normals - fullbright = TRUE; - } - const LLTextureEntry* te = facep->getTextureEntry(); BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; @@ -2899,7 +2701,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - // llassert(mask & LLVertexBuffer::MAP_NORMAL); + llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } @@ -2930,7 +2732,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - // llassert(mask & LLVertexBuffer::MAP_NORMAL); + llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } @@ -2943,8 +2745,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!is_alpha && !LLPipeline::sRenderDeferred) { - // llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); - facep->setPoolType(LLDrawPool::POOL_SIMPLE); // facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); + llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); + facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); if (!force_simple && te->getBumpmap()) { @@ -3023,7 +2825,7 @@ LLHUDPartition::LLHUDPartition() mPartitionType = LLViewerRegion::PARTITION_HUD; mDrawableType = LLPipeline::RENDER_TYPE_HUD; mSlopRatio = 0.f; - mLODPeriod = 32; // KL 32 in SD + mLODPeriod = 1; } void LLHUDPartition::shift(const LLVector3 &offset) diff --git a/linden/indra/newview/llvovolume.h b/linden/indra/newview/llvovolume.h index 4c6ad9af2..a78aa37ff 100644 --- a/linden/indra/newview/llvovolume.h +++ b/linden/indra/newview/llvovolume.h @@ -130,7 +130,7 @@ class LLVOVolume : public LLViewerObject BOOL getVolumeChanged() const { return mVolumeChanged; } - F32 getTextureVirtualSize(LLFace* face); + /*virtual*/ F32 getRadius() const { return mVObjRadius; }; const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; @@ -158,14 +158,14 @@ class LLVOVolume : public LLViewerObject /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump); /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny); /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright); - /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); // KL S19? + /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s); /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t); /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen); - /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media); // KL S19 + /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media); /*virtual*/ BOOL setMaterial(const U8 material); void setTexture(const S32 face); @@ -177,8 +177,8 @@ class LLVOVolume : public LLViewerObject /*virtual*/ void updateFaceSize(S32 idx); /*virtual*/ BOOL updateLOD(); void updateRadius(); - /*virtual*/ void updateTextures(LLAgent &agent); - void updateTextures(); + /*virtual*/ void updateTextures(); + void updateTextureVirtualSize(); void updateFaceFlags(); void regenFaces(); @@ -196,18 +196,9 @@ class LLVOVolume : public LLViewerObject void setLightRadius(F32 radius); void setLightFalloff(F32 falloff); void setLightCutoff(F32 cutoff); - void setLightTextureID(LLUUID id); - void setSpotLightParams(LLVector3 params); - BOOL getIsLight() const; LLColor3 getLightBaseColor() const; // not scaled by intensity LLColor3 getLightColor() const; // scaled by intensity - LLUUID getLightTextureID() const; - LLVector3 getSpotLightParams() const; - void updateSpotLightPriority(); - F32 getSpotLightPriority() const; - - LLViewerImage* getLightTexture(); F32 getLightIntensity() const; F32 getLightRadius() const; F32 getLightFalloff() const; @@ -217,8 +208,6 @@ class LLVOVolume : public LLViewerObject U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; virtual BOOL isSculpted() const; - virtual BOOL hasLightTexture() const; - BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); @@ -244,14 +233,12 @@ class LLVOVolume : public LLViewerObject BOOL mLODChanged; S32 mSculptLevel; BOOL mSculptChanged; - F32 mSpotLightPriority; LLMatrix4 mRelativeXform; LLMatrix3 mRelativeXformInvTrans; BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; LLPointer<LLViewerImage> mSculptTexture; - LLPointer<LLViewerImage> mLightTexture; // statics public: diff --git a/linden/indra/newview/llvowater.cpp b/linden/indra/newview/llvowater.cpp index 251667c5c..c66295ab1 100644 --- a/linden/indra/newview/llvowater.cpp +++ b/linden/indra/newview/llvowater.cpp @@ -101,7 +101,7 @@ void LLVOWater::setPixelAreaAndAngle(LLAgent &agent) // virtual -void LLVOWater::updateTextures(LLAgent &agent) +void LLVOWater::updateTextures() { } @@ -281,9 +281,9 @@ U32 LLVOVoidWater::getPartitionType() const } LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0, FALSE, 0) +: LLSpatialPartition(0) { - // mRenderByGroup = FALSE; // KL specified const SG branch not req here + mRenderByGroup = FALSE; mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; mPartitionType = LLViewerRegion::PARTITION_WATER; diff --git a/linden/indra/newview/llvowater.h b/linden/indra/newview/llvowater.h index de2cb3ec5..55ce6d789 100644 --- a/linden/indra/newview/llvowater.h +++ b/linden/indra/newview/llvowater.h @@ -69,7 +69,7 @@ class LLVOWater : public LLStaticViewerObject /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); - /*virtual*/ void updateTextures(LLAgent &agent); + /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area /*virtual*/ U32 getPartitionType() const; diff --git a/linden/indra/newview/llwaterparammanager.cpp b/linden/indra/newview/llwaterparammanager.cpp index 8ef11bea2..e01506e94 100644 --- a/linden/indra/newview/llwaterparammanager.cpp +++ b/linden/indra/newview/llwaterparammanager.cpp @@ -407,7 +407,8 @@ void LLWaterParamManager::update(LLViewerCamera * cam) LLFloaterWater::instance()->syncMenu(); } - //stop_glerror(); + stop_glerror(); + // only do this if we're dealing with shaders if(gPipeline.canUseVertexShaders()) { diff --git a/linden/indra/newview/llwlparammanager.cpp b/linden/indra/newview/llwlparammanager.cpp index 09f7d017e..31471d77c 100644 --- a/linden/indra/newview/llwlparammanager.cpp +++ b/linden/indra/newview/llwlparammanager.cpp @@ -539,7 +539,8 @@ void LLWLParamManager::update(LLViewerCamera * cam) F32 camYaw = cam->getYaw(); - //stop_glerror(); + stop_glerror(); + // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h index 62374d5e7..2c5815cde 100644 --- a/linden/indra/newview/llworld.h +++ b/linden/indra/newview/llworld.h @@ -2,7 +2,7 @@ * @file llworld.h * @brief Collection of viewer regions in the vacinity of the user. * - * Represents the whole world, so far as 3D functionality is concerned. + * Represents the whole world, so far as 3D functionality is conserned. * Always contains the region that the user's avatar is in along with * neighboring regions. As the user crosses region boundaries, new * regions are added to the world and distant ones are rolled up. @@ -152,8 +152,7 @@ class LLWorld : public LLSingleton<LLWorld> public: typedef std::list<LLViewerRegion*> region_list_t; - region_list_t mActiveRegionList; // KL SD branch public not private - region_list_t& getRegionList() { return mActiveRegionList; } + const region_list_t& getRegionList() const { return mActiveRegionList; } // Returns lists of avatar IDs and their world-space positions within a given distance of a point. // All arguments are optional. Given containers will be emptied and then filled. @@ -164,6 +163,7 @@ class LLWorld : public LLSingleton<LLWorld> const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX) const; private: + region_list_t mActiveRegionList; region_list_t mRegionList; region_list_t mVisibleRegionList; region_list_t mCulledRegionList; diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 53d7e4973..8dce5cf98 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -159,8 +159,6 @@ std::string gPoolNames[] = "POOL_ALPHA", }; -void drawBox(const LLVector3& c, const LLVector3& r); - U32 nhpo2(U32 v) { U32 r = 1; @@ -269,11 +267,11 @@ static const U32 gl_cube_face[] = void validate_framebuffer_object(); - void addDeferredAttachments(LLRenderTarget& target) { - target.addColorAttachment(GL_RGBA); //specular //target.addColorAttachment(GL_RGBA16F_ARB); //specular // KL - target.addColorAttachment(GL_RGBA); //normal+z //target.addColorAttachment(GL_RGBA16F_ARB); //normal+z + target.addColorAttachment(GL_RGBA16F_ARB); //specular + target.addColorAttachment(GL_RGBA16F_ARB); //normal+z + target.addColorAttachment(GL_RGBA16F_ARB); //position } LLPipeline::LLPipeline() : @@ -315,8 +313,6 @@ LLPipeline::LLPipeline() : mLightingDetail(0) { mNoiseMap = 0; - //mTrueNoiseMap = 0; // KL SD - mLightFunc = 0; // KL SD } void LLPipeline::init() @@ -366,11 +362,6 @@ void LLPipeline::init() LLViewerShaderMgr::instance()->setShaders(); stop_glerror(); - - for (U32 i = 0; i < 2; ++i) - { - mSpotLightFade[i] = 1.f; - } } LLPipeline::~LLPipeline() @@ -382,9 +373,6 @@ void LLPipeline::cleanup() { assertInitialized(); - mGroupQ1.clear() ; - mGroupQ2.clear() ; - for(pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ) { @@ -481,69 +469,33 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWindowDisplayWidth(); GLuint resY = gViewerWindow->getWindowDisplayHeight(); - allocateScreenBuffer(resX,resY); - } -} - -void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) -{ - - U32 samples = gSavedSettings.getU32("RenderFSAASamples"); U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); - if (res_mod > 1 && res_mod < resX && res_mod < resY) { resX /= res_mod; resY /= res_mod; } - if (gSavedSettings.getBOOL("RenderUIBuffer")) - { - //mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - } + allocateScreenBuffer(resX,resY); + + llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; + } +} +void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) +{ + U32 samples = gSavedSettings.getU32("RenderFSAASamples"); if (LLPipeline::sRenderDeferred) { //allocate deferred rendering color buffers - mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredScreen.allocate(resX, resY, GL_RGBA16F_ARB, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); addDeferredAttachments(mDeferredScreen); + mScreen.allocate(resX, resY, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - // always set viewport to desired size, since allocate resets the viewport - - mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - - for (U32 i = 0; i < 3; i++) - { - mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); - } - for (U32 i = 0; i < 2; i++) { - mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); - } - - F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); - - for (U32 i = 0; i < 4; i++) - { - mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); - } - - - U32 width = nhpo2(U32(resX*scale))/2; - U32 height = width; - - for (U32 i = 4; i < 6; i++) - { - mShadow[i].allocate(width, height, 0, TRUE, FALSE); + mDeferredLight[i].allocate(resX, resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); } - - - - width = nhpo2(resX)/2; - height = nhpo2(resY)/2; - mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); } else { @@ -553,23 +505,25 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (gGLManager.mHasFramebufferMultisample && samples > 1) { - mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); if (LLPipeline::sRenderDeferred) { + mSampleBuffer.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); addDeferredAttachments(mSampleBuffer); mDeferredScreen.setSampleBuffer(&mSampleBuffer); } + else + { + mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); + } mScreen.setSampleBuffer(&mSampleBuffer); - stop_glerror(); } - - if (LLPipeline::sRenderDeferred) + else if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); - for (U32 i = 0; i < 3; i++) - { //share stencil buffer with screen space lightmap to stencil out sky + for (U32 i = 0; i < 2; i++) + { mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); } } @@ -602,40 +556,17 @@ void LLPipeline::releaseGLBuffers() mNoiseMap = 0; } -/* if (mTrueNoiseMap) - { - LLImageGL::deleteTextures(1, &mTrueNoiseMap); - mTrueNoiseMap = 0; - } -*/ - if (mLightFunc) - { - LLImageGL::deleteTextures(1, &mLightFunc); - mLightFunc = 0; - } - mWaterRef.release(); mWaterDis.release(); mScreen.release(); mSampleBuffer.releaseSampleBuffer(); mDeferredScreen.release(); - mDeferredDepth.release(); - for (U32 i = 0; i < 3; i++) - { - mDeferredLight[i].release(); - } - - mGIMap.release(); - mGIMapPost[0].release(); - mGIMapPost[1].release(); - mHighlight.release(); -// mLuminanceMap.release(); - for (U32 i = 0; i < 6; i++) // KL 6 in SD + + for (U32 i = 0; i < 4; i++) { - mShadow[i].release(); + mSunShadow[i].release(); } - for (U32 i = 0; i < 3; i++) { mGlow[i].release(); @@ -658,13 +589,9 @@ void LLPipeline::createGLBuffers() mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE); } - mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); stop_glerror(); - GLuint resX = gViewerWindow->getWindowDisplayWidth(); - GLuint resY = gViewerWindow->getWindowDisplayHeight(); - if (LLPipeline::sRenderGlow) { //screen space glow buffers const U32 glow_res = llmax(1, @@ -674,13 +601,20 @@ void LLPipeline::createGLBuffers() { mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); } + } + GLuint resX = gViewerWindow->getWindowDisplayWidth(); + GLuint resY = gViewerWindow->getWindowDisplayHeight(); + allocateScreenBuffer(resX,resY); - } - if (sRenderDeferred) { + mSunShadow[0].allocate(1024,1024, 0, TRUE, FALSE); + mSunShadow[1].allocate(1024,1024, 0, TRUE, FALSE); + mSunShadow[2].allocate(1024,1024, 0, TRUE, FALSE); + mSunShadow[3].allocate(1024,1024, 0, TRUE, FALSE); + if (!mNoiseMap) { const U32 noiseRes = 128; @@ -700,83 +634,7 @@ void LLPipeline::createGLBuffers() LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - -/* if (!mTrueNoiseMap) - { - const U32 noiseRes = 128; - F32 noise[noiseRes*noiseRes*3]; - for (U32 i = 0; i < noiseRes*noiseRes*3; i++) - { - noise[i] = ll_frand()*2.0-1.0; } - - LLImageGL::generateTextures(1, &mTrueNoiseMap); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } -*/ - if (!mLightFunc) - { - U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); - U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); - U8* lg = new U8[lightResX*lightResY]; - - for (U32 y = 0; y < lightResY; ++y) - { - for (U32 x = 0; x < lightResX; ++x) - { - //spec func - F32 sa = (F32) x/(lightResX-1); - F32 spec = (F32) y/(lightResY-1); - //lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255); - - //F32 sp = acosf(sa)/(1.f-spec); - - sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent")); - F32 a = acosf(sa*0.25f+0.75f); - F32 m = llmax(0.5f-spec*0.5f, 0.001f); - F32 t2 = tanf(a)/m; - t2 *= t2; - - F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f; - F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2); - - lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255); - } - } - - LLImageGL::generateTextures(1, &mLightFunc); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_ALPHA, lightResX, lightResY, GL_ALPHA, GL_UNSIGNED_BYTE, lg); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - - delete [] lg; -/* } - - if (gSavedSettings.getBOOL("RenderDeferredGI")) - { */ - mGIMap.allocate(1024,1024,GL_RGBA, TRUE, FALSE); - addDeferredAttachments(mGIMap); - - { - LLGLDepthTest depth(GL_TRUE); - gGL.setColorMask(true, true); - for (U32 i = 0; i < 2; i++) - { - mGIMapPost[i].allocate(128,128,GL_RGB16F_ARB, FALSE, FALSE); - mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); - mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); - mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); - - mGIMapPost[i].bindTarget(); - mGIMapPost[i].clear(); - mGIMapPost[i].flush(); - } - } - } - } //mLuminanceMap.allocate(128,128, GL_RGBA, FALSE, FALSE); } void LLPipeline::restoreGL() @@ -788,7 +646,7 @@ void LLPipeline::restoreGL() LLViewerShaderMgr::instance()->setShaders(); } - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -842,7 +700,7 @@ void LLPipeline::unloadShaders() void LLPipeline::assertInitializedDoError() { - llwarns << "LLPipeline used when uninitialized." << llendl; + llerrs << "LLPipeline used when uninitialized." << llendl; } //============================================================================ @@ -905,7 +763,7 @@ class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable> for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { LLDrawInfo* params = *j; - if (mTextures.find(params->mViewerTexture) != mTextures.end()) + if (mTextures.find(params->mTexture) != mTextures.end()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } @@ -939,7 +797,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& texture } LLOctreeDirtyTexture dirty(textures); - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1018,7 +876,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) default: llassert(0); - llwarns << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; + llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; break; } @@ -1133,7 +991,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) #ifdef LL_RELEASE_FOR_DOWNLOAD llwarns << "Couldn't remove object from spatial group!" << llendl; #else - llwarns << "Couldn't remove object from spatial group!" << llendl; + llerrs << "Couldn't remove object from spatial group!" << llendl; #endif } } @@ -1148,31 +1006,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) break; } } - - { - HighlightItem item(drawablep); - mHighlightSet.erase(item); - - if (mHighlightObject == drawablep) - { - mHighlightObject = NULL; - } - } - - for (U32 i = 0; i < 2; ++i) - { - if (mShadowSpotLight[i] == drawablep) - { - mShadowSpotLight[i] = NULL; - } - - if (mTargetShadowSpotLight[i] == drawablep) - { - mTargetShadowSpotLight[i] = NULL; - } - } - - } U32 LLPipeline::addObject(LLViewerObject *vobj) @@ -1229,7 +1062,7 @@ void LLPipeline::createObject(LLViewerObject* vobj) } else { - llwarns << "Redundant drawable creation!" << llendl; + llerrs << "Redundant drawable creation!" << llendl; } llassert(drawablep); @@ -1293,7 +1126,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) } if (!drawablep) { - llwarns << "updateMove called with NULL drawablep" << llendl; + llerrs << "updateMove called with NULL drawablep" << llendl; return; } if (drawablep->isState(LLDrawable::EARLY_MOVE)) @@ -1324,8 +1157,7 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) } if (!drawablep) { - llwarns << "updateMove called with NULL drawablep" << llendl; - return; + llerrs << "updateMove called with NULL drawablep" << llendl; } if (drawablep->isState(LLDrawable::EARLY_MOVE)) { @@ -1418,7 +1250,7 @@ void LLPipeline::updateMove() { LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1445,6 +1277,7 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera F32 dist = lookAt.length(); //ramp down distance for nearby objects + //shrink dist by dist/16. if (dist < 16.f) { dist /= 16.f; @@ -1465,7 +1298,7 @@ void LLPipeline::grabReferences(LLCullResult& result) BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1497,7 +1330,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& BOOL res = TRUE; - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1560,7 +1393,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1637,7 +1470,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) group->setVisible(); - if (!sSkipUpdate) // && !sShadowRender) KL? + if (!sSkipUpdate) { group->updateDistance(camera); } @@ -1728,78 +1561,6 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) return update_complete; } -void LLPipeline::updateGL() // KL SD -{ - while (!LLGLUpdate::sGLQ.empty()) - { - LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); - glu->updateGL(); - glu->mInQ = FALSE; - LLGLUpdate::sGLQ.pop_front(); - } -} // KL updateGL SD - -void LLPipeline::rebuildPriorityGroups() -{ - LLTimer update_timer; - LLMemType mt(LLMemType::MTYPE_PIPELINE); - - assertInitialized(); - - // Iterate through all drawables on the priority build queue, - for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); - iter != mGroupQ1.end(); ++iter) - { - LLSpatialGroup* group = *iter; - group->rebuildGeom(); - group->clearState(LLSpatialGroup::IN_BUILD_Q1); - } - - mGroupQ1.clear(); -} - -void LLPipeline::rebuildGroups() -{ - // Iterate through some drawables on the non-priority build queue - S32 size = (S32) mGroupQ2.size(); - S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); - - S32 count = 0; - - std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); // KL - - LLSpatialGroup::sg_vector_t::iterator iter; - for (iter = mGroupQ2.begin(); - iter != mGroupQ2.end(); ++iter) - { - LLSpatialGroup* group = *iter; - - if (group->isDead()) - { - continue; - } - - group->rebuildGeom(); - - if (group->mSpatialPartition->mRenderByGroup) - { - count++; - } - - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - - if (count > min_count) - { - ++iter; - break; - } - } - - mGroupQ2.erase(mGroupQ2.begin(), iter); - - updateMovedList(mMovedBridge); -} - void LLPipeline::updateGeom(F32 max_dtime) { LLTimer update_timer; @@ -1914,16 +1675,6 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) if (drawablep->isSpatialBridge()) { - LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; - - if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment()) - { - LLVOAvatar* av = root->getParent()->getVObj()->asAvatar(); - if (av->isImpostor()) - { - return; - } - } sCull->pushBridge((LLSpatialBridge*) drawablep); } else @@ -1940,7 +1691,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) if (!drawablep) { - //llwarns << "Sending null drawable to moved list!" << llendl; + //llerrs << "Sending null drawable to moved list!" << llendl; return; } @@ -2025,7 +1776,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) } mShiftList.resize(0); - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -2053,54 +1804,6 @@ void LLPipeline::markTextured(LLDrawable *drawablep) } } -void LLPipeline::markGLRebuild(LLGLUpdate* glu) -{ - if (glu && !glu->mInQ) - { - LLGLUpdate::sGLQ.push_back(glu); - glu->mInQ = TRUE; - } -} - -void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) -{ - LLMemType mt(LLMemType::MTYPE_PIPELINE); - //assert_main_thread(); - - if (group && !group->isDead() && group->mSpatialPartition) - { - if (priority) - { - if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) - { - mGroupQ1.push_back(group); - group->setState(LLSpatialGroup::IN_BUILD_Q1); - - if (group->isState(LLSpatialGroup::IN_BUILD_Q2)) - { - LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); - if (iter != mGroupQ2.end()) - { - mGroupQ2.erase(iter); - } - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - } - } - } - else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) - { - //llwarns << "Non-priority updates not yet supported!" << llendl; - if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) - { - llwarns << "WTF?" << llendl; - } - mGroupQ2.push_back(group); - group->setState(LLSpatialGroup::IN_BUILD_Q2); - - } - } -} - void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -2156,13 +1859,12 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) grabReferences(result); - //if (!LLPipeline::sShadowRender) { for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); - if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED)) + if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) { markOccluder(group); } @@ -2175,15 +1877,12 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } - } - if (!LLPipeline::sShadowRender) - { for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); - if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED)) + if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) { markOccluder(group); } @@ -2195,7 +1894,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - if (!LLPipeline::sShadowRender) { for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { @@ -2247,7 +1945,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (!sSkipUpdate && !sShadowRender && bridge->getSpatialGroup()->changeLOD()) + if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2309,8 +2007,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - if (!sShadowRender) - { LLSpatialGroup* group = drawablep->getSpatialGroup(); if (!group || group->changeLOD()) { @@ -2318,18 +2014,17 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) { if (!drawablep->isActive()) { - drawablep->updateDistance(camera, TRUE); + bool force_update = false; + drawablep->updateDistance(camera, force_update); } else if (drawablep->isAvatar()) { - drawablep->updateDistance(camera, TRUE); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() + bool force_update = false; + drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() } } } - } - if (!drawablep->getVOVolume()) - { for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); iter != drawablep->mFaces.end(); iter++) { @@ -2347,8 +2042,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } } - } - mNumVisibleFaces += drawablep->getNumFaces(); } @@ -2514,7 +2207,7 @@ void LLPipeline::postSort(LLCamera& camera) //rebuild groups sCull->assertDrawMapsEmpty(); - /*LLSpatialGroup::sNoDelete = FALSE; + LLSpatialGroup::sNoDelete = FALSE; for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; @@ -2526,11 +2219,9 @@ void LLPipeline::postSort(LLCamera& camera) group->rebuildGeom(); } - LLSpatialGroup::sNoDelete = TRUE;*/ + LLSpatialGroup::sNoDelete = TRUE; - rebuildPriorityGroups(); - const S32 bin_count = 1024*8; static LLCullResult::drawinfo_list_t alpha_bins[bin_count]; @@ -2555,28 +2246,17 @@ void LLPipeline::postSort(LLCamera& camera) { continue; } - - if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY)) - { //no way this group is going to be drawable without a rebuild - group->rebuildGeom(); - } - + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) { LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - if (!hasRenderType(j->first)) - { - continue; - } - + for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) { sCull->pushDrawInfo(j->first, *k); } } - if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) - { LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); if (alpha != group->mDrawMap.end()) @@ -2601,7 +2281,6 @@ void LLPipeline::postSort(LLCamera& camera) } } } - } if (!sShadowRender) { @@ -2699,7 +2378,7 @@ void LLPipeline::postSort(LLCamera& camera) } } - //LLSpatialGroup::sNoDelete = FALSE; + LLSpatialGroup::sNoDelete = FALSE; } @@ -2760,103 +2439,6 @@ void LLPipeline::renderHighlights() LLGLEnable color_mat(GL_COLOR_MATERIAL); disableLights(); - if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && !mHighlightSet.empty()) - { //draw blurry highlight image over screen - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - LLGLDisable test(GL_ALPHA_TEST); - - LLGLEnable stencil(GL_STENCIL_TEST); - gGL.flush(); - glStencilMask(0xFFFFFFFF); - glClearStencil(1); - glClear(GL_STENCIL_BUFFER_BIT); - - glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - - gGL.setColorMask(false, false); - for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter) - { - renderHighlight(iter->mItem->getVObj(), 1.f); - } - gGL.setColorMask(true, false); - - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); - - //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - - gGL.pushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - gGL.pushMatrix(); - glLoadIdentity(); - - gGL.getTexUnit(0)->bind(&mHighlight); - - LLVector2 tc1; - LLVector2 tc2; - - tc1.setVec(0,0); - tc2.setVec(2,2); - - gGL.begin(LLRender::TRIANGLES); - - F32 scale = gSavedSettings.getF32("RenderHighlightBrightness"); - LLColor4 color = gSavedSettings.getColor4("RenderHighlightColor"); - F32 thickness = gSavedSettings.getF32("RenderHighlightThickness"); - - for (S32 pass = 0; pass < 2; ++pass) - { - if (pass == 0) - { - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - } - else - { - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - - for (S32 i = 0; i < 8; ++i) - { - for (S32 j = 0; j < 8; ++j) - { - LLVector2 tc(i-4+0.5f, j-4+0.5f); - - F32 dist = 1.f-(tc.length()/sqrtf(32.f)); - dist *= scale/64.f; - - tc *= thickness; - tc.mV[0] = (tc.mV[0])/mHighlight.getWidth(); - tc.mV[1] = (tc.mV[1])/mHighlight.getHeight(); - - gGL.color4f(color.mV[0], - color.mV[1], - color.mV[2], - color.mV[3]*dist); - - gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc.mV[0]+tc2.mV[0], tc.mV[1]+tc1.mV[1]); - gGL.vertex2f(3,-1); - } - } - } - - gGL.end(); - - gGL.popMatrix(); - glMatrixMode(GL_MODELVIEW); - gGL.popMatrix(); - - //gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) { gHighlightProgram.bind(); @@ -2879,7 +2461,7 @@ void LLPipeline::renderHighlights() LLFace *facep = mSelectedFaces[i]; if (!facep || facep->getDrawable()->isDead()) { - llwarns << "Bad face on selection" << llendl; + llerrs << "Bad face on selection" << llendl; return; } @@ -2952,7 +2534,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { if (!verify()) { - llwarns << "Pipeline verification failed!" << llendl; + llerrs << "Pipeline verification failed!" << llendl; } } @@ -3001,9 +2583,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) stop_glerror(); LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDeferred"); - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { LLDrawPool *poolp = *iter; @@ -3015,6 +2594,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) { + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect()); } else @@ -3078,8 +2658,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); if (depth > 3) { - - llwarns << "GL matrix stack corrupted!" << llendl; + llerrs << "GL matrix stack corrupted!" << llendl; } std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); LLGLState::checkStates(msg); @@ -3150,13 +2729,21 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLVertexBuffer::unbind(); - if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) { + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { // Render debugging beacons. gObjectList.renderObjectBeacons(); LLHUDObject::renderAll(); gObjectList.resetObjectBeacons(); } + else + { + // Make sure particle effects disappear + LLHUDObject::renderAllForTimer(); + } + } LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); @@ -3179,6 +2766,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) void LLPipeline::renderGeomDeferred(LLCamera& camera) { + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); LLFastTimer t2(LLFastTimer::FTM_POOLS); @@ -3245,20 +2833,17 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) poolp->endDeferredPass(i); LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) - { GLint depth; glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); if (depth > 3) { - llwarns << "GL matrix stack corrupted!" << llendl; + llerrs << "GL matrix stack corrupted!" << llendl; } LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); } } - } else { // Skip all pools of this type @@ -3338,20 +2923,17 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) poolp->endPostDeferredPass(i); LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) - { GLint depth; glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); if (depth > 3) { - llwarns << "GL matrix stack corrupted!" << llendl; + llerrs << "GL matrix stack corrupted!" << llendl; } LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); } } - } else { // Skip all pools of this type @@ -3385,6 +2967,11 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLHUDObject::renderAll(); gObjectList.resetObjectBeacons(); } + else + { + // Make sure particle effects disappear + LLHUDObject::renderAllForTimer(); + } if (occlude) { @@ -3488,7 +3075,7 @@ void LLPipeline::renderDebug() gGL.setColorMask(true, false); // Debug stuff. - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -3505,7 +3092,7 @@ void LLPipeline::renderDebug() } } - for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) @@ -3519,91 +3106,96 @@ void LLPipeline::renderDebug() if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { - LLGLEnable blend(GL_BLEND); // kl sd - LLGLDepthTest depth(TRUE, FALSE); - LLGLDisable cull(GL_CULL_FACE); // kl - gGL.color4f(1,1,1,1); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - F32 a = 0.1f; - F32 col[] = { - 1,0,0,a, - 0,1,0,a, - 0,0,1,a, - 1,0,1,a, - - 1,1,0,a, - 0,1,1,a, - 1,1,1,a, - 1,0,1,a, + 1,1,0, + 0,1,1, + 1,0,1, + 1,1,1, + 1,0,0, + 0,1,0, + 0,0,1, + 0,0,0 }; for (U32 i = 0; i < 8; i++) { - if (i > 3) - { - gGL.color4fv(col+(i-4)*4); - + gGL.color3fv(col+i*3); + + gGL.begin(LLRender::LINES); + LLVector3* frust = mShadowCamera[i].mAgentFrustum; - gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); + + gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.end(); + if (i < 4) + { + LLVector3* ext = mShadowExtents[i]; - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[0].mV); - gGL.vertex3fv(frust[1].mV); - gGL.vertex3fv(frust[3].mV); - gGL.vertex3fv(frust[2].mV); - gGL.end(); + LLVector3 box[] = + { + LLVector3(ext[0][0], ext[0][1], ext[0][2]), + LLVector3(ext[1][0], ext[0][1], ext[0][2]), + LLVector3(ext[1][0], ext[1][1], ext[0][2]), + LLVector3(ext[0][0], ext[1][1], ext[0][2]), + LLVector3(ext[0][0], ext[0][1], ext[1][2]), + LLVector3(ext[1][0], ext[0][1], ext[1][2]), + LLVector3(ext[1][0], ext[1][1], ext[1][2]), + LLVector3(ext[0][0], ext[1][1], ext[1][2]), + }; - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[6].mV); - gGL.end(); + gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[1].mV); + gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[2].mV); + gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[3].mV); + gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[0].mV); + + gGL.vertex3fv(box[4].mV); gGL.vertex3fv(box[5].mV); + gGL.vertex3fv(box[5].mV); gGL.vertex3fv(box[6].mV); + gGL.vertex3fv(box[6].mV); gGL.vertex3fv(box[7].mV); + gGL.vertex3fv(box[7].mV); gGL.vertex3fv(box[4].mV); + + gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[4].mV); + gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[5].mV); + gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[6].mV); + gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[7].mV); } + gGL.end(); - if (i < 4) + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { - gGL.begin(LLRender::LINES); - - F32* c = col+i*4; - for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) + LLViewerRegion* region = *iter; + for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) { - - gGL.color3fv(c); - - for (U32 k = 0; k < mShadowFrustPoints[i].size(); ++k) + LLSpatialPartition* part = region->getSpatialPartition(j); + if (part) { - if (j != k) + if (hasRenderType(part->mDrawableType)) { - gGL.vertex3fv(mShadowFrustPoints[i][j].mV); - gGL.vertex3fv(mShadowFrustPoints[i][k].mV); + part->renderIntersectingBBoxes(&mShadowCamera[i]); } } - - if (!mShadowFrustOrigin[i].isExactlyZero()) - { - gGL.vertex3fv(mShadowFrustPoints[i][j].mV); - gGL.color4f(1,1,1,1); - gGL.vertex3fv(mShadowFrustOrigin[i].mV); } } - gGL.end(); } } - } if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) { @@ -3638,55 +3230,6 @@ void LLPipeline::renderDebug() } } - if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) - { - U32 count = 0; - U32 size = mBuildQ2.size(); - LLColor4 col; - - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep); - - for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) - { - LLSpatialGroup* group = *iter; - if (group->isDead()) - { - continue; - } - - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); - - if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead())) - { - continue; - } - - if (bridge) - { - gGL.pushMatrix(); - glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); - } - - F32 alpha = (F32) (size-count)/size; - - - LLVector2 c(1.f-alpha, alpha); - c.normVec(); - - - ++count; - col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f); - group->drawObjectBox(col); - - if (bridge) - { - gGL.popMatrix(); - } - } - } - gGL.flush(); } @@ -5120,7 +4663,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -5177,7 +4720,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, //check against avatars sPickAvatar = TRUE; - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -5254,7 +4797,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co { LLDrawable* drawable = NULL; - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -5317,7 +4860,7 @@ void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -5428,18 +4971,18 @@ void validate_framebuffer_object() break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: // frame buffer not OK: probably means unsupported depth buffer format - llwarns << "Framebuffer Incomplete Dimensions." << llendl; + llerrs << "Framebuffer Incomplete Dimensions." << llendl; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: // frame buffer not OK: probably means unsupported depth buffer format - llwarns << "Framebuffer Incomplete Attachment." << llendl; + llerrs << "Framebuffer Incomplete Attachment." << llendl; break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: /* choose different formats */ - llwarns << "Framebuffer unsupported." << llendl; + llerrs << "Framebuffer unsupported." << llendl; break; default: - llwarns << "Unknown framebuffer status." << llendl; + llerrs << "Unknown framebuffer status." << llendl; break; } } @@ -5757,202 +5300,46 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post) //, U32 noise_map) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) { -/* if (noise_map == 0xFFFFFFFF) - { - noise_map = mNoiseMap; - } -*/ - LLFastTimer ftm(LLFastTimer::FTM_TEMP3); - LLGLState::checkTextureChannels(); - shader.bind(); S32 channel = 0; channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(0,channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(2, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - if (gi_source) - { - BOOL has_gi = FALSE; - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { - has_gi = TRUE; - gi_source->bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(2, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(3, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(2, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(3, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); - if (channel > -1) - { - has_gi = TRUE; - gGL.getTexUnit(channel)->bind(gi_source, TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - stop_glerror(); - - glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); - - stop_glerror(); - } - - if (has_gi) - { - U32 gi_samples = llclamp(gSavedSettings.getU32("RenderGISamples"), (U32) 1, (U32) 8); - - F32 range_x = llmin(mGIRange.mV[0], 1.f); - F32 range_y = llmin(mGIRange.mV[1], 1.f); - - LLVector2 scale(range_x,range_y); - - LLVector2 kern[25]; - - for (S32 i = 0; i < 5; ++i) - { - for (S32 j = 0; j < 5; ++j) - { - S32 idx = i*5+j; - kern[idx].mV[0] = (i-2)*0.5f; - kern[idx].mV[1] = (j-2)*0.5f; - kern[idx].scaleVec(scale); - } - } - - F32 gi_radius = mGILightRadius; //gSavedSettings.getF32("RenderGILightRadius"); - - shader.uniform2f("gi_scale", scale.mV[0], scale.mV[1]); - shader.uniform2fv("gi_kern", 25, (F32*) kern); - shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m); - shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m); - shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m); - shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m); - shader.uniform1f("gi_radius", gi_radius); - shader.uniform1i("gi_samples", (GLint) gSavedSettings.getU32("RenderGISamples")); - shader.uniform1f("gi_intensity", gSavedSettings.getF32("RenderGIIntensity")/(gi_samples*gi_samples)); - shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV); - shader.uniform3fv("gi_spec", 1, gSavedSettings.getVector3("RenderGISpecularCurve").mV); - shader.uniform1f("gi_direction_weight", gSavedSettings.getF32("RenderGIDirectionWeight")); - shader.uniform1f("gi_light_offset", gSavedSettings.getF32("RenderGILightOffset")); - shader.uniform1f("gi_blend", gFrameIntervalSeconds); - } + mDeferredScreen.bindTexture(3, channel); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { - gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - stop_glerror(); - - glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); - - stop_glerror(); - - glh::matrix4f projection = glh_get_current_projection(); - glh::matrix4f inv_proj = projection.inverse(); - - shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m); - shader.uniform4f("viewport", (F32) gGLViewport[0], - (F32) gGLViewport[1], - (F32) gGLViewport[2], - (F32) gGLViewport[3]); + gGL.getTexUnit(channel)->bind(&mDeferredScreen, TRUE); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE); if (channel > -1) { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); // was noise_map KL - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); - if (channel > -1) - { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); } stop_glerror(); @@ -5961,68 +5348,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen if (channel > -1) { mDeferredLight[light_index].bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); - if (channel > -1) - { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - gi_source->bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - mDeferredLight[1].bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - mDeferredLight[2].bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - stop_glerror(); for (U32 i = 0; i < 4; i++) - { - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); - stop_glerror(); - if (channel > -1) - { - stop_glerror(); - gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - stop_glerror(); - - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); - stop_glerror(); - } - } - - for (U32 i = 4; i < 6; i++) { channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i); stop_glerror(); if (channel > -1) { stop_glerror(); - gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); + gGL.getTexUnit(channel)->bind(&mSunShadow[i], TRUE); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); @@ -6033,19 +5371,17 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen stop_glerror(); - F32 mat[16*6]; + F32 mat[64]; for (U32 i = 0; i < 16; i++) { mat[i] = mSunShadowMatrix[0].m[i]; mat[i+16] = mSunShadowMatrix[1].m[i]; mat[i+32] = mSunShadowMatrix[2].m[i]; mat[i+48] = mSunShadowMatrix[3].m[i]; - mat[i+64] = mSunShadowMatrix[4].m[i]; - mat[i+80] = mSunShadowMatrix[5].m[i]; } - shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat); - shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix[0]", 4, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix", 4, FALSE, mat); stop_glerror(); @@ -6094,23 +5430,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften")); - shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")); - shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")); -/* shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV); - shader.uniform3fv("lum_quad", 1, gSavedSettings.getVector3("RenderLuminanceColorCurve").mV); - shader.uniform3fv("gi_lum_quad", 1, gSavedSettings.getVector3("RenderGILuminanceColorCurve").mV); - shader.uniform3fv("sun_lum_quad", 1, gSavedSettings.getVector3("RenderSunLuminanceColorCurve").mV); - shader.uniform1f("lum_lod", gSavedSettings.getF32("RenderLuminanceDetail")); - shader.uniform1f("gi_range", gSavedSettings.getF32("RenderGIRange")); - - if (shader.getUniformLocation("norm_mat") >= 0) - { - glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); - shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m); - } */ } -// KL The Deffered Pipeline begins here! void LLPipeline::renderDeferredLighting() { if (!sCull) @@ -6118,12 +5439,6 @@ void LLPipeline::renderDeferredLighting() return; } - { - LLGLDepthTest depth(GL_TRUE); - mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -6137,10 +5452,16 @@ void LLPipeline::renderDeferredLighting() glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); gGL.setColorMask(true, true); + + mDeferredLight[0].bindTarget(); + + //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), + // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); //draw a cube around every light LLVertexBuffer::unbind(); + glBlendFunc(GL_ONE, GL_ONE); LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); @@ -6152,34 +5473,8 @@ void LLPipeline::renderDeferredLighting() -1,-3, 3,1, }; - glVertexPointer(2, GL_FLOAT, 0, vert); - glColor3f(1,1,1); - //Set mSunDir KL This makes sense to have it here. Still calculated EVEN if Deferred Sun is FALSE! - { - setupHWLights(NULL); //to set mSunDir; - LLVector4 dir(mSunDir, 0.f); - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); - } - - if (gSavedSettings.getBOOL("RenderDeferredShadow")) - { - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - mDeferredLight[0].bindTarget(); -// KL Bind to 0 next section Deferred Sun ! - if (gSavedSettings.getBOOL("RenderDeferredSun")) - { //paint shadow/SSAO light map (direct lighting lightmap) - bindDeferredShader(gDeferredSunProgram, 0); - - glClearColor(1,1,1,1); - mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); + bindDeferredShader(gDeferredSunProgram); glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); @@ -6202,115 +5497,24 @@ void LLPipeline::renderDeferredLighting() gDeferredSunProgram.uniform3fv("offset", slice, offset); gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - unbindDeferredShader(gDeferredSunProgram); - } - else - { - mDeferredLight[0].clear(); - } - - mDeferredLight[0].flush(); - mDeferredLight[1].bindTarget(); - } -// KL Bind to 1 next section GI -/* if (gSavedSettings.getBOOL("RenderDeferredGI")) - { - { //get luminance map from previous frame's light map - LLGLEnable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable stencil(GL_STENCIL_TEST); - - //static F32 fade = 1.f; - - F32 fade = gSavedSettings.getF32("RenderLuminanceFade"); - { - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gLuminanceGatherProgram.bind(); - gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); - gLuminanceGatherProgram.uniform1f("fade", llclamp(fade, 0.f, 1.f)); - mLuminanceMap.bindTarget(); - gGL.getTexUnit(0)->bind(&mDeferredLight[0]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - gLuminanceGatherProgram.unbind(); - mLuminanceMap.flush(); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - glGenerateMipmapEXT(GL_TEXTURE_2D); - } - } - - { //paint noisy GI map (bounce lighting lightmap) - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable test(GL_ALPHA_TEST); + setupHWLights(NULL); //to set mSunDir; - mGIMapPost[0].bindTarget(); - - bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0);//, mTrueNoiseMap); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - unbindDeferredShader(gDeferredGIProgram); - mGIMapPost[0].flush(); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + LLVector4 dir(mSunDir, 0.f); - } + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); + glColor3f(1,1,1); - U32 pass_count = 0; - if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) + glVertexPointer(2, GL_FLOAT, 0, vert); { - pass_count = llclamp(gSavedSettings.getU32("RenderGIBlurPasses"), (U32) 1, (U32) 128); - } - - for (U32 i = 0; i < pass_count; ++i) - { //gather/soften indirect lighting map - bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL); //, mTrueNoiseMap); - - LLVector2 gauss[32]; // xweight, yweight, offset - - F32 sc = 1.f; - - F32 go = gSavedSettings.getF32("RenderGIGaussian"); - U32 kern_length = llclamp(gSavedSettings.getU32("RenderGIBlurSamples"), (U32) 1, (U32) 16)*2 - 1; - F32 blur_size = gSavedSettings.getF32("RenderGIBlurSize")*sc; - F32 dist_factor = gSavedSettings.getF32("RenderGIBlurDistFactor"); - - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = -(kern_length/2.0f) + 0.5f; - - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go); - gauss[i].mV[1] = x; - x += 1.f; - } - // swap the x=0 position to the start of gauss[] so we can - // treat it specially as an optimization. - LLVector2 swap; - swap = gauss[kern_length/2]; - gauss[kern_length/2] = gauss[0]; - gauss[0] = swap; - llassert(gauss[0].mV[2] == 0.0f); - - gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f); - gDeferredPostGIProgram.uniform1f("dist_factor", dist_factor); - gDeferredPostGIProgram.uniform2fv("kern[0]", kern_length, gauss[0].mV); - gDeferredPostGIProgram.uniform2fv("kern", kern_length, gauss[0].mV); - gDeferredPostGIProgram.uniform1i("kern_length", kern_length); - gDeferredPostGIProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - gDeferredPostGIProgram.uniform3fv("blur_quad", 1, gSavedSettings.getVector3("RenderGIBlurColorCurve").mV); - - mGIMapPost[1].bindTarget(); - { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_FALSE); stop_glerror(); @@ -6318,39 +5522,15 @@ void LLPipeline::renderDeferredLighting() stop_glerror(); } - mGIMapPost[1].flush(); - unbindDeferredShader(gDeferredPostGIProgram); - - bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL);//, mTrueNoiseMap); - mGIMapPost[0].bindTarget(); + unbindDeferredShader(gDeferredSunProgram); - gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - stop_glerror(); - } - mGIMapPost[0].flush(); - unbindDeferredShader(gDeferredPostGIProgram); - } - } */ + mDeferredLight[0].flush(); - if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) - { //soften direct lighting lightmap //blur lightmap mDeferredLight[1].bindTarget(); - glClearColor(1,1,1,1); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); + //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), + // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); bindDeferredShader(gDeferredBlurLightProgram); @@ -6359,7 +5539,6 @@ void LLPipeline::renderDeferredLighting() LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); - F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); // sample symmetrically with the middle sample falling exactly on 0.0 F32 x = -(kern_length/2.0f) + 0.5f; @@ -6380,12 +5559,11 @@ void LLPipeline::renderDeferredLighting() llassert(gauss[0].mV[2] == 0.0f); gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - + { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_FALSE); @@ -6401,7 +5579,6 @@ void LLPipeline::renderDeferredLighting() mDeferredLight[0].bindTarget(); gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); @@ -6411,12 +5588,11 @@ void LLPipeline::renderDeferredLighting() LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_FALSE); stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); // KL 4? + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); stop_glerror(); } mDeferredLight[0].flush(); unbindDeferredShader(gDeferredBlurLightProgram); - } stop_glerror(); glPopMatrix(); @@ -6425,26 +5601,15 @@ void LLPipeline::renderDeferredLighting() stop_glerror(); glPopMatrix(); stop_glerror(); -// } //copy depth and stencil from deferred screen //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); -/* if (gSavedSettings.getBOOL("RenderDeferredGI")) - { - mDeferredLight[1].bindTarget(); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); - } - else - { */ mScreen.bindTarget(); mScreen.clear(GL_COLOR_BUFFER_BIT); -// } - - if (gSavedSettings.getBOOL("RenderDeferredAtmospheric")) - { //apply sunlight contribution - bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]); // may not be using GI but still need this KL + + bindDeferredShader(gDeferredSoftenProgram); { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -6467,56 +5632,15 @@ void LLPipeline::renderDeferredLighting() } unbindDeferredShader(gDeferredSoftenProgram); - } -// KL this code is a tad buggered atm it obliterates local lights...... -/* { //render sky/water/hair/skirts - LLGLDisable blend(GL_BLEND); - LLGLDisable stencil(GL_STENCIL_TEST); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - U32 render_mask = mRenderTypeMask; - mRenderTypeMask = mRenderTypeMask & - ((1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_CLOUDS) | - (1 << LLPipeline::RENDER_TYPE_WL_SKY) | - (1 << LLPipeline::RENDER_TYPE_AVATAR) | - (1 << LLPipeline::RENDER_TYPE_WATER)); - - renderGeomPostDeferred(*LLViewerCamera::getInstance()); - mRenderTypeMask = render_mask; - } */ + bindDeferredShader(gDeferredLightProgram); - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); - BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights"); - -/* - if (gSavedSettings.getBOOL("RenderDeferredGI")) - { - mDeferredLight[1].flush(); - mDeferredLight[2].bindTarget(); - mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT); - } -*/ - if (render_local || render_fullscreen) - { - gGL.setSceneBlendType(LLRender::BT_ADD); std::list<LLVector4> fullscreen_lights; - LLDrawable::drawable_list_t spot_lights; - LLDrawable::drawable_list_t fullscreen_spot_lights; - - for (U32 i = 0; i < 2; i++) - { - mTargetShadowSpotLight[i] = NULL; - } - std::list<LLVector4> light_colors; F32 v[24]; glVertexPointer(3, GL_FLOAT, 0, v); - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); - { - bindDeferredShader(gDeferredLightProgram); LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { @@ -6532,29 +5656,18 @@ void LLPipeline::renderDeferredLighting() F32* c = center.mV; F32 s = volume->getLightRadius()*1.5f; - LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - - if (col.magVecSquared() < 0.001f) - { - continue; - } - - if (s <= 0.001f) - { - continue; - } - if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) { continue; } sVisibleLightCount++; - glh::vec3f tc(c); mat.mult_matrix_vec(tc); + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + //vertex positions are encoded so the 3 bits of their vertex index //correspond to their axis facing, with bit position 3,2,1 matching //axis facing x,y,z, bit set meaning positive facing, bit clear @@ -6576,90 +5689,24 @@ void LLPipeline::renderDeferredLighting() LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) { //draw box if camera is outside box - if (render_local) - { - if (volume->getLightTexture()) - { - drawablep->getVOVolume()->updateSpotLightPriority(); - spot_lights.push_back(drawablep); - continue; - } - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); } - } - else if (render_fullscreen) + else { - if (volume->getLightTexture()) - { - drawablep->getVOVolume()->updateSpotLightPriority(); - fullscreen_spot_lights.push_back(drawablep); - continue; - } - fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); } } - unbindDeferredShader(gDeferredLightProgram); } - if (!spot_lights.empty()) - { - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - bindDeferredShader(gDeferredSpotLightProgram); - - gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredLightProgram); - for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) + if (!fullscreen_lights.empty()) { - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); - - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; - F32 s = volume->getLightRadius()*1.5f; - - sVisibleLightCount++; - - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - setupSpotLight(gDeferredSpotLightProgram, drawablep); - - LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - - //vertex positions are encoded so the 3 bits of their vertex index - //correspond to their axis facing, with bit position 3,2,1 matching - //axis facing x,y,z, bit set meaning positive facing, bit clear - //meaning negative facing - v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 - v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 - v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 - v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 - - v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 - v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 - v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 - v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); - glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); - } - gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); - unbindDeferredShader(gDeferredSpotLightProgram); - } - - { bindDeferredShader(gDeferredMultiLightProgram); - LLGLDepthTest depth(GL_FALSE); //full screen blit @@ -6671,14 +5718,11 @@ void LLPipeline::renderDeferredLighting() U32 count = 0; - const U32 max_count = 8; // KL poss 16? - LLVector4 light[max_count]; - LLVector4 col[max_count]; + LLVector4 light[16]; + LLVector4 col[16]; glVertexPointer(2, GL_FLOAT, 0, vert); - F32 far_z = 0.f; - while (!fullscreen_lights.empty()) { light[count] = fullscreen_lights.front(); @@ -6686,111 +5730,32 @@ void LLPipeline::renderDeferredLighting() col[count] = light_colors.front(); light_colors.pop_front(); - far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z); - count++; - if (count == max_count || fullscreen_lights.empty()) + if (count == 16 || fullscreen_lights.empty()) { gDeferredMultiLightProgram.uniform1i("light_count", count); gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); - gDeferredMultiLightProgram.uniform1f("far_z", far_z); - far_z = 0.f; count = 0; glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); } } - unbindDeferredShader(gDeferredMultiLightProgram); - - bindDeferredShader(gDeferredMultiSpotLightProgram); - - gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); - - for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) - { - LLDrawable* drawablep = *iter; - LLVOVolume* volume = drawablep->getVOVolume(); - - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; - F32 s = volume->getLightRadius()*1.5f; - - sVisibleLightCount++; - - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); - - LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); - glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - } - - gDeferredMultiSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); - unbindDeferredShader(gDeferredMultiSpotLightProgram); - glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); - } - } + unbindDeferredShader(gDeferredMultiLightProgram); + } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gGL.setColorMask(true, true); -/* - if (gSavedSettings.getBOOL("RenderDeferredGI")) - { - mDeferredLight[2].flush(); - mScreen.bindTarget(); - mScreen.clear(GL_COLOR_BUFFER_BIT); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); - { //mix various light maps (local, sun, gi) + { //render non-deferred geometry LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - LLGLDepthTest depth(GL_FALSE); LLGLDisable stencil(GL_STENCIL_TEST); - - gViewerWindow->setupViewport(); - - bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]); - - gDeferredPostProgram.bind(); - - LLVertexBuffer::unbind(); - - glVertexPointer(2, GL_FLOAT, 0, vert); - glColor3f(1,1,1); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glDrawArrays(GL_TRIANGLES, 0, 3); - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - unbindDeferredShader(gDeferredPostProgram); - } - } -*/ - { //render non-deferred geometry (alpha, fullbright, glow) KL issues with render pipeline merge needs work.. here - LLGLDisable blend(GL_BLEND); - LLGLDisable stencil(GL_STENCIL_TEST); - gGL.setSceneBlendType(LLRender::BT_ALPHA); U32 render_mask = mRenderTypeMask; mRenderTypeMask = mRenderTypeMask & ((1 << LLPipeline::RENDER_TYPE_SKY) | @@ -6803,161 +5768,18 @@ void LLPipeline::renderDeferredLighting() (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | (1 << LLPipeline::RENDER_TYPE_VOLUME) | (1 << LLPipeline::RENDER_TYPE_GLOW) | - (1 << LLPipeline::RENDER_TYPE_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_GLOW) | - (1 << LLPipeline::RENDER_TYPE_PASS_GRASS) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY)); + (1 << LLPipeline::RENDER_TYPE_BUMP)); renderGeomPostDeferred(*LLViewerCamera::getInstance()); mRenderTypeMask = render_mask; } - mScreen.flush(); // We are FLUSHED alright ! end of deferred render YAY! + mScreen.flush(); } -void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) -{ - //construct frustum - LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 params = volume->getSpotLightParams(); - - F32 fov = params.mV[0]; - F32 focus = params.mV[1]; - - LLVector3 pos = drawablep->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); - LLVector3 scale = volume->getScale(); - - //get near clip plane - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; - - LLVector3 np = pos+at_axis; - at_axis.normVec(); - - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); - - LLVector3 origin = np - at_axis*dist; - - //matrix from volume space to agent space - LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); - - glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); - glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent; - - glh::matrix4f screen_to_light = light_to_screen.inverse(); - - F32 s = volume->getLightRadius()*1.5f; - F32 near_clip = dist; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = s+dist-scale.mV[VZ]; - - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; - - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); - - glh::vec3f p1(0, 0, -(near_clip+0.01f)); - glh::vec3f p2(0, 0, -(near_clip+1.f)); - - glh::vec3f screen_origin(0, 0, 0); - - light_to_screen.mult_matrix_vec(p1); - light_to_screen.mult_matrix_vec(p2); - light_to_screen.mult_matrix_vec(screen_origin); - - glh::vec3f n = p2-p1; - n.normalize(); - - F32 proj_range = far_clip - near_clip; - glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); - screen_to_light = trans * light_proj * screen_to_light; - shader.uniformMatrix4fv("proj_mat", 1, FALSE, screen_to_light.m); - shader.uniform1f("proj_near", near_clip); - shader.uniform3fv("proj_p", 1, p1.v); - shader.uniform3fv("proj_n", 1, n.v); - shader.uniform3fv("proj_origin", 1, screen_origin.v); - shader.uniform1f("proj_range", proj_range); - shader.uniform1f("proj_ambiance", params.mV[2]); - S32 s_idx = -1; - - for (U32 i = 0; i < 2; i++) - { - if (mShadowSpotLight[i] == drawablep) - { - s_idx = i; - } - } - - shader.uniform1i("proj_shadow_idx", s_idx); - - if (s_idx >= 0) - { - shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]); - } - else - { - shader.uniform1f("shadow_fade", 1.f); - } - - { - LLDrawable* potential = drawablep; - //determine if this is a good light for casting shadows - F32 m_pri = volume->getSpotLightPriority(); - - for (U32 i = 0; i < 2; i++) - { - F32 pri = 0.f; - - if (mTargetShadowSpotLight[i].notNull()) - { - pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority(); - } - - if (m_pri > pri) - { - LLDrawable* temp = mTargetShadowSpotLight[i]; - mTargetShadowSpotLight[i] = potential; - potential = temp; - m_pri = pri; - } - } - } - - LLViewerImage* img = volume->getLightTexture(); - - S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); - - if (channel > -1 && img) - { - gGL.getTexUnit(channel)->bind(img); - - F32 lod_range = logf(img->getWidth())/logf(2.f); - - shader.uniform1f("proj_focus", focus); - shader.uniform1f("proj_lod", lod_range); - shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); - } -} - void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { - LLFastTimer ftm(LLFastTimer::FTM_TEMP4); stop_glerror(); shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); @@ -6965,40 +5787,14 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); - shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); - for (U32 i = 0; i < 4; i++) - { - if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) - { - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - } - } - - for (U32 i = 4; i < 6; i++) { if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } } - shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); if (channel > -1) @@ -7012,8 +5808,6 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->activate(); shader.unbind(); - - LLGLState::checkTextureChannels(); } inline float sgn(float a) @@ -7153,15 +5947,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } } - //LLSpatialPartition::sFreezeState = TRUE; - //LLPipeline::sSkipUpdate = TRUE; + LLSpatialPartition::sFreezeState = TRUE; + LLPipeline::sSkipUpdate = TRUE; LLGLUserClipPlane clip_plane(plane, mat, projection); static LLCullResult result; updateCull(camera, result, 1); stateSort(camera, result); renderGeom(camera); - //LLSpatialPartition::sFreezeState = FALSE; - //LLPipeline::sSkipUpdate = FALSE; + LLSpatialPartition::sFreezeState = FALSE; + LLPipeline::sSkipUpdate = FALSE; } } glCullFace(GL_BACK); @@ -7261,6 +6055,7 @@ glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) dirN = dir; dirN.normVec(); + ret.m[ 0] = lftN[0]; ret.m[ 1] = upN[0]; @@ -7311,629 +6106,114 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) return ret; } -void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, BOOL use_shader) +void LLPipeline::generateSunShadow(LLCamera& camera) { - LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); - - //clip out geometry on the same side of water as the camera - static LLCullResult result; - S32 occlude = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 1; - LLPipeline::sShadowRender = TRUE; - - updateCull(shadow_cam, result); - stateSort(shadow_cam, result); - - U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; - LLGLEnable cull(GL_CULL_FACE); - - //generate shadow map - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(proj.m); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(view.m); - - stop_glerror(); - gGLLastMatrix = NULL; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - glColor4f(1,1,1,1); - - stop_glerror(); - - gGL.setColorMask(false, false); - if (use_shader) + if (!sRenderDeferred) { - gDeferredShadowProgram.bind(); + return; } - //glCullFace(GL_FRONT); - + //temporary hack to disable shadows but keep local lights + static BOOL clear = TRUE; + BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); + if (!gen_shadow) { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->disable(); - for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) + if (clear) { - renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + clear = FALSE; + for (U32 i = 0; i < 4; i++) + { + mSunShadow[i].bindTarget(); + mSunShadow[i].clear(); + mSunShadow[i].flush(); + } } - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - } - - if (use_shader) - { - gDeferredShadowProgram.unbind(); - renderGeomShadow(shadow_cam); - gDeferredShadowProgram.bind(); - } - else - { - renderGeomShadow(shadow_cam); - } - - { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); - LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); - renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); - glColor4f(1,1,1,1); - renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + return; } + clear = TRUE; - //glCullFace(GL_BACK); + gGL.setColorMask(false, false); - if (use_shader) - { - gDeferredShadowProgram.unbind(); - } + //get sun view matrix - gGL.setColorMask(true, true); + F32 range = 128.f; - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gGLLastMatrix = NULL; + //store current projection/modelview matrix + glh::matrix4f saved_proj = glh_get_current_projection(); + glh::matrix4f saved_view = glh_get_current_modelview(); + glh::matrix4f inv_view = saved_view.inverse(); - LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = FALSE; -} + glh::matrix4f view[4]; + glh::matrix4f proj[4]; + LLVector3 up; + //clip contains parallel split distances for 3 splits + LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes"); -BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) -{ - LLFastTimer ftm(LLFastTimer::FTM_TEMP2); - //get point cloud of intersection of frust and min, max + //far clip on last split is minimum of camera view distance and 128 + mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); - //get set of planes - std::vector<LLPlane> ps; - - if (getVisibleExtents(camera, min, max)) - { - return FALSE; + const LLPickInfo& pick_info = gViewerWindow->getLastPick(); + + if (!pick_info.mPosGlobal.isExactlyZero()) + { //squish nearest frustum based on alt-zoom (tighten up nearest frustum when focusing on tiny object + F32 focus_dist = (F32) (pick_info.mPosGlobal + LLVector3d(pick_info.mObjectOffset) - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec(); + mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]); } + + // convenience array of 4 near clip plane distances + F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; - ps.push_back(LLPlane(min, LLVector3(-1,0,0))); - ps.push_back(LLPlane(min, LLVector3(0,-1,0))); - ps.push_back(LLPlane(min, LLVector3(0,0,-1))); - ps.push_back(LLPlane(max, LLVector3(1,0,0))); - ps.push_back(LLPlane(max, LLVector3(0,1,0))); - ps.push_back(LLPlane(max, LLVector3(0,0,1))); + //currently used for amount to extrude frusta corners for constructing shadow frusta + LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); + F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; - if (!light_dir.isExactlyZero()) + for (S32 j = 0; j < 4; j++) { - LLPlane ucp; - LLPlane mcp; + //restore render matrices + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); - F32 maxd = -1.f; - F32 mind = 1.f; + //get center of far clip plane (for point of interest later) + LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range; - for (U32 i = 0; i < ps.size(); ++i) - { //pick the plane most aligned to lightDir for user clip plane - LLVector3 n(ps[i].mV); - F32 da = n*light_dir; - if (da > maxd) - { - maxd = da; - ucp = ps[i]; - } + LLVector3 eye = camera.getOrigin(); - if (da < mind) - { - mind = da; - mcp = ps[i]; - } - } - - camera.setUserClipPlane(ucp); + //camera used for shadow cull/render + LLCamera shadow_cam; + + // perspective shadow map + glh::vec3f p[16]; //point cloud to be contained by shadow projection (light camera space) + glh::vec3f wp[16]; //point cloud to be contained by shadow projection (world space) + + LLVector3 lightDir = -mSunDir; + glh::vec3f light_dir(lightDir.mV); - ps.clear(); - ps.push_back(ucp); - ps.push_back(mcp); - } - - for (U32 i = 0; i < 6; i++) - { - ps.push_back(camera.getAgentPlane(i)); - } + //create light space camera matrix + LLVector3 at; + F32 dl = camera.getLeftAxis() * lightDir; + F32 du = camera.getUpAxis() * lightDir; - //get set of points where planes intersect and points are not above any plane - fp.clear(); - - for (U32 i = 0; i < ps.size(); ++i) - { - for (U32 j = 0; j < ps.size(); ++j) - { - for (U32 k = 0; k < ps.size(); ++k) - { - if (i == j || - i == k || - k == j) - { - continue; - } - - LLVector3 n1,n2,n3; - F32 d1,d2,d3; - - n1.setVec(ps[i].mV); - n2.setVec(ps[j].mV); - n3.setVec(ps[k].mV); - - d1 = ps[i].mV[3]; - d2 = ps[j].mV[3]; - d3 = ps[k].mV[3]; - - //get point of intersection of 3 planes "p" - LLVector3 p = (-d1*(n2%n3)-d2*(n3%n1)-d3*(n1%n2))/(n1*(n2%n3)); - - if (llround(p*n1+d1, 0.0001f) == 0.f && - llround(p*n2+d2, 0.0001f) == 0.f && - llround(p*n3+d3, 0.0001f) == 0.f) - { //point is on all three planes - BOOL found = TRUE; - for (U32 l = 0; l < ps.size() && found; ++l) - { - if (llround(ps[l].dist(p), 0.0001f) > 0.0f) - { //point is above some plane, not contained - found = FALSE; - } - } - - if (found) - { - fp.push_back(p); - } - } - } - } - } - - if (fp.empty()) - { - return FALSE; - } - - return TRUE; -} - -void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc) -{ -/* if (!gSavedSettings.getBOOL("RenderDeferredGI")) - { - return; - } */ - - LLVector3 up; - - if (lightDir.mV[2] > 0.5f) - { - up = LLVector3(1,0,0); - } - else - { - up = LLVector3(0, 0, 1); - } - - - F32 lrad = gSavedSettings.getF32("RenderGILightRadius"); - - F32 samples = (F32) gSavedSettings.getU32("RenderGISamples"); - - F32 gi_range = gSavedSettings.getF32("RenderGIRange"); - - U32 res = 1024; - - lrad = samples*gi_range/(res-samples)*0.5f; - - F32 lrange = lrad+gi_range*0.5f; - - LLVector3 pad(lrange,lrange,lrange); - - glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up); - - LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f); - - glh::vec3f scp(cp.mV); - view.mult_matrix_vec(scp); - cp.setVec(scp.v); - - F32 pix_width = lrange/(res*0.5f); - - //lrad = llround(lrad, pix_width); - - //move cp to the nearest pix_width - for (U32 i = 0; i < 3; i++) - { - cp.mV[i] = llround(cp.mV[i], pix_width); - } - - LLVector3 min = cp-pad; - LLVector3 max = cp+pad; - - //set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point - mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res; - mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res; - mGILightRadius = lrad; - - glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - - LLCamera sun_cam = camera; - - glh::matrix4f eye_view = glh_get_current_modelview(); - - //get eye space to camera space matrix - mGIMatrix = view*eye_view.inverse(); - mGINormalMatrix = mGIMatrix.inverse().transpose(); - mGIInvProj = proj.inverse(); - mGIMatrixProj = proj*mGIMatrix; - - //translate and scale to [0,1] - glh::matrix4f trans(.5f, 0.f, 0.f, .5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); - - mGIMatrixProj = trans*mGIMatrixProj; - - glh_set_current_modelview(view); - glh_set_current_projection(proj); - - LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE); - - sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); - static LLCullResult result; - - U32 type_mask = mRenderTypeMask; - - mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | - (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1<<LLPipeline::RENDER_TYPE_BUMP) | - (1<<LLPipeline::RENDER_TYPE_VOLUME) | - (1<<LLPipeline::RENDER_TYPE_TREE) | - (1<<LLPipeline::RENDER_TYPE_TERRAIN) | - (1<<LLPipeline::RENDER_TYPE_WATER) | - (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | - (1<<LLPipeline::RENDER_TYPE_AVATAR) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY)); - - - - S32 occlude = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 0; - LLPipeline::sShadowRender = TRUE; - - updateCull(sun_cam, result); - stateSort(sun_cam, result); - - LLGLEnable cull(GL_CULL_FACE); - - //generate GI map - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(proj.m); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(view.m); - - stop_glerror(); - gGLLastMatrix = NULL; - - mGIMap.clear(); - - { - LLGLEnable enable(GL_DEPTH_CLAMP_NV); - renderGeomDeferred(camera); - } - - mGIMap.flush(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gGLLastMatrix = NULL; - - LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = FALSE; - - - mRenderTypeMask = type_mask; - -} - -void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) -{ - if (!gSavedSettings.getBOOL("renderhighlights")) // KL need this to make the mouseover Highlights toggle ^^ - { - return; - } - - if (obj && obj->getVolume()) - { - for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter) - { - renderHighlight(*iter, fade); - } - - LLDrawable* drawable = obj->mDrawable; - if (drawable) - { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* face = drawable->getFace(i); - if (face) - { - face->renderSelected(LLViewerImage::sNullImagep, LLColor4(1,1,1,fade)); - } - } - } - } -} - -void LLPipeline::generateHighlight(LLCamera& camera) -{ - if (!gSavedSettings.getBOOL("renderhighlights")) // KL need this to make the mouseover Highlights toggle ^^ - { - return; - } - //render highlighted object as white into offscreen render target - - if (mHighlightObject.notNull()) - { - mHighlightSet.insert(HighlightItem(mHighlightObject)); - } - - if (!mHighlightSet.empty()) - { - F32 transition = gFrameIntervalSeconds/gSavedSettings.getF32("RenderHighlightFadeTime"); - - LLGLDisable test(GL_ALPHA_TEST); - LLGLDepthTest depth(GL_FALSE); - mHighlight.bindTarget(); - disableLights(); - gGL.setColorMask(true, true); - mHighlight.clear(); - - gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep); - for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ) - { - std::set<HighlightItem>::iterator cur_iter = iter++; - - if (cur_iter->mItem.isNull()) - { - mHighlightSet.erase(cur_iter); - continue; - } - - if (cur_iter->mItem == mHighlightObject) - { - cur_iter->incrFade(transition); - } - else - { - cur_iter->incrFade(-transition); - if (cur_iter->mFade <= 0.f) - { - mHighlightSet.erase(cur_iter); - continue; - } - } - - renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade); - } - - mHighlight.flush(); - gGL.setColorMask(true, false); - gViewerWindow->setupViewport(); - } -} - - -void LLPipeline::generateSunShadow(LLCamera& camera) -{ - if (!sRenderDeferred) - { - return; - } - - LLFastTimer ftm(LLFastTimer::FTM_TEMP1); - - //temporary hack to disable shadows but keep local lights - static BOOL clear = TRUE; - BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); - if (!gen_shadow) - { - if (clear) - { - clear = FALSE; - for (U32 i = 0; i < 6; i++) - { - mShadow[i].bindTarget(); - mShadow[i].clear(); - mShadow[i].flush(); - } - } - return; - } - clear = TRUE; - - U32 type_mask = mRenderTypeMask; - mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | - (1<<LLPipeline::RENDER_TYPE_ALPHA) | - (1<<LLPipeline::RENDER_TYPE_GRASS) | - (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1<<LLPipeline::RENDER_TYPE_BUMP) | - (1<<LLPipeline::RENDER_TYPE_VOLUME) | - (1<<LLPipeline::RENDER_TYPE_AVATAR) | - (1<<LLPipeline::RENDER_TYPE_TREE) | - (1<<LLPipeline::RENDER_TYPE_TERRAIN) | - (1<<LLPipeline::RENDER_TYPE_WATER) | - (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY)); - - gGL.setColorMask(false, false); - - //get sun view matrix - - //store current projection/modelview matrix - glh::matrix4f saved_proj = glh_get_current_projection(); - glh::matrix4f saved_view = glh_get_current_modelview(); - glh::matrix4f inv_view = saved_view.inverse(); - - glh::matrix4f view[6]; - glh::matrix4f proj[6]; - - //clip contains parallel split distances for 3 splits - LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes"); - - //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold"); - - //far clip on last split is minimum of camera view distance and 128 - mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); - - clip = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); - mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); - - //currently used for amount to extrude frusta corners for constructing shadow frusta - LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); - //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; - - LLVector3 lightDir = -mSunDir; - lightDir.normVec(); - - glh::vec3f light_dir(lightDir.mV); - - //create light space camera matrix - - LLVector3 at = lightDir; - - LLVector3 up = camera.getAtAxis(); - - if (fabsf(up*lightDir) > 0.75f) - { - up = camera.getUpAxis(); - } - - /*LLVector3 left = up%at; - up = at%left;*/ - - up.normVec(); - at.normVec(); - - - F32 near_clip = 0.f; - { - //get visible point cloud - std::vector<LLVector3> fp; - - LLVector3 min,max; - getVisiblePointCloud(camera,min,max,fp); - - if (fp.empty()) + //choose an at axis such that up will be most aligned with lightDir + if (dl*dl < du*du) { - mRenderTypeMask = type_mask; - return; + at = lightDir%camera.getLeftAxis(); } - - generateGI(camera, lightDir, fp); - - //get good split distances for frustum - for (U32 i = 0; i < fp.size(); ++i) + else { - glh::vec3f v(fp[i].mV); - saved_view.mult_matrix_vec(v); - fp[i].setVec(v.v); + at = lightDir%camera.getUpAxis(); } - min = fp[0]; - max = fp[0]; - - //get camera space bounding box - for (U32 i = 1; i < fp.size(); ++i) + if (at * camera.getAtAxis() < 0) { - update_min_max(min, max, fp[i]); + at = -at; } - - near_clip = -max.mV[2]; - F32 far_clip = -min.mV[2]*2.f; - - far_clip = llmin(far_clip, 128.f); - far_clip = llmin(far_clip, camera.getFar()); - - F32 range = far_clip-near_clip; - - LLVector3 split_exp = gSavedSettings.getVector3("RenderShadowSplitExponent"); - - F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); - da = powf(da, split_exp.mV[2]); - - - F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; - - - for (U32 i = 0; i < 4; ++i) - { - F32 x = (F32)(i+1)/4.f; - x = powf(x, sxp); - mSunClipPlanes.mV[i] = near_clip+range*x; - } - } - - // convenience array of 4 near clip plane distances - F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; - - for (S32 j = 0; j < 4; j++) - { - if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowFrustPoints[j].clear(); - } - - //restore render matrices - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); - - LLVector3 eye = camera.getOrigin(); + LLVector3 left = lightDir%at; + up = left%lightDir; + up.normVec(); - //camera used for shadow cull/render - LLCamera shadow_cam; - //create world space camera frustum for this split shadow_cam = camera; shadow_cam.setFar(16.f); @@ -7944,6 +6224,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 pn = shadow_cam.getAtAxis(); + LLVector3 frust_center; + LLVector3 min, max; //construct 8 corners of split frustum section @@ -7954,19 +6236,21 @@ void LLPipeline::generateSunShadow(LLCamera& camera) F32 dp = delta*pn; frust[i] = eye + (delta*dist[j])/dp; frust[i+4] = eye + (delta*dist[j+1])/dp; + frust_center += frust[i] + frust[i+4]; } + + //get frustum center + frust_center /= 8.f; shadow_cam.calcAgentFrustumPlanes(frust); - shadow_cam.mFrustumCornerDist = 0.f; + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { mShadowCamera[j] = shadow_cam; } - std::vector<LLVector3> fp; - - if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) + if (gPipeline.getVisibleExtents(shadow_cam, min, max)) { //no possible shadow receivers if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) @@ -7976,16 +6260,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowCamera[j+4] = shadow_cam; } - mShadow[j].bindTarget(); - { - LLGLDepthTest depth(GL_TRUE); - mShadow[j].clear(); - } - mShadow[j].flush(); - - mShadowError.mV[j] = 0.f; - mShadowFOV.mV[j] = 0.f; - continue; } @@ -7993,252 +6267,42 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { mShadowExtents[j][0] = min; mShadowExtents[j][1] = max; - mShadowFrustPoints[j] = fp; } + view[j] = look(frust_center-lightDir*nearDist[j], lightDir, up); + F32 shadow_dist = nearDist[j]; - //find a good origin for shadow projection - LLVector3 origin; - - //get a temporary view projection - view[j] = look(camera.getOrigin(), lightDir, -up); - - std::vector<LLVector3> wpf; - - for (U32 i = 0; i < fp.size(); i++) + for (U32 i = 0; i < 8; i++) { - glh::vec3f p = glh::vec3f(fp[i].mV); - view[j].mult_matrix_vec(p); - wpf.push_back(LLVector3(p.v)); - } - - min = wpf[0]; - max = wpf[0]; - - for (U32 i = 0; i < fp.size(); ++i) - { //get AABB in camera space - update_min_max(min, max, wpf[i]); + //points in worldspace (wp) and light camera space (p) + //that must be included in shadow generation + wp[i] = glh::vec3f(frust[i].mV); + wp[i+8] = wp[i] - light_dir*shadow_dist; + view[j].mult_matrix_vec(wp[i], p[i]); + view[j].mult_matrix_vec(wp[i+8], p[i+8]); } - - // Construct a perspective transform with perspective along y-axis that contains - // points in wpf - //Known: - // - far clip plane - // - near clip plane - // - points in frustum - //Find: - // - origin - - //get some "interesting" points of reference - LLVector3 center = (min+max)*0.5f; - LLVector3 size = (max-min)*0.5f; - LLVector3 near_center = center; - near_center.mV[1] += size.mV[1]*2.f; - - //put all points in wpf in quadrant 0, reletive to center of min/max - //get the best fit line using least squares - F32 bfm = 0.f; - F32 bfb = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - wpf[i] -= center; - wpf[i].mV[0] = fabsf(wpf[i].mV[0]); - wpf[i].mV[2] = fabsf(wpf[i].mV[2]); - } - - if (!wpf.empty()) - { - F32 sx = 0.f; - F32 sx2 = 0.f; - F32 sy = 0.f; - F32 sxy = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - sx += wpf[i].mV[0]; - sx2 += wpf[i].mV[0]*wpf[i].mV[0]; - sy += wpf[i].mV[1]; - sxy += wpf[i].mV[0]*wpf[i].mV[1]; - } + min = LLVector3(p[0].v); + max = LLVector3(p[0].v); - bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); - bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); - } - - { - // best fit line is y=bfm*x+bfb - - //find point that is furthest to the right of line - F32 off_x = -1.f; - LLVector3 lp; + LLVector3 fmin = min; + LLVector3 fmax = max; - for (U32 i = 0; i < wpf.size(); ++i) + for (U32 i = 1; i < 16; i++) + { //find camera space AABB of frustum in light camera space + update_min_max(min, max, LLVector3(p[i].v)); + if (i < 8) { - //y = bfm*x+bfb - //x = (y-bfb)/bfm - F32 lx = (wpf[i].mV[1]-bfb)/bfm; - - lx = wpf[i].mV[0]-lx; - - if (off_x < lx) - { - off_x = lx; - lp = wpf[i]; + update_min_max(fmin, fmax, LLVector3(p[i].v)); } } - //get line with slope bfm through lp - // bfb = y-bfm*x - bfb = lp.mV[1]-bfm*lp.mV[0]; - - //calculate error - mShadowError.mV[j] = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - F32 lx = (wpf[i].mV[1]-bfb)/bfm; - mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); - } - - mShadowError.mV[j] /= wpf.size(); - mShadowError.mV[j] /= size.mV[0]; - - if (mShadowError.mV[j] > gSavedSettings.getF32("RenderShadowErrorCutoff")) - { //just use ortho projection - mShadowFOV.mV[j] = -1.f; - origin.clearVec(); + //generate perspective matrix that contains frustum + //proj[j] = matrix_perspective(min, max); proj[j] = gl_ortho(min.mV[0], max.mV[0], min.mV[1], max.mV[1], -max.mV[2], -min.mV[2]); - } - else - { - //origin is where line x = 0; - origin.setVec(0,bfb,0); - - F32 fovz = 1.f; - F32 fovx = 1.f; - LLVector3 zp; - LLVector3 xp; - - for (U32 i = 0; i < wpf.size(); ++i) - { - LLVector3 atz = wpf[i]-origin; - atz.mV[0] = 0.f; - atz.normVec(); - if (fovz > -atz.mV[1]) - { - zp = wpf[i]; - fovz = -atz.mV[1]; - } - - LLVector3 atx = wpf[i]-origin; - atx.mV[2] = 0.f; - atx.normVec(); - if (fovx > -atx.mV[1]) - { - fovx = -atx.mV[1]; - xp = wpf[i]; - } - } - - fovx = acos(fovx); - fovz = acos(fovz); - - F32 cutoff = llmin(gSavedSettings.getF32("RenderShadowFOVCutoff"), 1.4f); - - mShadowFOV.mV[j] = fovx; - - if (fovx < cutoff && fovz > cutoff) - { - //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff - F32 d = zp.mV[2]/tan(cutoff); - F32 ny = zp.mV[1] + fabsf(d); - - origin.mV[1] = ny; - - fovz = 1.f; - fovx = 1.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - LLVector3 atz = wpf[i]-origin; - atz.mV[0] = 0.f; - atz.normVec(); - fovz = llmin(fovz, -atz.mV[1]); - - LLVector3 atx = wpf[i]-origin; - atx.mV[2] = 0.f; - atx.normVec(); - fovx = llmin(fovx, -atx.mV[1]); - } - - fovx = acos(fovx); - fovz = acos(fovz); - - if (fovx > cutoff || llround(fovz, 0.01f) > cutoff) - { - // llwarns << "WTF?" << llendl; - } - - mShadowFOV.mV[j] = cutoff; - } - - - origin += center; - - F32 ynear = -(max.mV[1]-origin.mV[1]); - F32 yfar = -(min.mV[1]-origin.mV[1]); - - if (ynear < 0.1f) //keep a sensible near clip plane - { - F32 diff = 0.1f-ynear; - origin.mV[1] += diff; - ynear += diff; - yfar += diff; - } - - if (fovx > cutoff) - { //just use ortho projection - origin.clearVec(); - mShadowError.mV[j] = -1.f; - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - } - else - { - //get perspective projection - view[j] = view[j].inverse(); - - glh::vec3f origin_agent(origin.mV); - - //translate view to origin - view[j].mult_matrix_vec(origin_agent); - - eye = LLVector3(origin_agent.v); - - if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowFrustOrigin[j] = eye; - } - - view[j] = look(LLVector3(origin_agent.v), lightDir, -up); - - F32 fx = 1.f/tanf(fovx); - F32 fz = 1.f/tanf(fovz); - - proj[j] = glh::matrix4f(-fx, 0, 0, 0, - 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), - 0, 0, -fz, 0, - 0, -1.f, 0, 0); - } - } - } - shadow_cam.setFar(128.f); shadow_cam.setOriginAndLookAt(eye, up, center); @@ -8247,7 +6311,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + proj[j] = gl_ortho(fmin.mV[0], fmax.mV[0], + fmin.mV[1], fmax.mV[1], + -fmax.mV[2], -fmin.mV[2]); //translate and scale to from [-1, 1] to [0, 1] glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, @@ -8260,154 +6326,110 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; + U32 type_mask = mRenderTypeMask; + mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | + (1<<LLPipeline::RENDER_TYPE_ALPHA) | + (1<<LLPipeline::RENDER_TYPE_GRASS) | + (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | + (1<<LLPipeline::RENDER_TYPE_BUMP) | + (1<<LLPipeline::RENDER_TYPE_VOLUME) | + (1<<LLPipeline::RENDER_TYPE_AVATAR) | + (1<<LLPipeline::RENDER_TYPE_TREE) | + (1<<LLPipeline::RENDER_TYPE_TERRAIN) | + 0); + + //clip out geometry on the same side of water as the camera + static LLCullResult result; + S32 occlude = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 1; + LLPipeline::sShadowRender = TRUE; //hack to prevent LOD updates from using sun camera origin shadow_cam.setOrigin(camera.getOrigin()); - - stop_glerror(); - - mShadow[j].bindTarget(); - mShadow[j].getViewport(gGLViewport); - - { - LLGLDepthTest depth(GL_TRUE); - mShadow[j].clear(); - } - - { - LLGLEnable enable(GL_DEPTH_CLAMP_NV); - renderShadow(view[j], proj[j], shadow_cam, FALSE); - } - - mShadow[j].flush(); + updateCull(shadow_cam, result); + stateSort(shadow_cam, result); if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); mShadowCamera[j+4] = shadow_cam; } - } - - //llinfos << "Shadow error: " << error << " Slope: " << best_fit_slope << llendl; - - F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); + LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); - //update shadow targets - for (U32 i = 0; i < 2; i++) - { //for each current shadow - if (mShadowSpotLight[i].notNull() && - (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || - mShadowSpotLight[i] == mTargetShadowSpotLight[1])) - { //keep this spotlight - mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); - } - else - { //fade out this light - mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); - - if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) - { //faded out, grab one of the pending spots (whichever one isn't already taken) - if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) - { - mShadowSpotLight[i] = mTargetShadowSpotLight[0]; - } - else - { - mShadowSpotLight[i] = mTargetShadowSpotLight[1]; - } - } - } - } - - for (S32 i = 0; i < 2; i++) - { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); - - if (mShadowSpotLight[i].isNull()) - { - continue; - } + stop_glerror(); - LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + mSunShadow[j].bindTarget(); + mSunShadow[j].getViewport(gGLViewport); - if (!volume) { - mShadowSpotLight[i] = NULL; - continue; + LLGLDepthTest depth(GL_TRUE); + mSunShadow[j].clear(); } - LLDrawable* drawable = mShadowSpotLight[i]; - - LLVector3 params = volume->getSpotLightParams(); - F32 fov = params.mV[0]; - - //get agent->light space matrix (modelview) - LLVector3 center = drawable->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); - - //get near clip plane - LLVector3 scale = volume->getScale(); - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; - - LLVector3 np = center+at_axis; - at_axis.normVec(); - - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; + LLGLEnable cull(GL_CULL_FACE); - LLVector3 origin = np - at_axis*dist; - - LLMatrix4 mat(quat, LLVector4(origin, 1.f)); - - view[i+4] = glh::matrix4f((F32*) mat.mMatrix); - - view[i+4] = view[i+4].inverse(); + //generate sun shadow map + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(proj[j].m); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(view[j].m); - //get perspective matrix - F32 near_clip = dist+0.01f; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = dist+volume->getLightRadius()*1.5f; + stop_glerror(); + gGLLastMatrix = NULL; - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); - - glh_set_current_modelview(view[i+4]); - glh_set_current_projection(proj[i+4]); - - mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; + glColor4f(1,1,1,1); - LLCamera shadow_cam = camera; - shadow_cam.setFar(far_clip); - shadow_cam.setOrigin(origin); - - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - - shadow_cam.setOrigin(camera.getOrigin()); + glCullFace(GL_FRONT); stop_glerror(); - mShadow[i+4].bindTarget(); - mShadow[i+4].getViewport(gGLViewport); + gGL.setColorMask(false, false); + gDeferredShadowProgram.bind(); { - LLGLDepthTest depth(GL_TRUE); - mShadow[i+4].clear(); + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->disable(); + for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) + { + renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); } + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + } + + { + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); + LLGLEnable test(GL_ALPHA_TEST); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); + renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); + glColor4f(1,1,1,1); + renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + } + + gDeferredShadowProgram.unbind(); + + renderGeomShadow(shadow_cam); - renderShadow(view[i+4], proj[i+4], shadow_cam, FALSE); + gGL.setColorMask(true, true); - mShadow[i+4].flush(); + glCullFace(GL_BACK); + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = FALSE; + mRenderTypeMask = type_mask; + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gGLLastMatrix = NULL; + + mSunShadow[j].flush(); } if (!gSavedSettings.getBOOL("CameraOffset")) @@ -8425,8 +6447,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glMatrixMode(GL_MODELVIEW); } gGL.setColorMask(true, false); - - mRenderTypeMask = type_mask; } void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) @@ -8466,7 +6486,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (muted) { - mask = 1 << LLPipeline::RENDER_TYPE_INVISIBLE; // Peachy ;) + mask = 1 << LLPipeline::RENDER_TYPE_AVATAR; } else { @@ -8477,16 +6497,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) (1<<LLPipeline::RENDER_TYPE_SIMPLE) | (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | (1<<LLPipeline::RENDER_TYPE_ALPHA) | - (1<<LLPipeline::RENDER_TYPE_INVISIBLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); + (1<<LLPipeline::RENDER_TYPE_INVISIBLE); } mask = mask & gPipeline.getRenderTypeMask(); @@ -8496,7 +6507,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) S32 occlusion = sUseOcclusion; sUseOcclusion = 0; sReflectionRender = sRenderDeferred ? FALSE : TRUE; - sShadowRender = TRUE; sImpostorRender = TRUE; markVisible(avatar->mDrawable, *LLViewerCamera::getInstance()); @@ -8576,7 +6586,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (LLPipeline::sRenderDeferred) { avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE); - //addDeferredAttachments(avatar->mImpostor); + addDeferredAttachments(avatar->mImpostor); } else { @@ -8655,7 +6665,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sUseOcclusion = occlusion; sReflectionRender = FALSE; sImpostorRender = FALSE; - sShadowRender = FALSE; gPipeline.mRenderTypeMask = saved_mask; glMatrixMode(GL_PROJECTION); diff --git a/linden/indra/newview/pipeline.h b/linden/indra/newview/pipeline.h index 7c56375ec..1ecb56e92 100644 --- a/linden/indra/newview/pipeline.h +++ b/linden/indra/newview/pipeline.h @@ -129,8 +129,6 @@ class LLPipeline void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE); void markShift(LLDrawable *drawablep); void markTextured(LLDrawable *drawablep); - void markGLRebuild(LLGLUpdate* glu); - void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); //get the object between start and end that's closest to start. @@ -181,14 +179,10 @@ class LLPipeline void updateMove(); BOOL visibleObjectsInFrustum(LLCamera& camera); BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); - BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0)); void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void updateGeom(F32 max_dtime); - void updateGL(); - void rebuildPriorityGroups(); - void rebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -209,21 +203,12 @@ class LLPipeline void renderGeomDeferred(LLCamera& camera); void renderGeomPostDeferred(LLCamera& camera); void renderGeomShadow(LLCamera& camera); - void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, LLRenderTarget* gi_source = NULL, LLRenderTarget* last_gi_post = NULL); - void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep); - + void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0); void unbindDeferredShader(LLGLSLShader& shader); void renderDeferredLighting(); void generateWaterReflection(LLCamera& camera); void generateSunShadow(LLCamera& camera); - void generateHighlight(LLCamera& camera); - void renderHighlight(const LLViewerObject* obj, F32 fade); - void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } - - - void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, BOOL use_shader = TRUE); - void generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc); // KL sd void renderHighlights(); void renderDebug(); @@ -331,27 +316,15 @@ class LLPipeline RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE, RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER, RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, - RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, + RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, - RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE, - RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, - RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, - RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, - RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, - RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY, - RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY, - RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP, - RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW, - RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA, - RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK, - RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, - RENDER_TYPE_PASS_ALPHA_SHADOW = LLRenderPass::PASS_ALPHA_SHADOW, + // Following are object types (only used in drawable mRenderType) RENDER_TYPE_HUD = LLDrawPool::NUM_POOL_TYPES, RENDER_TYPE_VOLUME, RENDER_TYPE_PARTICLES, RENDER_TYPE_CLOUDS, - RENDER_TYPE_HUD_PARTICLES // KL S19? + RENDER_TYPE_HUD_PARTICLES }; enum LLRenderDebugFeatureMask @@ -389,7 +362,8 @@ class LLPipeline RENDER_DEBUG_SHAME = 0x0020000, RENDER_DEBUG_SHADOW_FRUSTA = 0x0040000, RENDER_DEBUG_SCULPTED = 0x0080000, - RENDER_DEBUG_BUILD_QUEUE = 0x0100000, + RENDER_DEBUG_AVATAR_VOLUME = 0x0100000, + RENDER_DEBUG_AGENT_TARGET = 0x0200000, }; public: @@ -448,36 +422,15 @@ class LLPipeline //screen texture LLRenderTarget mScreen; LLRenderTarget mDeferredScreen; - LLRenderTarget mDeferredDepth; - LLRenderTarget mDeferredLight[3]; + LLRenderTarget mDeferredLight[2]; LLMultisampleBuffer mSampleBuffer; - LLRenderTarget mGIMap; - LLRenderTarget mGIMapPost[2]; - LLRenderTarget mLuminanceMap; - LLRenderTarget mHighlight; //sun shadow map - LLRenderTarget mShadow[6]; - std::vector<LLVector3> mShadowFrustPoints[4]; - LLVector4 mShadowError; - LLVector4 mShadowFOV; - LLVector3 mShadowFrustOrigin[4]; + LLRenderTarget mSunShadow[4]; LLCamera mShadowCamera[8]; LLVector3 mShadowExtents[4][2]; - glh::matrix4f mSunShadowMatrix[6]; - glh::matrix4f mGIMatrix; - glh::matrix4f mGIMatrixProj; - glh::matrix4f mGINormalMatrix; - glh::matrix4f mGIInvProj; - LLVector2 mGIRange; - F32 mGILightRadius; - - LLPointer<LLDrawable> mShadowSpotLight[2]; - F32 mSpotLightFade[2]; - LLPointer<LLDrawable> mTargetShadowSpotLight[2]; - + glh::matrix4f mSunShadowMatrix[4]; LLVector4 mSunClipPlanes; - LLVector4 mSunOrthoClipPlanes; LLVector2 mScreenScale; @@ -492,8 +445,6 @@ class LLPipeline //noise map U32 mNoiseMap; - U32 mTrueNoiseMap; - U32 mLightFunc; LLColor4 mSunDiffuse; LLVector3 mSunDir; @@ -554,45 +505,12 @@ class LLPipeline // LLDrawable::drawable_list_t mBuildQ1; // priority LLDrawable::drawable_list_t mBuildQ2; // non-priority - LLSpatialGroup::sg_list_t mGroupQ1; //priority - LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority - LLViewerObject::vobj_list_t mCreateQ; LLDrawable::drawable_set_t mActiveQ; LLDrawable::drawable_set_t mRetexturedList; - class HighlightItem - { - public: - const LLPointer<LLDrawable> mItem; - mutable F32 mFade; - - HighlightItem(LLDrawable* item) - : mItem(item), mFade(0) - { - } - - bool operator<(const HighlightItem& rhs) const - { - return mItem < rhs.mItem; - } - - bool operator==(const HighlightItem& rhs) const - { - return mItem == rhs.mItem; - } - - void incrFade(F32 val) const - { - mFade = llclamp(mFade+val, 0.f, 1.f); - } - }; - - std::set<HighlightItem> mHighlightSet; - LLPointer<LLDrawable> mHighlightObject; - ////////////////////////////////////////////////// // // Draw pools are responsible for storing all rendered data, diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml b/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml index e85eaa8ff..24a895bff 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml @@ -64,35 +64,7 @@ tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled." width="315" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="12" - left="10" mouse_opaque="true" name="Enable FBO:" v_pad="0" - width="128"> - Enable FBO: - </text> - <check_box bottom_delta="-5" control_name="RenderUseFBO" enabled="true" follows="left|top" - font="SansSerifSmall" height="16" initial_value="true" - label="Enable OpenGL Framebuffer Objects" left="148" - mouse_opaque="true" name="fbo" radio_style="false" - tool_tip="Enabling this will use OpenGL Framebuffer objects for some dynamic textures. Prerequisite for deferred rendering." - width="315" /> - - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="12" - left="10" mouse_opaque="true" name="Deferred Rendering:" v_pad="0" - width="128"> - Deferred Rendering: - </text> - <check_box bottom_delta="-5" control_name="RenderDeferred" enabled="true" follows="left|top" - font="SansSerifSmall" height="16" initial_value="true" - label="Enable per-pixel lighting and shadows" left="148" - mouse_opaque="true" name="deferred" radio_style="false" - tool_tip="Enabling this will perform lighting calculations in screen space, enabling per pixel lighting for all lights and shadows from the sun/moon. Requires a fast graphics card. Might not be compatible with FSAA." - width="315" /> - - <slider bottom_delta="-21" can_edit_text="false" control_name="TextureMemory" + <slider bottom_delta="-21" can_edit_text="false" control_name="TextureMemory" decimal_digits="0" enabled="true" follows="left|top" height="16" increment="16" initial_val="32" label="Texture Memory (MB):" label_width="135" left="10" diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index 1be2e58ff..0cb4a592a 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -1036,47 +1036,25 @@ <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom_delta="-21" drop_shadow_visible="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left_delta="0" - mouse_opaque="true" name="label color" v_pad="0" width="57"> + mouse_opaque="true" name="label color" v_pad="0" width="58"> Color: </text> <color_swatch border_color="0.45098, 0.517647, 0.607843, 1" bottom_delta="-28" can_apply_immediately="true" color="0.5, 0.5, 0.5, 1" follows="left|top" - height="48" label="" left_delta="57" mouse_opaque="true" name="colorswatch" + height="48" label="" left_delta="67" mouse_opaque="true" name="colorswatch" tool_tip="Click to open Color Picker" width="32" /> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="28" drop_shadow_visible="true" follows="left|top" - font="SansSerifSmall" h_pad="0" height="10" left="144" - mouse_opaque="true" name="label texture" v_pad="0" width="58"> - Texture - </text> - <texture_picker allow_no_texture="true" bottom_delta="-28" can_apply_immediately="true" - default_image_name="Default" follows="left|top" height="48" label="" - left_delta="57" mouse_opaque="true" name="light texture control" - tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)" width="32" /> <spinner bottom_delta="-4" decimal_digits="3" follows="left|top" height="16" - increment="0.1" initial_val="0.5" label="Intensity:" label_width="55" - left="10" max_val="1" min_val="0" mouse_opaque="true" - name="Light Intensity" width="120" /> - <spinner bottom_delta="0" decimal_digits="3" follows="left|top" height="16" - increment="0.1" initial_val="0.5" label="FOV" label_width="55" - left="144" max_val="3" min_val="0" mouse_opaque="true" - name="Light FOV" width="120" /> + increment="0.1" initial_val="0.5" label="Intensity:" label_width="65" + left="10" max_val="1" min_val="0" mouse_opaque="true" + name="Light Intensity" width="128" /> <spinner bottom_delta="-20" decimal_digits="3" follows="left|top" height="16" - increment="0.1" initial_val="5" label="Radius" label_width="55" - left="10" max_val="20" min_val="0" mouse_opaque="true" - name="Light Radius" width="120" /> - <spinner bottom_delta="0" decimal_digits="3" follows="left|top" height="16" - increment="0.5" initial_val="0.5" label="Focus" label_width="55" - left="144" max_val="20" min_val="-20" mouse_opaque="true" - name="Light Focus" width="120" /> + increment="0.1" initial_val="5" label="Radius:" label_width="65" + left_delta="0" max_val="20" min_val="0" mouse_opaque="true" + name="Light Radius" width="128" /> <spinner bottom_delta="-20" decimal_digits="3" follows="left|top" height="16" - increment="0.25" initial_val="1" label="Falloff" label_width="55" - left="10" max_val="2" min_val="0" mouse_opaque="true" - name="Light Falloff" width="120" /> - <spinner bottom_delta="0" decimal_digits="3" follows="left|top" height="16" - increment="0.05" initial_val="1" label="Ambiance" label_width="55" - left="144" max_val="1" min_val="0" mouse_opaque="true" - name="Light Ambiance" width="120" /> + increment="0.25" initial_val="1" label="Falloff:" label_width="65" + left_delta="0" max_val="2" min_val="0" mouse_opaque="true" + name="Light Falloff" width="128" /> </panel> <!-- Texture sub-tab --> From f90beef498640a2f7fd083eac687acac16e28613 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Tue, 12 Oct 2010 18:21:07 +0200 Subject: [PATCH 045/239] Don't try to fetch http-textures past end of file Treat http texture requests that returned less data than requsted as indication that we have the whole file, even if we did not specifically requested the whole file by using a very large range yet. IMPORTANT: This will fail to load past 599 bytes in OpenSim <= 0.7.0.2, as it has buggy handling of ranged requests. But OpenSim http texture breakage is not new. http://opensimulator.org/mantis/view.php?id=5081 --- linden/indra/newview/lltexturefetch.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index 5cad14c8d..bf97584e7 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -317,7 +317,7 @@ class HTTPGetResponder : public LLCurl::Responder mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow); } - lldebugs << "HTTP COMPLETE: " << mID << llendl; + LL_DEBUGS("TextureFetch") << "HTTP COMPLETE: " << mID << " with status: " << status << LL_ENDL; mFetcher->lockQueue(); LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) @@ -882,10 +882,11 @@ bool LLTextureFetchWorker::doWork(S32 param) mLoaded = FALSE; mGetStatus = 0; mGetReason.clear(); - lldebugs << "HTTP GET: " << mID << " Offset: " << offset + LL_DEBUGS("TextureFetch") << "HTTP GET: " << mID << " Offset: " << offset << " Bytes: " << mRequestedSize + << " Range: " << offset << "-" << offset+mRequestedSize-1 << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << max_bandwidth - << llendl; + << LL_ENDL; setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); mState = WAIT_HTTP_REQ; @@ -1322,18 +1323,18 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, gImageList.sTextureBits += data_size * 8; // Approximate - does not include header bits - //llinfos << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << llendl; + LL_DEBUGS("TextureFetch") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << " mRequestedSize: " << mRequestedSize << LL_ENDL; if (data_size > 0) { // *TODO: set the formatted image data here directly to avoid the copy mBuffer = new U8[data_size]; buffer->readAfter(channels.in(), NULL, mBuffer, data_size); mBufferSize += data_size; - if (data_size < mRequestedSize && - (mRequestedDiscard == 0 || mRequestedSize >= MAX_IMAGE_DATA_SIZE) ) + if (data_size < mRequestedSize) { // We requested whole image (by discard or by size,) so assume we got it mHaveAllData = TRUE; + mRequestedDiscard = 0; } else if (data_size > mRequestedSize) { From 202deea1a2480f5a18553f6e60e797a5f2582eb6 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Thu, 14 Oct 2010 20:22:23 +0200 Subject: [PATCH 046/239] More robust handling of http texture responses. Specifically allow for status 416 (unsatisfiable range) and scuessful responses without status 216 (i.e. whole file at once). This *should* allow this to work on different servers, as long as they comply with RFC 2616 WRT range requests. --- linden/indra/newview/lltexturefetch.cpp | 97 +++++++++++++++++-------- 1 file changed, 68 insertions(+), 29 deletions(-) diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index bf97584e7..80e3bfc19 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -157,7 +157,7 @@ class LLTextureFetchWorker : public LLWorkerClass void callbackHttpGet(const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer, - bool last_block, bool success); + bool partial, bool unsatisfiable, bool success); void callbackCacheRead(bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal); void callbackCacheWrite(bool success); @@ -324,6 +324,7 @@ class HTTPGetResponder : public LLCurl::Responder { bool success = false; bool partial = false; + bool unsatisfiable = false; if (200 <= status && status < 300) { success = true; @@ -332,18 +333,19 @@ class HTTPGetResponder : public LLCurl::Responder partial = true; } } - else + else if (status == HTTP_REQUESTED_RANGE_NOT_SATISFIABLE) { - worker->setGetStatus(status, reason); -// llwarns << status << ": " << reason << llendl; + LL_DEBUGS("TextureFetch") << "Request was an unsatisfiable range: mRequestedSize=" << mRequestedSize << " mOffset=" << mOffset << " for: " << mID << LL_ENDL; + unsatisfiable = true; } + if (!success) { worker->setGetStatus(status, reason); // llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl; } mFetcher->removeFromHTTPQueue(mID); - worker->callbackHttpGet(channels, buffer, partial, success); + worker->callbackHttpGet(channels, buffer, partial, unsatisfiable, success); } else { @@ -1301,7 +1303,9 @@ bool LLTextureFetchWorker::processSimulatorPackets() void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer, - bool last_block, bool success) + bool partial, + bool unsatisfiable, + bool success) { LLMutexLock lock(&mWorkMutex); @@ -1316,56 +1320,91 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, llwarns << "Duplicate callback for " << mID.asString() << llendl; return; // ignore duplicate callback } + + S32 data_size = 0; if (success) { // get length of stream: - S32 data_size = buffer->countAfter(channels.in(), NULL); + data_size = buffer->countAfter(channels.in(), NULL); gImageList.sTextureBits += data_size * 8; // Approximate - does not include header bits LL_DEBUGS("TextureFetch") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << " mRequestedSize: " << mRequestedSize << LL_ENDL; + if (data_size > 0) { - // *TODO: set the formatted image data here directly to avoid the copy - mBuffer = new U8[data_size]; - buffer->readAfter(channels.in(), NULL, mBuffer, data_size); - mBufferSize += data_size; - if (data_size < mRequestedSize) + bool clean_data = false; + bool done = false; + if (!partial) { - // We requested whole image (by discard or by size,) so assume we got it - mHaveAllData = TRUE; - mRequestedDiscard = 0; + // we got the whole image in one go + done = true; + clean_data = true; + } + else if (data_size < mRequestedSize) + { + // we have the whole image + done = true; + } + else if (data_size == mRequestedSize) + { + if (mRequestedDiscard <= 0) + { + done = true; + } + else + { + // this is the normal case where we get the data we requested, + // but still need to request more data. + } } else if (data_size > mRequestedSize) { // *TODO: This shouldn't be happening any more llwarns << "data_size = " << data_size << " > requested: " << mRequestedSize << llendl; - mHaveAllData = TRUE; + done = true; + clean_data = true; llassert_always(mDecodeHandle == 0); - mFormattedImage = NULL; // discard any previous data we had - mBufferSize = data_size; } - mRequestedSize = data_size; - } - else - { - // We requested data but received none (and no error), - if (mFormattedImage.notNull() && mFormattedImage->getDataSize() > 0) + + if (clean_data) { - // but have earlier data, so presumably we have it all. - mRequestedSize = 0; - mHaveAllData = TRUE; + resetFormattedData(); // discard any previous data we had + llassert(mBufferSize == 0); } - else + if (done) { - mRequestedSize = -1; // treat this fetch as if it failed. + mHaveAllData = TRUE; + mRequestedDiscard = 0; } + + // *TODO: set the formatted image data here directly to avoid the copy + mBuffer = new U8[data_size]; + buffer->readAfter(channels.in(), NULL, mBuffer, data_size); + mBufferSize += data_size; + mRequestedSize = data_size; + } + } + + if ((success && (data_size == 0)) || unsatisfiable) + { + if (mFormattedImage.notNull() && mFormattedImage->getDataSize() > 0) + { + // we already have some data, so we'll assume we have it all + mRequestedSize = 0; + mRequestedDiscard = 0; + mHaveAllData = TRUE; + } + else + { + mRequestedSize = -1; // treat this fetch as if it failed. } } else { mRequestedSize = -1; // error } + mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); } From 4d9f3db24601091947611aa20efbb8432e4f2aa7 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Thu, 14 Oct 2010 20:34:04 +0200 Subject: [PATCH 047/239] Work around for buggy range responses in OpenSim Ugly work around for http://opensimulator.org/mantis/view.php?id=5081 by adding 1 to the http request range when on affected versions, and always requesting ranges that start with 0 (viewer2 style). --- linden/indra/newview/lltexturefetch.cpp | 53 ++++++++++++++++++++++++- linden/indra/newview/lltexturefetch.h | 2 + 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index 80e3bfc19..bd1812e0c 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -871,6 +871,16 @@ bool LLTextureFetchWorker::doWork(S32 param) return false; } } + + // *TODO: remove this hack when not needed anymore + S32 buggy_range_fudge = 0; + if (LLTextureFetch::hasBuggyHTTPRange()) + { + buggy_range_fudge = 1; + resetFormattedData(); // discard any previous data we had + cur_size = 0 ; + } + mRequestedSize = mDesiredSize; mRequestedDiscard = mDesiredDiscard; mRequestedSize -= cur_size; @@ -896,7 +906,7 @@ bool LLTextureFetchWorker::doWork(S32 param) // Will call callbackHttpGet when curl request completes std::vector<std::string> headers; headers.push_back("Accept: image/x-j2c"); - res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, + res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize + buggy_range_fudge, new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset)); } if (!res) @@ -2258,3 +2268,44 @@ void LLTextureFetch::dump() } } +// This tries to detect if the sim has this bug: +// http://opensimulator.org/mantis/view.php?id=5081 +// +// *TODO: This is a *HACK and may not work if the grid is heterogenous. +// Remove it once OpenSim versions in the wild are > 0.7.0.2! +#include "hippoGridManager.h" +#include <boost/regex.hpp> +//static +bool LLTextureFetch::hasBuggyHTTPRange() +{ + static std::string s_version; + static bool buggy = false; + if ((s_version != gLastVersionChannel) && !gLastVersionChannel.empty()) + { + s_version = gLastVersionChannel; + buggy = true; + if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_OPENSIM) + { + std::string ver_string; + try + { + const boost::regex re(".*OpenSim.*?([0-9.]+).+"); + ver_string = regex_replace(s_version, re, "\\1", boost::match_default); + } + catch(std::runtime_error) + { + ver_string = "0.0"; + } + LLStringUtil::replaceChar(ver_string, '.', '0'); + ver_string = "0." + ver_string; + F64 version = atof(ver_string.c_str()); + // we look for "0.6.8" < version < "0.7.0.3" + if ((version > 0.00608) && (version < 0.0070003)) + { + buggy = true; + llwarns << "Setting buggy http ranges mode for current sim, because we're on " << s_version << llendl; + } + } + } + return buggy; +} diff --git a/linden/indra/newview/lltexturefetch.h b/linden/indra/newview/lltexturefetch.h index 5eca0ba60..61f76bc1c 100644 --- a/linden/indra/newview/lltexturefetch.h +++ b/linden/indra/newview/lltexturefetch.h @@ -86,6 +86,8 @@ class LLTextureFetch : public LLWorkerThread LLTextureInfo* getTextureInfo() { return &mTextureInfo; } + static bool hasBuggyHTTPRange(); // *TODO: remove this *HACK once buggy OpenSim versions are gone + protected: void addToNetworkQueue(LLTextureFetchWorker* worker); void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); From 7b0ce8e12ac68bfc1eb7524a394aaf3a485b559b Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Fri, 15 Oct 2010 01:21:53 +0200 Subject: [PATCH 048/239] Fix typo in buggy OpenSim version detection. --- linden/indra/newview/lltexturefetch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index bd1812e0c..e307afff3 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -896,7 +896,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mGetReason.clear(); LL_DEBUGS("TextureFetch") << "HTTP GET: " << mID << " Offset: " << offset << " Bytes: " << mRequestedSize - << " Range: " << offset << "-" << offset+mRequestedSize-1 + << " Range: " << offset << "-" << offset+mRequestedSize-1+buggy_range_fudge << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << max_bandwidth << LL_ENDL; setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); @@ -2283,7 +2283,7 @@ bool LLTextureFetch::hasBuggyHTTPRange() if ((s_version != gLastVersionChannel) && !gLastVersionChannel.empty()) { s_version = gLastVersionChannel; - buggy = true; + buggy = false; if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_OPENSIM) { std::string ver_string; From 67f55bad571044535f1d8c3b3c3afb5078249fd3 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 15 Oct 2010 17:49:06 +0200 Subject: [PATCH 049/239] RED-595: Manual merge with weekly-webkit. Plus some white space fixes (TABs --> spaces) in install.xml. --- linden/doc/contributions.txt | 2 + linden/indra/cmake/FindLLQtWebkit.cmake | 62 +++++++++++++++++ linden/indra/cmake/WebKitLibPlugin.cmake | 38 ++++++----- linden/indra/llwindow/llwindow.h | 2 +- linden/indra/llwindow/llwindowsdl.cpp | 3 +- linden/indra/newview/linux_tools/wrapper.sh | 13 ++-- linden/indra/newview/llfloaterhtmlhelp.cpp | 2 +- linden/indra/newview/llmediactrl.cpp | 3 +- linden/indra/newview/llstartup.cpp | 4 -- linden/indra/newview/secondlife-i686.supp | 44 ------------ .../skins/default/xui/zh/mime_types.xml | 9 --- linden/indra/newview/viewer_manifest.py | 6 +- linden/install.xml | 68 ++++++++++--------- 13 files changed, 132 insertions(+), 124 deletions(-) create mode 100644 linden/indra/cmake/FindLLQtWebkit.cmake diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index 931794c4e..4d3f0177f 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -80,6 +80,7 @@ Aleric Inglewood RED-578 RED-579 RED-581 + RED-595 Alissa Sabre VWR-81 VWR-83 @@ -512,6 +513,7 @@ Robin Cornelius VWR-2488 VWR-9557 VWR-12838 + RED-595 Ryozu Kojima VWR-53 VWR-287 diff --git a/linden/indra/cmake/FindLLQtWebkit.cmake b/linden/indra/cmake/FindLLQtWebkit.cmake new file mode 100644 index 000000000..c747ec32a --- /dev/null +++ b/linden/indra/cmake/FindLLQtWebkit.cmake @@ -0,0 +1,62 @@ +# -*- cmake -*- + +# - Find llqtwebkit +# Find the llqtwebkit includes and library +# This module defines +# LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc. +# LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path. +# LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit. +# also defined, but not for general use are +# LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit. +# LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library. +# LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS}) +# before compiling code that includes llqtwebkit library files. + +# Try to use pkg-config first. +# This allows to have two different libllqtwebkit packages installed: +# one for viewer 2.x and one for viewer 1.x. +include(FindPkgConfig) +if (PKG_CONFIG_FOUND) + if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION) + set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED) + else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION) + set(_PACKAGE_ARGS libllqtwebkit) + endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION) + if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_LESS "2.8") + # As virtually nobody will have a pkg-config file for this, do this check always quiet. + # Unfortunately cmake 2.8 or higher is required for pkg_check_modules to have a 'QUIET'. + set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET) + endif () + pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS}) +endif (PKG_CONFIG_FOUND) +set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER}) + +find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS}) + +find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS}) + +if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND) # If pkg-config couldn't find it, pretend we don't have pkg-config. + set(LLQTWEBKIT_LIBRARIES llqtwebkit) + get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH) +endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND) + +# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND +# to TRUE if all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + LLQTWEBKIT + DEFAULT_MSG + LLQTWEBKIT_LIBRARY + LLQTWEBKIT_INCLUDE_DIR + LLQTWEBKIT_LIBRARIES + LLQTWEBKIT_LIBRARY_DIRS + ) + +mark_as_advanced( + LLQTWEBKIT_LIBRARY + LLQTWEBKIT_INCLUDE_DIR + LLQTWEBKIT_LIBRARIES + LLQTWEBKIT_LIBRARY_DIRS + LLQTWEBKIT_DEFINITIONS + ) + diff --git a/linden/indra/cmake/WebKitLibPlugin.cmake b/linden/indra/cmake/WebKitLibPlugin.cmake index 23958fedf..3eafe77d2 100644 --- a/linden/indra/cmake/WebKitLibPlugin.cmake +++ b/linden/indra/cmake/WebKitLibPlugin.cmake @@ -3,6 +3,7 @@ include(Linking) include(Prebuilt) if (STANDALONE) + find_package(LLQtWebkit REQUIRED QUIET) set(WEBKITLIBPLUGIN OFF CACHE BOOL "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") else (STANDALONE) @@ -31,25 +32,26 @@ if (WINDOWS) elseif (DARWIN) set(WEBKIT_PLUGIN_LIBRARIES optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - debug ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib + debug ${ARCH_PREBUILT_DIRS_DEBUG}/libllqtwebkit.dylib ) elseif (LINUX) - if (STANDALONE) - set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit) - else (STANDALONE) + if (STANDALONE) + set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY}) + else (STANDALONE) set(WEBKIT_PLUGIN_LIBRARIES - llqtwebkit - qgif - qjpeg - QtWebKit - QtOpenGL - QtNetwork - QtGui - QtCore - fontconfig - X11 - Xrender - GL - ) - endif (STANDALONE) + llqtwebkit + qgif + qjpeg + QtWebKit + QtOpenGL + QtNetwork + QtGui + QtCore + jpeg + fontconfig + X11 + Xrender + GL + ) + endif (STANDALONE) endif (WINDOWS) diff --git a/linden/indra/llwindow/llwindow.h b/linden/indra/llwindow/llwindow.h index 2e96294cf..5e93ab32d 100644 --- a/linden/indra/llwindow/llwindow.h +++ b/linden/indra/llwindow/llwindow.h @@ -196,7 +196,7 @@ class LLWindow // 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) +// return the platform-specific window reference we use to initialize llqtwebkitlib (HWND on Windows, WindowRef on the Mac, Gtk window on Linux) virtual void *getMediaWindow(); // control platform's Language Text Input mechanisms. diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp index fa53c84f2..16106af36 100644 --- a/linden/indra/llwindow/llwindowsdl.cpp +++ b/linden/indra/llwindow/llwindowsdl.cpp @@ -1606,6 +1606,7 @@ void LLWindowSDL::processMiscNativeEvents() // the locale to protect it, as exotic/non-C locales // causes our code lots of general critical weirdness // and crashness. (SL-35450) + // Note: It is unknown if this is still needed now that we use webkit. static std::string saved_locale; saved_locale = ll_safe_string(setlocale(LC_ALL, NULL)); @@ -2433,7 +2434,7 @@ void *LLWindowSDL::getPlatformWindow() return rtnw; } #endif // LL_GTK && LL_LLMOZLIB_ENABLED - // Unixoid mozilla really needs GTK. + llassert(false); // Do we even GET here at all? Note that LL_LLMOZLIB_ENABLED is never defined! return NULL; } diff --git a/linden/indra/newview/linux_tools/wrapper.sh b/linden/indra/newview/linux_tools/wrapper.sh index 8c47434c5..a43ebd5a4 100755 --- a/linden/indra/newview/linux_tools/wrapper.sh +++ b/linden/indra/newview/linux_tools/wrapper.sh @@ -106,17 +106,16 @@ if [ -n "$LL_TCMALLOC" ]; then fi fi fi -BINARY_SYSTEM=$(expr match "$(file -b /bin/uname)" '\(.*executable\)') -BINARY_VIEWER=$(expr match "$(file -b ${RUN_PATH}/bin/do-not-directly-run-imprudence-bin)" '\(.*executable\)') -echo "viewer: $BINARY_VIEWER system: $BINARY_SYSTEM" -if ( [ "$BINARY_SYSTEM" == "ELF 64-bit LSB executable" ] && [ "$BINARY_VIEWER" == "ELF 64-bit LSB executable" ] ); then - export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib64:"`pwd`"/lib32:"`pwd`"/app_settings/mozilla-runtime-linux-x86_64:"${LD_LIBRARY_PATH}"' +export VIEWER_BINARY='do-not-directly-run-imprudence-bin' +BINARY_TYPE=$(expr match "$(file -b bin/$VIEWER_BINARY)" '\(.*executable\)') +if [ "${BINARY_TYPE}" == "ELF 64-bit LSB executable" ]; then + export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib64:"`pwd`"/lib32:"${LD_LIBRARY_PATH}"' else - export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-linux-i686:"${LD_LIBRARY_PATH}"' + export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"${LD_LIBRARY_PATH}"' fi -export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-imprudence-bin' +export SL_CMD='$LL_WRAPPER bin/$VIEWER_BINARY' export SL_OPT="`cat gridargs.dat` $@" # Run the program diff --git a/linden/indra/newview/llfloaterhtmlhelp.cpp b/linden/indra/newview/llfloaterhtmlhelp.cpp index 17774030d..1ec964b36 100644 --- a/linden/indra/newview/llfloaterhtmlhelp.cpp +++ b/linden/indra/newview/llfloaterhtmlhelp.cpp @@ -534,7 +534,7 @@ void LLFloaterHtmlHelp::onStatusTextChange( const EventType& eventIn ) // void LLFloaterHtmlHelp::onLocationChange( const EventType& eventIn ) { - llinfos << "MOZ> Location changed to " << eventIn.getStringValue() << llendl; + llinfos << "WEB> Location changed to " << eventIn.getStringValue() << llendl; mCurrentUrl = std::string( eventIn.getStringValue() ); } diff --git a/linden/indra/newview/llmediactrl.cpp b/linden/indra/newview/llmediactrl.cpp index 153059897..c3bcf8516 100644 --- a/linden/indra/newview/llmediactrl.cpp +++ b/linden/indra/newview/llmediactrl.cpp @@ -199,8 +199,9 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) { mMediaSource->mouseUp(x, y); - // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, + // *HACK: media_plugin_webkit automatically takes focus on mouseup, // in addition to the onFocusReceived() call below. Undo this. JC + // RED-595: Is this really still the case for webkit? if (!mTakeFocusOnClick) { mMediaSource->focus(false); diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index bd227721f..7bd5fff21 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -199,10 +199,6 @@ #include <Security/Security.h> #endif -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED - #if LL_WINDOWS #include "llwindebug.h" #include "lldxhardware.h" diff --git a/linden/indra/newview/secondlife-i686.supp b/linden/indra/newview/secondlife-i686.supp index 43d448346..d70cda3b8 100644 --- a/linden/indra/newview/secondlife-i686.supp +++ b/linden/indra/newview/secondlife-i686.supp @@ -41,50 +41,6 @@ # - After you build the viewer, replace the stripped # do-not-directly-run-secondlife-bin binary with an unstripped copy. -# Mozilla noise. - -{ - Cond:mozilla-runtime/*.so - Memcheck:Cond - obj:*/mozilla-runtime-*/*.so -} - -{ - Value4:mozilla-runtime/*.so - Memcheck:Value4 - obj:*/mozilla-runtime-*/*.so -} - -{ - Cond:mozilla-runtime/*/*.so - Memcheck:Cond - obj:*/mozilla-runtime-*/*/*.so -} - -{ - Value4:mozilla-runtime/*/*.so - Memcheck:Value4 - obj:*/mozilla-runtime-*/*/*.so -} - -{ - Cond:mozilla-runtime/libmozjs.so - Memcheck:Cond - obj:*/libmozjs.so -} - -{ - Cond:mozilla-runtime/libxul - Memcheck:Cond - obj:*/libxul.so -} - -{ - Value4:mozilla-runtime/libxul - Memcheck:Value4 - obj:*/libxul.so -} - # libcurl badness. { diff --git a/linden/indra/newview/skins/default/xui/zh/mime_types.xml b/linden/indra/newview/skins/default/xui/zh/mime_types.xml index fc5fae414..0cc6f2f23 100644 --- a/linden/indra/newview/skins/default/xui/zh/mime_types.xml +++ b/linden/indra/newview/skins/default/xui/zh/mime_types.xml @@ -1,14 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <mimetypes name="default"> - <defaultlabel> - (未知) - </defaultlabel> - <defaultwidget> - æ—  - </defaultwidget> - <defaultimpl> - LLMediaImplLLMozLib - </defaultimpl> <widgetset name="web"> <label name="web_label"> 网页内容 diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 314cb65e8..143d946fb 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -949,7 +949,6 @@ def construct(self): super(Linux_i686Manifest, self).construct() self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") - if (not self.standalone()) and self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"): self.path("libapr-1.so.0") self.path("libaprutil-1.so.0") @@ -1076,9 +1075,6 @@ def construct(self): self.path("featuretable_linux.txt") #self.path("secondlife-x86_64.supp") - if not self.standalone(): - self.path("app_settings/mozilla-runtime-linux-x86_64") - if (not self.standalone()) and self.prefix("../../libraries/x86_64-linux/lib_release_client", dst="lib64"): self.path("libapr-1.so.0") self.path("libaprutil-1.so.0") @@ -1090,7 +1086,7 @@ def construct(self): self.path("libuuid.so", "libuuid.so.1") self.path("libSDL-1.2.so.0") self.path("libELFIO.so") - self.path("libjpeg.so.7") + self.path("libjpeg.so.62") self.path("libpng12.so.0") self.path("libopenjpeg.so.2") self.path("libxml2.so.2") diff --git a/linden/install.xml b/linden/install.xml index 0c20157c2..b1efd11f6 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -74,13 +74,13 @@ <key>url</key> <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/SDL-1.2.5-linux-i686-gcc-4.1-20080915.tar.bz2</uri> </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>214fe53a11b3cdef115d36cb95aae185</string> - <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/SDL-1.2.12-linux64-20091230.tar.bz2</uri> - </map> + <key>linux64</key> + <map> + <key>md5sum</key> + <string>214fe53a11b3cdef115d36cb95aae185</string> + <key>url</key> + <uri>http://imprudenceviewer.org/download/libs/SDL-1.2.12-linux64-20091230.tar.bz2</uri> + </map> <key>windows</key> <map> <key>md5sum</key> @@ -295,7 +295,7 @@ </map> </map> </map> - <key>dbghelp</key> + <key>dbghelp</key> <map> <key>copyright</key> <string>Copyright Microsoft Corporation</string> @@ -327,9 +327,9 @@ <key>linux</key> <map> <key>md5sum</key> - <string>eb25444142d4102b0ce1b7ffaadb071e</string> + <string>bfcff12c0d5cef53aa2e04fa53299b23</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/dbusglib-linux-20080707.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/dbusglib-linux-20101012.tar.bz2</uri> </map> <key>linux64</key> <map> @@ -816,9 +816,9 @@ cairo: Copyright © 2002 University of Southern California, Copyright © 2005 Re <key>linux64</key> <map> <key>md5sum</key> - <string>64e7fa98568ef52b3b9d4a18b3515090</string> + <string>8b5f413bdefec7cfe3d9ad2d69986bdc</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/jpeglib-7-linux64-20091230.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/jpeglib-6b-linux64-20101012.tar.bz2</uri> </map> <key>windows</key> <map> @@ -1057,23 +1057,30 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <key>darwin</key> <map> <key>md5sum</key> - <string>becffca6bd8dcb239de284ea2a8b485b</string> + <string>34d9e4c93678a422cf80521bf0cd7628</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6+cookies-darwin-20100617.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100914.tar.bz2</uri> </map> <key>linux</key> <map> <key>md5sum</key> - <string>414d72dd59e3d83c96f0e1531360792e</string> + <string>5d743c93b970abe685b185de83001a6e</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20100618.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-qt4.6-20100923.tar.bz2</uri> + </map> + <key>linux64</key> + <map> + <key>md5sum</key> + <string>863f7b31556b1d368651f85457f4e46d</string> + <key>url</key> + <uri>http://github.com/downloads/AlericInglewood/imprudence/llqtwebkit-linux64-20101012.1.tar.bz2</uri> </map> <key>windows</key> <map> <key>md5sum</key> - <string>df1bdd683128e060d60e435f65d8f7e8</string> + <string>4b8412833c00f8cdaba26808f0ddb404</string> <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100617.tar.bz2</uri> + <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100916.tar.bz2</uri> </map> </map> </map> @@ -1636,7 +1643,7 @@ Copyright (C) 2004-2005 Vladimir Berezniker @ http://public.xdi.org/=vmpn <key>url</key> <string>http://www.xfree86.org/4.4.0/LICENSE9.html#sgi</string> </map> - <key>MSDTW</key> + <key>MSDTW</key> <map> <key>text</key> <string>MICROSOFT SOFTWARE LICENSE TERMS @@ -1843,12 +1850,12 @@ Cass Everitt - cass@r3.nu <key>text</key> <string>on file</string> </map> - <key>hunspell</key> + <key>hunspell</key> <map> <key>url</key> <string>http://www.gnu.org/licenses/gpl.html</string> </map> - <key>hunspell-dictionaries</key> + <key>hunspell-dictionaries</key> <map> <key>url</key> <string>http://www.gnu.org/licenses/gpl.html</string> @@ -1864,13 +1871,13 @@ Cass Everitt - cass@r3.nu <key>text</key> <string>http://nyctergatis.com/jpeglib/</string> </map> - <key>jsoncpp</key> - <map> - <key>text</key> - <string>The json-cpp library and this documentation are in Public Domain. Retrieved from http://jsoncpp.sourceforge.net/ on 2009-09-04.</string> - <key>url</key> - <string>http://jsoncpp.sourceforge.net</string> - </map> + <key>jsoncpp</key> + <map> + <key>text</key> + <string>The json-cpp library and this documentation are in Public Domain. Retrieved from http://jsoncpp.sourceforge.net/ on 2009-09-04.</string> + <key>url</key> + <string>http://jsoncpp.sourceforge.net</string> + </map> <key>kdu</key> <map> <key>text</key> @@ -1911,11 +1918,6 @@ Cass Everitt - cass@r3.nu <key>text</key> <string>Multiple licenses. See package contents for details.</string> </map> - <key>mozillaPL</key> - <map> - <key>url</key> - <string>http://www.mozilla.org/MPL/MPL-1.1.html</string> - </map> <key>xiph-bsd</key> <map> <key>url</key> From 0bf2f0afa632a379a32f08cf9b3e77f76c3a13da Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 15 Oct 2010 17:58:59 +0200 Subject: [PATCH 050/239] Add missing semi-colon. --- linden/indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index b0b8a94e4..c4c3f0795 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp @@ -4274,7 +4274,7 @@ LLFaceID LLVolume::generateFaceMask() } break; default: - llerrs << "Unknown profile!" << llendl + llerrs << "Unknown profile!" << llendl; break; } From 8a62086cb0a9a8ae746bffa57e785cc4ca5be3a5 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 15 Oct 2010 18:01:07 +0200 Subject: [PATCH 051/239] Comment out code to make it compile at all (with the latest llqtwebkit). --- linden/indra/llplugin/llpluginclassmedia.cpp | 4 ++++ linden/indra/media_plugins/webkit/media_plugin_webkit.cpp | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp index 86645248b..9f14920ff 100755 --- a/linden/indra/llplugin/llpluginclassmedia.cpp +++ b/linden/indra/llplugin/llpluginclassmedia.cpp @@ -724,6 +724,9 @@ void LLPluginClassMedia::setJavascriptEnabled(const bool enabled) LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) { + llassert(false); + return LLPluginClassMedia::TARGET_OTHER; +#if 0 // convert a LinkTargetType value from llqtwebkit to an ETargetType // so that we don't expose the llqtwebkit header in viewer code switch (target_type) @@ -740,6 +743,7 @@ LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) default: return LLPluginClassMedia::TARGET_OTHER; } +#endif } /* virtual */ diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index ebf64f865..5058e0ac6 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -323,8 +323,13 @@ class MediaPluginWebKit : // append details to agent string LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); +#if 0 // FIXME (webkit_plugins): this doesn't compile with latest version of llqtwebkit + // error: ‘class LLQtWebKit’ has no member named ‘setWindowOpenBehavior’ + // error: ‘WOB_SIMULATE_BLANK_HREF_CLICK’ is not a member of ‘LLQtWebKit’ + // Set up window open behavior LLQtWebKit::getInstance()->setWindowOpenBehavior(mBrowserWindowId, LLQtWebKit::WOB_SIMULATE_BLANK_HREF_CLICK); +#endif #if !LL_QTWEBKIT_USES_PIXMAPS // don't flip bitmap @@ -518,7 +523,9 @@ class MediaPluginWebKit : LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); message.setValue("uri", event.getStringValue()); message.setValue("target", event.getStringValue2()); +#if 0 // FIXME (webkit_plugins): error: ‘const class LLEmbeddedBrowserWindowEvent’ has no member named ‘getLinkType’ message.setValueU32("target_type", event.getLinkType()); +#endif sendMessage(message); } From b2d616b732943817b7e705fc8f6c4be9beee3def Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 15 Oct 2010 18:02:40 +0200 Subject: [PATCH 052/239] Rename LLRect::isNull to LLRect::isEmpty (a random thing I picked up from snowglobe 2.x). --- linden/indra/llmath/llrect.h | 4 ++-- linden/indra/llplugin/llpluginclassmedia.cpp | 4 ++-- linden/indra/llui/llpanel.cpp | 2 +- linden/indra/llui/llview.cpp | 4 ++-- linden/indra/newview/llviewerwindow.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/linden/indra/llmath/llrect.h b/linden/indra/llmath/llrect.h index 9eb58dbbe..33070c40a 100644 --- a/linden/indra/llmath/llrect.h +++ b/linden/indra/llmath/llrect.h @@ -229,14 +229,14 @@ template <class Type> class LLRectBase return mLeft <= mRight && mBottom <= mTop; } - bool isNull() const + bool isEmpty() const { return mLeft == mRight || mBottom == mTop; } bool notNull() const { - return !isNull(); + return !isEmpty(); } LLRectBase& unionWith(const LLRectBase &other) diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp index 9f14920ff..5dc0c4722 100755 --- a/linden/indra/llplugin/llpluginclassmedia.cpp +++ b/linden/indra/llplugin/llpluginclassmedia.cpp @@ -393,7 +393,7 @@ bool LLPluginClassMedia::textureValid(void) bool LLPluginClassMedia::getDirty(LLRect *dirty_rect) { - bool result = !mDirtyRect.isNull(); + bool result = !mDirtyRect.isEmpty(); if(dirty_rect != NULL) { @@ -793,7 +793,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) newDirtyRect.mBottom = temp; } - if(mDirtyRect.isNull()) + if(mDirtyRect.isEmpty()) { mDirtyRect = newDirtyRect; } diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index 26137d7b1..07e78eda9 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp @@ -1171,7 +1171,7 @@ void LLLayoutStack::draw() LLLocalClipRect clip(clip_rect); // only force drawing invisible children if visible amount is non-zero - drawChild(panelp, 0, 0, !clip_rect.isNull()); + drawChild(panelp, 0, 0, !clip_rect.isEmpty()); } } diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index 1f7669613..d4eda8f25 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp @@ -1542,7 +1542,7 @@ void LLView::updateBoundingRect() LLRect child_bounding_rect = childp->getBoundingRect(); - if (local_bounding_rect.isNull()) + if (local_bounding_rect.isEmpty()) { // start out with bounding rect equal to first visible child's bounding rect local_bounding_rect = child_bounding_rect; @@ -1550,7 +1550,7 @@ void LLView::updateBoundingRect() else { // accumulate non-null children rectangles - if (!child_bounding_rect.isNull()) + if (!child_bounding_rect.isEmpty()) { local_bounding_rect.unionWith(child_bounding_rect); } diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index f4b738f0f..5cd730a52 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -2817,7 +2817,7 @@ BOOL LLViewerWindow::handlePerFrameHover() // snap floaters to top of chat bar/button strip LLView* chatbar_and_buttons = gOverlayBar->getChild<LLView>("chatbar_and_buttons", TRUE); // find top of chatbar and state buttons, if either are visible - if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull()) + if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isEmpty()) { // convert top/left corner of chatbar/buttons container to gFloaterView-relative coordinates S32 top, left; From f99462872fd9d54658f8702929583bd4a607b21a Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 16 Oct 2010 03:11:19 +0200 Subject: [PATCH 053/239] Fix the fix - bad logic for failed http requests --- linden/indra/newview/lltexturefetch.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index e307afff3..a39e2dfca 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -1395,6 +1395,10 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, mRequestedSize = data_size; } } + else + { + mRequestedSize = -1; // error + } if ((success && (data_size == 0)) || unsatisfiable) { @@ -1410,11 +1414,7 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, mRequestedSize = -1; // treat this fetch as if it failed. } } - else - { - mRequestedSize = -1; // error - } - + mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); } From ee23c250612b9b2da34472c47c740746232c6104 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 16 Oct 2010 03:16:14 +0200 Subject: [PATCH 054/239] Port of SNOW-802: Use UDP for baked textures. Port of SNOW-802 from SG1. Originally ported by Robin cornelius from SG 2.1. Also added a paramter can_use_http to the LLTextureFetchWorker constructor, to avoid messing with locks. --- linden/indra/newview/lltexturefetch.cpp | 12 +++++++----- linden/indra/newview/lltexturefetch.h | 2 +- linden/indra/newview/llviewerimage.cpp | 6 ++++-- linden/indra/newview/llviewerimage.h | 4 ++++ linden/indra/newview/llvoavatar.cpp | 1 + 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index a39e2dfca..f63deb89d 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -176,7 +176,7 @@ class LLTextureFetchWorker : public LLWorkerClass LLTextureFetchWorker(LLTextureFetch* fetcher, const LLUUID& id, const LLHost& host, F32 priority, S32 discard, S32 size); LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host, - F32 priority, S32 discard, S32 size); + F32 priority, S32 discard, S32 size, bool can_use_http); private: /*virtual*/ void startWork(S32 param); // called from addWork() (MAIN THREAD) @@ -390,7 +390,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, const LLHost& host, // Simulator host F32 priority, // Priority S32 discard, // Desired discard - S32 size) // Desired size + S32 size, // Desired size + bool can_use_http) // Try HTTP first : LLWorkerClass(fetcher, "TextureFetch"), mState(INIT), mWriteToCacheState(NOT_WRITE), @@ -422,7 +423,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mNeedsAux(FALSE), mHaveAllData(FALSE), mInLocalCache(FALSE), - mCanUseHTTP(true), + mCanUseHTTP(can_use_http), mHTTPFailCount(0), mRetryAttempt(0), mActiveCount(0), @@ -1556,7 +1557,7 @@ LLTextureFetch::~LLTextureFetch() } bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, - S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux) + S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { if (mDebugPause) { @@ -1618,6 +1619,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con worker->lockWorkMutex(); worker->setImagePriority(priority); worker->setDesiredDiscard(desired_discard, desired_size); + worker->setCanUseHTTP(can_use_http); worker->unlockWorkMutex(); if (!worker->haveWork()) { @@ -1633,7 +1635,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con } else { - worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size); + worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size, can_use_http); mRequestMap[id] = worker; } worker->mActiveCount++; diff --git a/linden/indra/newview/lltexturefetch.h b/linden/indra/newview/lltexturefetch.h index 61f76bc1c..5fa2d1c17 100644 --- a/linden/indra/newview/lltexturefetch.h +++ b/linden/indra/newview/lltexturefetch.h @@ -60,7 +60,7 @@ class LLTextureFetch : public LLWorkerThread /*virtual*/ S32 update(U32 max_time_ms); bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, - S32 w, S32 h, S32 c, S32 discard, bool needs_aux); + S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool use_http); void deleteRequest(const LLUUID& id, bool cancel); bool getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux); diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index 400fb2f1f..4f23a0517 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp @@ -346,6 +346,8 @@ void LLViewerImage::init(bool firstinit) mForceToSaveRawImage = FALSE ; mSavedRawDiscardLevel = -1 ; mDesiredSavedRawDiscardLevel = -1 ; + + mCanUseHTTP = true; //default on if cap/settings allows us } // virtual @@ -1213,7 +1215,7 @@ bool LLViewerImage::updateFetch() // bypass texturefetch directly by pulling from LLTextureCache bool fetch_request_created = false; fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority, - w, h, c, desired_discard, needsAux()); + w, h, c, desired_discard, needsAux(), mCanUseHTTP); if (fetch_request_created) { @@ -1292,7 +1294,7 @@ BOOL LLViewerImage::forceFetch() c = getComponents(); } fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), maxDecodePriority(), - w, h, c, desired_discard, needsAux()); + w, h, c, desired_discard, needsAux(), mCanUseHTTP); if (fetch_request_created) { diff --git a/linden/indra/newview/llviewerimage.h b/linden/indra/newview/llviewerimage.h index c82b68bae..3bee51cf1 100644 --- a/linden/indra/newview/llviewerimage.h +++ b/linden/indra/newview/llviewerimage.h @@ -314,6 +314,8 @@ class LLViewerImage : public LLImageGL void addFace(LLFace* facep) ; void removeFace(LLFace* facep) ; + void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}; + friend class LocalBitmap; // tag: vaa emerald local_asset_browser private: @@ -418,6 +420,8 @@ class LLViewerImage : public LLImageGL typedef std::list<LLFace*> ll_face_list_t ; ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture + bool mCanUseHTTP; // can this image be fetched by http + public: static const U32 sCurrentFileVersion; // Default textures diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index d2aa3d8ee..7bbaf489c 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -5196,6 +5196,7 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerImage* imagep, void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level) { + imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures. mMaxPixelArea = llmax(pixel_area, mMaxPixelArea); mMinPixelArea = llmin(pixel_area, mMinPixelArea); imagep->addTextureStats(pixel_area / texel_area_ratio); From e6148fcb46922a570679ff12edbc364873dc54ac Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sat, 16 Oct 2010 13:36:40 +0200 Subject: [PATCH 055/239] Fix windows mime types and gstreamer plugin name. --- .../skins/default/xui/en-us/mime_types.xml | 478 ------------------ .../default/xui/en-us/mime_types_windows.xml | 14 +- linden/indra/newview/viewer_manifest.py | 2 +- 3 files changed, 8 insertions(+), 486 deletions(-) delete mode 100644 linden/indra/newview/skins/default/xui/en-us/mime_types.xml diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types.xml deleted file mode 100644 index 360438a51..000000000 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types.xml +++ /dev/null @@ -1,478 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<mimetypes name="default"> - <defaultlabel> - (Unknown) - </defaultlabel> - <defaultwidget> - none - </defaultwidget> - <defaultimpl> - media_plugin_webkit - </defaultimpl> - <widgetset name="web"> - <label name="web_label"> - Web Content - </label> - <icon> - icn_media_web.tga - </icon> - <default_type> - text/html - </default_type> - <tooltip name="web_tooltip"> - This location has Web content - </tooltip> - <playtip name="web_playtip"> - Show Web content - </playtip> - <allow_resize> - true - </allow_resize> - <allow_looping> - false - </allow_looping> - </widgetset> - <widgetset name="movie"> - <label name="movie_label"> - Movie - </label> - <default_type> - video/* - </default_type> - <icon> - icn_media_movie.tga - </icon> - <tooltip name="movie_tooltip"> - There is a movie to play here - </tooltip> - <playtip name="movie_playtip"> - Play movie - </playtip> - <allow_resize> - false - </allow_resize> - <allow_looping> - true - </allow_looping> - </widgetset> - <widgetset name="image"> - <label name="image_label"> - Image - </label> - <icon> - icn_media_web.tga - </icon> - <default_type> - image/* - </default_type> - <tooltip name="image_tooltip"> - There is an image at this location - </tooltip> - <playtip name="image_playtip"> - View this location's image - </playtip> - <allow_resize> - false - </allow_resize> - <allow_looping> - false - </allow_looping> - </widgetset> - <widgetset name="audio"> - <label name="audio_label"> - Audio - </label> - <icon> - icn_media_web.tga - </icon> - <default_type> - audio/* - </default_type> - <tooltip name="audio_tooltip"> - There is audio at this location - </tooltip> - <playtip name="audio_playtip"> - Play this location's audio - </playtip> - <allow_resize> - false - </allow_resize> - <allow_looping> - true - </allow_looping> - </widgetset> - <scheme name="rtsp"> - <label name="rtsp_label"> - Real Time Streaming - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </scheme> - <mimetype name="blank"> - <label name="blank_label"> - - None - - </label> - <widgettype> - none - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="none/none"> - <label name="none/none_label"> - - None - - </label> - <widgettype> - none - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="audio/*"> - <label name="audio2_label"> - Audio - </label> - <widgettype> - audio - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="video/*"> - <label name="video2_label"> - Video - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="image/*"> - <label name="image2_label"> - Image - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> - <label name="vnd.secondlife.qt.legacy_label"> - Movie (gstreamer) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="application/javascript"> - <label name="application/javascript_label"> - Javascript - </label> - <widgettype> - web - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="application/ogg"> - <label name="application/ogg_label"> - Ogg Audio/Video - </label> - <widgettype> - audio - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="application/pdf"> - <label name="application/pdf_label"> - PDF Document - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="application/postscript"> - <label name="application/postscript_label"> - Postscript Document - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="application/rtf"> - <label name="application/rtf_label"> - Rich Text (RTF) - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="application/smil"> - <label name="application/smil_label"> - Synchronized Multimedia Integration Language (SMIL) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="application/xhtml+xml"> - <label name="application/xhtml+xml_label"> - Web Page (XHTML) - </label> - <widgettype> - web - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="application/x-director"> - <label name="application/x-director_label"> - Macromedia Director - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="audio/mid"> - <label name="audio/mid_label"> - Audio (MIDI) - </label> - <widgettype> - audio - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="audio/mpeg"> - <label name="audio/mpeg_label"> - Audio (MP3) - </label> - <widgettype> - audio - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="audio/x-aiff"> - <label name="audio/x-aiff_label"> - Audio (AIFF) - </label> - <widgettype> - audio - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="audio/x-wav"> - <label name="audio/x-wav_label"> - Audio (WAV) - </label> - <widgettype> - audio - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype menu="1" name="image/bmp"> - <label name="image/bmp_label"> - Image (BMP) - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="image/gif"> - <label name="image/gif_label"> - Image (GIF) - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="image/jpeg"> - <label name="image/jpeg_label"> - Image (JPEG) - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="image/png"> - <label name="image/png_label"> - Image (PNG) - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="image/svg+xml"> - <label name="image/svg+xml_label"> - Image (SVG) - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="image/tiff"> - <label name="image/tiff_label"> - Image (TIFF) - </label> - <widgettype> - image - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="text/html"> - <label name="text/html_label"> - Web Page - </label> - <widgettype> - web - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="text/plain"> - <label name="text/plain_label"> - Text - </label> - <widgettype> - text - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype name="text/xml"> - <label name="text/xml_label"> - XML - </label> - <widgettype> - text - </widgettype> - <impl> - media_plugin_webkit - </impl> - </mimetype> - <mimetype menu="1" name="video/mpeg"> - <label name="video/mpeg_label"> - Movie (MPEG) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="video/mp4"> - <label name="video/mp4_label"> - Movie (MP4) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype menu="1" name="video/gstreamer"> - <label name="video/gstreamer_label"> - Movie (gstreamer) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="video/x-ms-asf"> - <label name="video/x-ms-asf_label"> - Movie (Windows Media ASF) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype name="video/x-ms-wmv"> - <label name="video/x-ms-wmv_label"> - Movie (Windows Media WMV) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> - <mimetype menu="1" name="video/x-msvideo"> - <label name="video/x-msvideo_label"> - Movie (AVI) - </label> - <widgettype> - movie - </widgettype> - <impl> - media_plugin_gstreamer010 - </impl> - </mimetype> -</mimetypes> diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml index d4d47cb45..5ff3b19eb 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml @@ -274,7 +274,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer010 + media_plugin_gstreamer </impl> </mimetype> <mimetype menu="1" name="image/bmp"> @@ -384,7 +384,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer010010 + media_plugin_gstreamer </impl> </mimetype> <mimetype name="video/mp4"> @@ -395,7 +395,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer010010 + media_plugin_gstreamer </impl> </mimetype> <mimetype menu="1" name="video/gstreamer"> @@ -406,7 +406,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer010010 + media_plugin_gstreamer </impl> </mimetype> <mimetype name="video/x-ms-asf"> @@ -417,7 +417,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer010010 + media_plugin_gstreamer </impl> </mimetype> <mimetype name="video/x-ms-wmv"> @@ -428,7 +428,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer010010 + media_plugin_gstreamer </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> @@ -439,7 +439,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer010010 + media_plugin_gstreamer </impl> </mimetype> </mimetypes> diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 143d946fb..65e615c60 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -271,7 +271,7 @@ def construct(self): # Media plugins - Gstreamer if self.prefix(src='../media_plugins/gstreamer/%s' % self.args['configuration'], dst="llplugin"): - self.path("media_plugin_gstreamer010.dll") + self.path("media_plugin_gstreamer010.dll", "media_plugin_gstreamer.dll") self.end_prefix() # For WebKit/Qt plugin runtimes From 0297f5d55f2ba5975ed3869f387d404638aec88f Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 16 Oct 2010 16:03:31 +0200 Subject: [PATCH 056/239] More SNOW-802: disable http for bakes earlier. --- linden/indra/newview/llviewerimage.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index 4f23a0517..671a359ed 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp @@ -256,6 +256,10 @@ LLViewerImage::LLViewerImage(const LLUUID& id, const LLHost& host, BOOL usemipma { init(true); sImageCount++; + if (host != LLHost::invalid) + { + mCanUseHTTP = false; // this is a baked texture + } } LLViewerImage::LLViewerImage(const std::string& url, const LLUUID& id, BOOL usemipmaps) From fa2df9d763270260ab4170507784190ae9066113 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 17 Oct 2010 00:26:00 +0200 Subject: [PATCH 057/239] Add LLQTWEBKIT_INCLUDE_DIR to indra/llplugin/CMakeLists.txt Make it find llqtwebkit.h with --standalone. --- linden/indra/llplugin/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt index 8eead9453..73cd9a396 100644 --- a/linden/indra/llplugin/CMakeLists.txt +++ b/linden/indra/llplugin/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( ${LLRENDER_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} + ${LLQTWEBKIT_INCLUDE_DIR} ) set(llplugin_SOURCE_FILES @@ -83,4 +84,4 @@ add_subdirectory(slplugin) # LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES}" # ) # -# LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}") \ No newline at end of file +# LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}") From 13dc7326705ec9b8219bef3ee339de499626d237 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 17 Oct 2010 22:34:20 +0200 Subject: [PATCH 058/239] Find Qt4 with find_package on STANDALONE. If Qt is found in a non-standard place, you still have to set LD_LIBRARY_PATH yourself (to $QTDIR/lib) before running imprudence of course (or the webkit plugin will silently fail). --- linden/indra/cmake/WebKitLibPlugin.cmake | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/linden/indra/cmake/WebKitLibPlugin.cmake b/linden/indra/cmake/WebKitLibPlugin.cmake index 3eafe77d2..9c56838c2 100644 --- a/linden/indra/cmake/WebKitLibPlugin.cmake +++ b/linden/indra/cmake/WebKitLibPlugin.cmake @@ -3,6 +3,16 @@ include(Linking) include(Prebuilt) if (STANDALONE) + # The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny. + find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL REQUIRED) + include(${QT_USE_FILE}) + set(QTDIR $ENV{QTDIR}) + if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin") + message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; " + "Qt is found by looking for qmake in your PATH. " + "Please set your PATH such that 'qmake' is found in \$QTDIR/bin, " + "or unset QTDIR if the found Qt is correct.") + endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin") find_package(LLQtWebkit REQUIRED QUIET) set(WEBKITLIBPLUGIN OFF CACHE BOOL "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") @@ -36,7 +46,7 @@ elseif (DARWIN) ) elseif (LINUX) if (STANDALONE) - set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY}) + set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES}) else (STANDALONE) set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit From ccf5b667663b01c724014f19c28022498d1b3bb6 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sun, 17 Oct 2010 23:50:42 +0200 Subject: [PATCH 059/239] Ask for at least 512^2 pixels of local texture before bake Not sure this helps with non-baking, but it looked wrong. Also, only bind local texture before they are covered by a bake. --- linden/indra/newview/llvoavatar.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 7bbaf489c..9937ed973 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -5129,12 +5129,6 @@ void LLVOAvatar::updateTextures() if (texture_dict->mIsLocalTexture) { addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); - // SNOW-8 : temporary snowglobe1.0 fix for baked textures - if (render_avatar && !gGLManager.mIsDisabled ) - { - // bind the texture so that its boost level won't be slammed - gGL.getTexUnit(0)->bind(imagep); - } } else if (texture_dict->mIsBakedTexture) { @@ -5171,8 +5165,14 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerImage* imagep, F32 desired_pixels; if( mIsSelf ) { - desired_pixels = llmin(mPixelArea, (F32)TEX_IMAGE_AREA_SELF ); + desired_pixels = llmax(mPixelArea, (F32)TEX_IMAGE_AREA_SELF ); imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_AVATAR_SELF); + // SNOW-8 : temporary snowglobe1.0 fix for baked textures + if (render_avatar && !gGLManager.mIsDisabled ) + { + // bind the texture so that its boost level won't be slammed + gGL.getTexUnit(0)->bind(imagep); + } } else { From dab62a3fba7b332323131cd038642d006e57f47c Mon Sep 17 00:00:00 2001 From: elektrahesse <sl@ircsystem.net> Date: Mon, 18 Oct 2010 03:36:43 +0200 Subject: [PATCH 060/239] Changed default compile settings for Mac. Now SSE3 and SSE4 are enabled by default, gcc-4.2 is used and 10.5 SDK is auto selected. Build from commandline in Release mode now work perfectly (./develop.py -t Release build) without the need for Xcode at all. --- linden/indra/cmake/00-Common.cmake | 4 ++-- linden/indra/cmake/Variables.cmake | 16 +++++----------- linden/indra/develop.py | 2 +- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/linden/indra/cmake/00-Common.cmake b/linden/indra/cmake/00-Common.cmake index 032a3cf13..0e9007395 100644 --- a/linden/indra/cmake/00-Common.cmake +++ b/linden/indra/cmake/00-Common.cmake @@ -186,8 +186,8 @@ if (DARWIN) add_definitions(-DLL_DARWIN=1) set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch -msse3 -msse4.1 -msse4.2 -mssse3 -w") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch -msse3 -msse4.1 -msse4.2 -mssse3 -w") # NOTE: it's critical that the optimization flag is put in front. # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") diff --git a/linden/indra/cmake/Variables.cmake b/linden/indra/cmake/Variables.cmake index 5d4dffe19..8a06133d8 100644 --- a/linden/indra/cmake/Variables.cmake +++ b/linden/indra/cmake/Variables.cmake @@ -60,17 +60,11 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # set this dynamically from the build system now - # NOTE: wont have a distributable build unless you add this on the configure line with: # -DCMAKE_OSX_ARCHITECTURES:STRING='i386;ppc' - #set(CMAKE_OSX_ARCHITECTURES i386;ppc) - set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.4u.sdk) - if (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc") - set(ARCH universal) - else (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc") - if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc") - set(ARCH ppc) - else (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc") - set(ARCH i386) - endif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc") - endif (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc") + set(CMAKE_OSX_ARCHITECTURES i386) + set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk) + if (CMAKE_OSX_ARCHITECTURES MATCHES "i386") + set(ARCH i386) + endif (CMAKE_OSX_ARCHITECTURES MATCHES "i386") set(LL_ARCH ${ARCH}_darwin) set(LL_ARCH_DIR universal-darwin) endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") diff --git a/linden/indra/develop.py b/linden/indra/develop.py index 809ac7823..2ce9f91af 100755 --- a/linden/indra/develop.py +++ b/linden/indra/develop.py @@ -421,7 +421,7 @@ def cmake_commandline(self, src_dir, build_dir, opts, simple): type=self.build_type.upper() ) if self.unattended == 'ON': - args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386;ppc\'' + args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386\'' #if simple: # return 'cmake %(opts)s %(dir)r' % args return ('cmake -G %(generator)r ' From 18e79cb6f6bdb7ab4426869417ccb917990df410 Mon Sep 17 00:00:00 2001 From: elektrahesse <sl@ircsystem.net> Date: Mon, 18 Oct 2010 14:10:38 +0200 Subject: [PATCH 061/239] Updated the Info.plist file on Mac to reflect the actual build date of the last weekly. --- linden/indra/newview/Info-Imprudence.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/Info-Imprudence.plist b/linden/indra/newview/Info-Imprudence.plist index 419cacdc8..3fe2000ba 100644 --- a/linden/indra/newview/Info-Imprudence.plist +++ b/linden/indra/newview/Info-Imprudence.plist @@ -32,7 +32,7 @@ </dict> </array> <key>CFBundleVersion</key> - <string>Experimental 2010.09.04</string> + <string>Experimental 2010.10.17</string> <key>CSResourcesFileMapped</key> <true/> </dict> From beb04d00cb01f3c81dcaef69751d526a38ce29e5 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Mon, 18 Oct 2010 23:39:16 +0200 Subject: [PATCH 062/239] Forgot QtWebKit and Qt plugins in last commit. Standalone now works (I have no idea why it worked before, since obviously I tested it before committing the previous commit). --- linden/indra/cmake/WebKitLibPlugin.cmake | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/linden/indra/cmake/WebKitLibPlugin.cmake b/linden/indra/cmake/WebKitLibPlugin.cmake index 9c56838c2..a4befa495 100644 --- a/linden/indra/cmake/WebKitLibPlugin.cmake +++ b/linden/indra/cmake/WebKitLibPlugin.cmake @@ -4,7 +4,7 @@ include(Prebuilt) if (STANDALONE) # The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny. - find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL REQUIRED) + find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED) include(${QT_USE_FILE}) set(QTDIR $ENV{QTDIR}) if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin") @@ -14,6 +14,18 @@ if (STANDALONE) "or unset QTDIR if the found Qt is correct.") endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin") find_package(LLQtWebkit REQUIRED QUIET) + # Add the plugins. + set(QT_PLUGIN_LIBRARIES) + foreach(qlibname qgif qjpeg) + find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH) + if (QT_PLUGIN_${qlibname}) + list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}}) + else (QT_PLUGIN_${qtlibname}) + message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!") + endif (QT_PLUGIN_${qlibname}) + endforeach(qlibname) + # qjpeg depends on libjpeg + list(APPEND QT_PLUGIN_LIBRARIES jpeg) set(WEBKITLIBPLUGIN OFF CACHE BOOL "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") else (STANDALONE) @@ -46,7 +58,7 @@ elseif (DARWIN) ) elseif (LINUX) if (STANDALONE) - set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES}) + set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES}) else (STANDALONE) set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit From cea604cda04d783b989498055102674170864b5c Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 18 Oct 2010 15:55:50 -0700 Subject: [PATCH 063/239] Fixed the Vivox license prompt appearing when connecting to non-SL grids on startup --- linden/indra/newview/llstartup.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 08d6d3fb2..d5adc119a 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -1073,10 +1073,11 @@ bool idle_startup() // color init must be after saved settings loaded init_colors(); - if (gSavedSettings.getBOOL("VivoxLicenseAccepted")) + if (gSavedSettings.getBOOL("VivoxLicenseAccepted") || gHippoGridManager->getConnectedGrid()->isSecondLife()) { // skipping over STATE_LOGIN_VOICE_LICENSE since we don't need it // skipping over STATE_UPDATE_CHECK because that just waits for input + // We don't do this on non-SL grids either LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); } else From 6f52903897ccb2ddd88049cd3137cf554ef45621 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 19 Oct 2010 21:14:03 +0200 Subject: [PATCH 064/239] Sync LLViewerMediaImpl::newSourceFromMediaType with SG2 Also renamed CookiesEnabled to BrowswerCookiesEnabled. Added BrowserJavascriptEnabled, BrowserPluginsEnabled and PluginAttachDebuggerToPlugins. --- .../indra/newview/app_settings/settings.xml | 55 +++++++++++++++---- linden/indra/newview/llpanelweb.cpp | 6 +- linden/indra/newview/llviewermedia.cpp | 37 ++++++++++++- 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 57ed4c0fc..417ddc32c 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -2612,6 +2612,39 @@ <key>Value</key> <integer>0</integer> </map> + <key>BrowserCookiesEnabled</key> + <map> + <key>Comment</key> + <string>Accept cookies from Web sites?</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BrowserJavascriptEnabled</key> + <map> + <key>Comment</key> + <string>Enable Javascript in the built-in Web browser?</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BrowserPluginsEnabled</key> + <map> + <key>Comment</key> + <string>Enable Web plugins in the built-in Web browser?</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>BrowserProxyAddress</key> <map> <key>Comment</key> @@ -4050,17 +4083,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>CookiesEnabled</key> - <map> - <key>Comment</key> - <string>Accept cookies from Web sites?</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>CreateToolCopyCenters</key> <map> <key>Comment</key> @@ -8460,6 +8482,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>PluginAttachDebuggerToPlugins</key> + <map> + <key>Comment</key> + <string>If true, attach a debugger session to each plugin process as it's launched.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>PrecachingDelay</key> <map> <key>Comment</key> diff --git a/linden/indra/newview/llpanelweb.cpp b/linden/indra/newview/llpanelweb.cpp index e2933f089..14df239e9 100644 --- a/linden/indra/newview/llpanelweb.cpp +++ b/linden/indra/newview/llpanelweb.cpp @@ -68,7 +68,7 @@ BOOL LLPanelWeb::postBuild() std::string value = gSavedSettings.getBOOL("UseExternalBrowser") ? "external" : "internal"; childSetValue("use_external_browser", value); - childSetValue("cookies_enabled", gSavedSettings.getBOOL("CookiesEnabled")); + childSetValue("cookies_enabled", gSavedSettings.getBOOL("BrowserCookiesEnabled")); childSetValue("web_proxy_enabled", gSavedSettings.getBOOL("BrowserProxyEnabled")); childSetValue("web_proxy_editor", gSavedSettings.getString("BrowserProxyAddress")); @@ -101,7 +101,7 @@ LLPanelWeb::~LLPanelWeb() void LLPanelWeb::apply() { - gSavedSettings.setBOOL("CookiesEnabled", childGetValue("cookies_enabled")); + gSavedSettings.setBOOL("BrowserCookiesEnabled", childGetValue("cookies_enabled")); gSavedSettings.setBOOL("BrowserProxyEnabled", childGetValue("web_proxy_enabled")); gSavedSettings.setString("BrowserProxyAddress", childGetValue("web_proxy_editor")); gSavedSettings.setS32("BrowserProxyPort", childGetValue("web_proxy_port")); @@ -224,4 +224,4 @@ void LLPanelWeb::onClickClear(void* user_data) { LLPanelWeb* self = (LLPanelWeb*)user_data; self->childSetValue("world_search_editor","") ; -} \ No newline at end of file +} diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 8c5cf6a14..57c211198 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -466,6 +466,19 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ std::string user_data_path = gDirUtilp->getOSUserAppDir(); user_data_path += gDirUtilp->getDirDelimiter(); + // Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.) + // If the linden username returned is blank, that can only mean we are + // at the login page displaying login Web page or Web browser test via Develop menu. + // In this case we just use whatever gDirUtilp->getOSUserAppDir() gives us (this + // is what we always used before this change) + std::string linden_user_dir = gDirUtilp->getLindenUserDir(); + if ( ! linden_user_dir.empty() ) + { + // gDirUtilp->getLindenUserDir() is whole path, not just Linden name + user_data_path = linden_user_dir; + user_data_path += gDirUtilp->getDirDelimiter(); + } + // See if the plugin executable exists llstat s; if(LLFile::stat(launcher_name, &s)) @@ -480,7 +493,22 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ { LLPluginClassMedia* media_source = new LLPluginClassMedia(owner); media_source->setSize(default_width, default_height); - if (media_source->init(launcher_name, plugin_name, false)) + media_source->setUserDataPath(user_data_path); + media_source->setLanguageCode(LLUI::getLanguage()); + + // collect 'cookies enabled' setting from prefs and send to embedded browser + bool cookies_enabled = gSavedSettings.getBOOL( "BrowserCookiesEnabled" ); + media_source->enable_cookies( cookies_enabled ); + + // collect 'plugins enabled' setting from prefs and send to embedded browser + bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" ); + media_source->setPluginsEnabled( plugins_enabled ); + + // collect 'javascript enabled' setting from prefs and send to embedded browser + bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" ); + media_source->setJavascriptEnabled( javascript_enabled ); + + if (media_source->init(launcher_name, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) { return media_source; } @@ -491,7 +519,12 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ } } } - + + LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL; + LLSD args; + args["MIME_TYPE"] = media_type; + LLNotifications::instance().add("NoPlugin", args); + return NULL; } From b7a4a4ce26b3784770c9ff21496c9b6fc2e116ea Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 19 Oct 2010 21:17:41 +0200 Subject: [PATCH 065/239] Update WebKit Version in About floater. --- linden/indra/newview/llfloaterabout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 7aed0950e..f8db715ea 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp @@ -243,7 +243,7 @@ LLFloaterAbout::LLFloaterAbout() // TODO: Implement media plugin version query - support.append("Qt Webkit Version: 4.5.2 "); + support.append("Qt Webkit Version: 4.6 (version number hard-coded)"); support.append("\n"); if (gPacketsIn > 0) From 2f4e17af336c9a399a0274b7836f40fc7ff56e21 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 20 Oct 2010 18:31:42 +0200 Subject: [PATCH 066/239] LindenUserDir fixes. The LindenUserDir (~/.imprudence/first_last/) cannot be initialized before the user logged in. However, several singletons (that only can be initialized once) depend on this directory for initialization. Therefore we have to take care not to instantiate those singletons until after the user logged in. With regard to webit, this fixes the browser_profile (cache and cookies) directory that the builtin browser uses. --- linden/indra/llui/lltexteditor.cpp | 11 +++- linden/indra/llvfs/lldir.cpp | 3 +- linden/indra/llvfs/lldir.h | 2 +- linden/indra/llvfs/lldir_linux.cpp | 2 +- linden/indra/llvfs/lldir_solaris.cpp | 2 +- linden/indra/newview/llappviewer.cpp | 20 ++++--- linden/indra/newview/llimview.cpp | 2 +- linden/indra/newview/llmutelist.cpp | 2 +- linden/indra/newview/llstartup.cpp | 6 ++- linden/indra/newview/llurlhistory.cpp | 2 +- linden/indra/newview/llviewermedia.cpp | 2 +- linden/indra/newview/llviewerwindow.cpp | 70 ++++++++++++++----------- linden/indra/newview/llviewerwindow.h | 1 + 13 files changed, 75 insertions(+), 50 deletions(-) diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index fdf8bcf94..004d06398 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -57,6 +57,7 @@ #include "llimagegl.h" #include "llwindow.h" #include "lltextparser.h" +#include "lldir.h" #include <queue> #include "llmenugl.h" @@ -4205,7 +4206,10 @@ void LLTextEditor::appendColoredText(const std::string &new_text, const std::string& font_name) { LLColor4 lcolor=color; - if (mParseHighlights) + // If LindenUserDir is empty then we didn't login yet. + // In that case we can't instantiate LLTextParser, which + // is initialized per user. + if (mParseHighlights && !gDirUtilp->getLindenUserDir(true).empty()) { LLTextParser* highlight = LLTextParser::getInstance(); highlight->parseFullLineHighlights(new_text, &lcolor); @@ -4285,7 +4289,10 @@ void LLTextEditor::appendHighlightedText(const std::string &new_text, S32 highlight_part, LLStyleSP stylep) { - if (mParseHighlights) + // If LindenUserDir is empty then we didn't login yet. + // In that case we can't instantiate LLTextParser, which + // is initialized per user. + if (mParseHighlights && !gDirUtilp->getLindenUserDir(true).empty()) { LLTextParser* highlight = LLTextParser::getInstance(); diff --git a/linden/indra/llvfs/lldir.cpp b/linden/indra/llvfs/lldir.cpp index 5567fddde..cd1e98d48 100644 --- a/linden/indra/llvfs/lldir.cpp +++ b/linden/indra/llvfs/lldir.cpp @@ -192,8 +192,9 @@ const std::string &LLDir::getOSUserAppDir() const return mOSUserAppDir; } -const std::string &LLDir::getLindenUserDir() const +const std::string &LLDir::getLindenUserDir(bool empty_ok) const { + llassert(empty_ok || !mLindenUserDir.empty()); return mLindenUserDir; } diff --git a/linden/indra/llvfs/lldir.h b/linden/indra/llvfs/lldir.h index 55574d623..766f3518f 100644 --- a/linden/indra/llvfs/lldir.h +++ b/linden/indra/llvfs/lldir.h @@ -92,7 +92,7 @@ class LLDir const std::string &getAppRODataDir() const; // Location of read-only data files const std::string &getOSUserDir() const; // Location of the os-specific user dir const std::string &getOSUserAppDir() const; // Location of the os-specific user app dir - const std::string &getLindenUserDir() const; // Location of the Linden user dir. + const std::string &getLindenUserDir(bool empty_ok = false) const; // Location of the Linden user dir. const std::string &getChatLogsDir() const; // Location of the chat logs dir. const std::string &getPerAccountChatLogsDir() const; // Location of the per account chat logs dir. const std::string &getTempDir() const; // Common temporary directory diff --git a/linden/indra/llvfs/lldir_linux.cpp b/linden/indra/llvfs/lldir_linux.cpp index ec0a4f468..5f1eabb8d 100644 --- a/linden/indra/llvfs/lldir_linux.cpp +++ b/linden/indra/llvfs/lldir_linux.cpp @@ -97,7 +97,7 @@ LLDir_Linux::LLDir_Linux() mAppRODataDir = tmp_str; mOSUserDir = getCurrentUserHome(tmp_str); mOSUserAppDir = ""; - mLindenUserDir = tmp_str; + mLindenUserDir = ""; char path [32]; /* Flawfinder: ignore */ diff --git a/linden/indra/llvfs/lldir_solaris.cpp b/linden/indra/llvfs/lldir_solaris.cpp index c647e2bd1..5132455ff 100644 --- a/linden/indra/llvfs/lldir_solaris.cpp +++ b/linden/indra/llvfs/lldir_solaris.cpp @@ -100,7 +100,7 @@ LLDir_Solaris::LLDir_Solaris() mAppRODataDir = strdup(tmp_str); mOSUserDir = getCurrentUserHome(tmp_str); mOSUserAppDir = ""; - mLindenUserDir = tmp_str; + mLindenUserDir = ""; char path [LL_MAX_PATH]; /* Flawfinder: ignore */ diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 9fad9f172..1d4557501 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -1205,7 +1205,10 @@ bool LLAppViewer::cleanup() //reset balance for not playing the UI-Sound //when relogging into another account - gStatusBar->clearBalance(); + if (gStatusBar) + { + gStatusBar->clearBalance(); + } if (mQuitRequested) { @@ -3282,12 +3285,15 @@ void LLAppViewer::saveFinalSnapshot() gSavedSettings.setBOOL("ShowParcelOwners", FALSE); idle(); - std::string snap_filename = gDirUtilp->getLindenUserDir(); - snap_filename += gDirUtilp->getDirDelimiter(); - snap_filename += SCREEN_LAST_FILENAME; - // use full pixel dimensions of viewer window (not post-scale dimensions) - gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight(), FALSE, TRUE); - mSavedFinalSnapshot = TRUE; + std::string snap_filename = gDirUtilp->getLindenUserDir(true); + if (!snap_filename.empty()) + { + snap_filename += gDirUtilp->getDirDelimiter(); + snap_filename += SCREEN_LAST_FILENAME; + // use full pixel dimensions of viewer window (not post-scale dimensions) + gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight(), FALSE, TRUE); + mSavedFinalSnapshot = TRUE; + } } } diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp index a6eaeb37e..0b710307a 100644 --- a/linden/indra/newview/llimview.cpp +++ b/linden/indra/newview/llimview.cpp @@ -1360,7 +1360,7 @@ void LLIMMgr::saveIgnoreGroup() { // llinfos << "saving ignore_groups.xml" << llendl; - std::string user_dir = gDirUtilp->getLindenUserDir(); + std::string user_dir = gDirUtilp->getLindenUserDir(true); if (!user_dir.empty()) { std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "ignore_groups.xml"); diff --git a/linden/indra/newview/llmutelist.cpp b/linden/indra/newview/llmutelist.cpp index 0e03509eb..fff555842 100644 --- a/linden/indra/newview/llmutelist.cpp +++ b/linden/indra/newview/llmutelist.cpp @@ -265,7 +265,7 @@ LLMuteList::~LLMuteList() // If we quit from the login screen we will not have an SL account // name. Don't try to save, otherwise we'll dump a file in // C:\Program Files\SecondLife\ JC - std::string user_dir = gDirUtilp->getLindenUserDir(); + std::string user_dir = gDirUtilp->getLindenUserDir(true); if (!user_dir.empty()) { std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml"); diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 7bd5fff21..fad3df2c1 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -839,7 +839,7 @@ bool idle_startup() LLToolMgr::getInstance()->initTools(); // Quickly get something onscreen to look at. - gViewerWindow->initWorldUI(); + gViewerWindow->pre_initWorldUI(); } gViewerWindow->setNormalControlsVisible( FALSE ); @@ -1823,6 +1823,10 @@ bool idle_startup() { LL_DEBUGS("AppInitStartupState") << "STATE_WORLD_INIT" << LL_ENDL; set_startup_status(0.40f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD); + + // Initialize the rest of the world. + gViewerWindow->initWorldUI(); + gDisconnected=FALSE; display_startup(); // We should have an agent id by this point. diff --git a/linden/indra/newview/llurlhistory.cpp b/linden/indra/newview/llurlhistory.cpp index fbd14bcaa..b187f3b22 100644 --- a/linden/indra/newview/llurlhistory.cpp +++ b/linden/indra/newview/llurlhistory.cpp @@ -74,7 +74,7 @@ bool LLURLHistory::loadFile(const std::string& filename) // static bool LLURLHistory::saveFile(const std::string& filename) { - std::string temp_str = gDirUtilp->getLindenUserDir(); + std::string temp_str = gDirUtilp->getLindenUserDir(true); if( temp_str.empty() ) { llwarns << "Can't save " << filename diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 57c211198..5c01b2543 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -471,7 +471,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ // at the login page displaying login Web page or Web browser test via Develop menu. // In this case we just use whatever gDirUtilp->getOSUserAppDir() gives us (this // is what we always used before this change) - std::string linden_user_dir = gDirUtilp->getLindenUserDir(); + std::string linden_user_dir = gDirUtilp->getLindenUserDir(true); if ( ! linden_user_dir.empty() ) { // gDirUtilp->getLindenUserDir() is whole path, not just Linden name diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index 5cd730a52..07fef5359 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -1652,7 +1652,7 @@ void LLViewerWindow::adjustControlRectanglesForFirstUse(const LLRect& window) adjust_rect_top_center("FloaterCameraRect3", window); } -void LLViewerWindow::initWorldUI() +void LLViewerWindow::pre_initWorldUI() { pre_init_menus(); @@ -1672,9 +1672,45 @@ void LLViewerWindow::initWorldUI() gHoverView = new LLHoverView(std::string("gHoverView"), full_window); gHoverView->setVisible(TRUE); mRootView->addChild(gHoverView); - + gIMMgr = LLIMMgr::getInstance(); + // Make sure we only create menus once per session -- MC + if (!gMenuHolder) + { + init_menus(); + } + + if (!gFloaterTools) + { + gFloaterTools = new LLFloaterTools(); + gFloaterTools->setVisible(FALSE); + } + + // menu holder appears on top to get first pass at all mouse events + + mRootView->sendChildToFront(gMenuHolder); + + if ( gHUDView == NULL ) + { + LLRect hud_rect = full_window; + hud_rect.mBottom += 50; + if (gMenuBarView) + { + hud_rect.mTop -= gMenuBarView->getRect().getHeight(); + } + gHUDView = new LLHUDView(hud_rect); + // put behind everything else in the UI + mRootView->addChildAtEnd(gHUDView); + } +} + +void LLViewerWindow::initWorldUI() +{ + S32 height = mRootView->getRect().getHeight(); + S32 width = mRootView->getRect().getWidth(); + LLRect full_window(0, height, width, 0); + if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) { LLFloaterChat::getInstance(LLSD())->loadHistory(); @@ -1715,18 +1751,6 @@ void LLViewerWindow::initWorldUI() // Toolbox floater - // Make sure we only create menus once per session -- MC - if (!gMenuHolder) - { - init_menus(); - } - - if (!gFloaterTools) - { - gFloaterTools = new LLFloaterTools(); - gFloaterTools->setVisible(FALSE); - } - if (!gStatusBar) { // Status bar @@ -1744,24 +1768,6 @@ void LLViewerWindow::initWorldUI() } LLFloaterChatterBox::createInstance(LLSD()); - - - // menu holder appears on top to get first pass at all mouse events - - mRootView->sendChildToFront(gMenuHolder); - - if ( gHUDView == NULL ) - { - LLRect hud_rect = full_window; - hud_rect.mBottom += 50; - if (gMenuBarView) - { - hud_rect.mTop -= gMenuBarView->getRect().getHeight(); - } - gHUDView = new LLHUDView(hud_rect); - // put behind everything else in the UI - mRootView->addChildAtEnd(gHUDView); - } } // Destroy the UI diff --git a/linden/indra/newview/llviewerwindow.h b/linden/indra/newview/llviewerwindow.h index 85cdc5221..ee8f3fe51 100644 --- a/linden/indra/newview/llviewerwindow.h +++ b/linden/indra/newview/llviewerwindow.h @@ -143,6 +143,7 @@ class LLViewerWindow : public LLWindowCallbacks void initBase(); void adjustRectanglesForFirstUse(const LLRect& window); void adjustControlRectanglesForFirstUse(const LLRect& window); + void pre_initWorldUI(); void initWorldUI(); // From b65b0ec23184885f212a78aa69edd152bdbd4588 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Thu, 21 Oct 2010 00:53:01 +0200 Subject: [PATCH 067/239] Add support for PluginAttachDebuggerToPlugins for linux Opens a terminal with a gdb session for newly started SLPlugin processes if PluginAttachDebuggerToPlugins is set to TRUE. --- linden/indra/llcommon/llprocesslauncher.h | 3 +++ linden/indra/llplugin/llpluginprocessparent.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/linden/indra/llcommon/llprocesslauncher.h b/linden/indra/llcommon/llprocesslauncher.h index 036732f95..9cdb0f68a 100644 --- a/linden/indra/llcommon/llprocesslauncher.h +++ b/linden/indra/llcommon/llprocesslauncher.h @@ -80,6 +80,9 @@ class LLProcessLauncher HANDLE mProcessHandle; #else pid_t mProcessID; + +public: + pid_t getProcessID() const { return mProcessID; } #endif }; diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp index 1bf34c5c4..8db6046e2 100755 --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp @@ -408,6 +408,17 @@ void LLPluginProcessParent::idle(void) mDebugger.addArgument("end tell"); mDebugger.launch(); + #elif LL_LINUX + + std::stringstream cmd; + + mDebugger.setExecutable("/usr/bin/gnome-terminal"); + mDebugger.addArgument("--geometry=165x24-0+0"); + mDebugger.addArgument("-e"); + cmd << "/usr/bin/gdb -n /proc/" << mProcess.getProcessID() << "/exe " << mProcess.getProcessID(); + mDebugger.addArgument(cmd.str()); + mDebugger.launch(); + #endif } From 5af5d291363298b448cbd755001f0590a16c036c Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Wed, 20 Oct 2010 16:45:14 -0700 Subject: [PATCH 068/239] Fixed the Preferences > Communication tab options not enabling (happens on OpenSim when a user's personal info isn't sent) --- linden/indra/newview/llprefsim.cpp | 32 ++++++++++++++++-------------- linden/indra/newview/llstartup.h | 3 +++ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp index 2c8ef4d05..e915bd2fd 100644 --- a/linden/indra/newview/llprefsim.cpp +++ b/linden/indra/newview/llprefsim.cpp @@ -45,6 +45,7 @@ #include "llviewercontrol.h" #include "llviewernetwork.h" #include "lluictrlfactory.h" +#include "llstartup.h" #include "lldirpicker.h" @@ -106,22 +107,23 @@ BOOL LLPrefsIMImpl::postBuild() childSetLabelArg("send_im_to_email", "[EMAIL]", getString("log_in_to_change")); // Don't enable this until we get personal data - childDisable("include_im_in_chat_console"); - childDisable("include_im_in_chat_history"); - childDisable("show_timestamps_check"); - childDisable("friends_online_notify_checkbox"); + // Unless we're already logged in. Some non-SL grids won't send us the data we need -- MC + childSetEnabled("include_im_in_chat_console", LLStartUp::isLoggedIn()); + childSetEnabled("include_im_in_chat_history", LLStartUp::isLoggedIn()); + childSetEnabled("show_timestamps_check", LLStartUp::isLoggedIn()); + childSetEnabled("friends_online_notify_checkbox", LLStartUp::isLoggedIn()); - childDisable("online_visibility"); - childDisable("send_im_to_email"); - childDisable("log_instant_messages"); - childDisable("log_chat"); - childDisable("log_show_history"); - childDisable("log_path_button"); - childDisable("busy_response"); - childDisable("log_instant_messages_timestamp"); - childDisable("log_chat_timestamp"); - childDisable("log_chat_IM"); - childDisable("log_date_timestamp"); + childSetEnabled("online_visibility", LLStartUp::isLoggedIn()); + childSetEnabled("send_im_to_email", LLStartUp::isLoggedIn()); + childSetEnabled("log_instant_messages", LLStartUp::isLoggedIn()); + childSetEnabled("log_chat", LLStartUp::isLoggedIn()); + childSetEnabled("log_show_history", LLStartUp::isLoggedIn()); + childSetEnabled("log_path_button", LLStartUp::isLoggedIn()); + childSetEnabled("busy_response", LLStartUp::isLoggedIn()); + childSetEnabled("log_instant_messages_timestamp", LLStartUp::isLoggedIn()); + childSetEnabled("log_chat_timestamp", LLStartUp::isLoggedIn()); + childSetEnabled("log_chat_IM", LLStartUp::isLoggedIn()); + childSetEnabled("log_date_timestamp", LLStartUp::isLoggedIn()); childSetText("busy_response", getString("log_in_to_change")); diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h index 9a3c91c37..08862e63c 100644 --- a/linden/indra/newview/llstartup.h +++ b/linden/indra/newview/llstartup.h @@ -124,6 +124,9 @@ class LLStartUp static bool shouldAutoLogin() { return mShouldAutoLogin; }; static void setShouldAutoLogin(bool value) { mShouldAutoLogin = value; }; + // Returns true if startup has been successfully completed + static bool isLoggedIn() { return gStartupState == STATE_STARTED; } + private: static bool mStartedOnce; static bool mShouldAutoLogin; From de1ece909c0125d0bd7aece788deeb0764bb070e Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 22 Oct 2010 00:33:41 +0200 Subject: [PATCH 069/239] LindenUserDir fixes, part 2. After the previous commit, the menu text - after logging in - had disappeared. This fixes that. --- linden/indra/newview/llstartup.cpp | 4 +- linden/indra/newview/llviewerwindow.cpp | 55 +++++++++++-------------- linden/indra/newview/llviewerwindow.h | 2 +- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index fad3df2c1..4683df127 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -839,7 +839,7 @@ bool idle_startup() LLToolMgr::getInstance()->initTools(); // Quickly get something onscreen to look at. - gViewerWindow->pre_initWorldUI(); + gViewerWindow->initWorldUI(); } gViewerWindow->setNormalControlsVisible( FALSE ); @@ -1825,7 +1825,7 @@ bool idle_startup() set_startup_status(0.40f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD); // Initialize the rest of the world. - gViewerWindow->initWorldUI(); + gViewerWindow->initWorldUI_postLogin(); gDisconnected=FALSE; display_startup(); diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index 07fef5359..2af6fe3de 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -1652,7 +1652,7 @@ void LLViewerWindow::adjustControlRectanglesForFirstUse(const LLRect& window) adjust_rect_top_center("FloaterCameraRect3", window); } -void LLViewerWindow::pre_initWorldUI() +void LLViewerWindow::initWorldUI() { pre_init_menus(); @@ -1681,16 +1681,13 @@ void LLViewerWindow::pre_initWorldUI() init_menus(); } + // Toolbox floater if (!gFloaterTools) { gFloaterTools = new LLFloaterTools(); gFloaterTools->setVisible(FALSE); } - // menu holder appears on top to get first pass at all mouse events - - mRootView->sendChildToFront(gMenuHolder); - if ( gHUDView == NULL ) { LLRect hud_rect = full_window; @@ -1705,12 +1702,34 @@ void LLViewerWindow::pre_initWorldUI() } } -void LLViewerWindow::initWorldUI() +// initWorldUI that wasn't before logging in. Some of this may require the access the 'LindenUserDir'. +void LLViewerWindow::initWorldUI_postLogin() { S32 height = mRootView->getRect().getHeight(); S32 width = mRootView->getRect().getWidth(); LLRect full_window(0, height, width, 0); + // The status base must be created before calling sendChildToFront below, + // or the text of the menu (after logging in) won't be visible. + if (!gStatusBar) + { + // Status bar + S32 menu_bar_height = gMenuBarView->getRect().getHeight(); + LLRect root_rect = mRootView->getRect(); + LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height); + gStatusBar = new LLStatusBar(std::string("status"), status_rect); + gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP); + + gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE); + gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight()); + // sync bg color with menu bar + gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor() ); + mRootView->addChild(gStatusBar); + } + + // Menu holder appears on top to get first pass at all mouse events + mRootView->sendChildToFront(gMenuHolder); + if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) { LLFloaterChat::getInstance(LLSD())->loadHistory(); @@ -1726,8 +1745,6 @@ void LLViewerWindow::initWorldUI() mRootView->addChild(gMorphView); gMorphView->setVisible(FALSE); - // *Note: this is where gFloaterMute used to be initialized. - LLWorldMapView::initClass(); adjust_rect_centered_partial_zoom("FloaterWorldMapRect2", full_window); @@ -1745,28 +1762,6 @@ void LLViewerWindow::initWorldUI() gFloaterTeleportHistory->setVisible(FALSE); } - // - // Tools for building - // - - // Toolbox floater - - if (!gStatusBar) - { - // Status bar - S32 menu_bar_height = gMenuBarView->getRect().getHeight(); - LLRect root_rect = mRootView->getRect(); - LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height); - gStatusBar = new LLStatusBar(std::string("status"), status_rect); - gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP); - - gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE); - gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight()); - // sync bg color with menu bar - gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor() ); - mRootView->addChild(gStatusBar); - } - LLFloaterChatterBox::createInstance(LLSD()); } diff --git a/linden/indra/newview/llviewerwindow.h b/linden/indra/newview/llviewerwindow.h index ee8f3fe51..d26d82010 100644 --- a/linden/indra/newview/llviewerwindow.h +++ b/linden/indra/newview/llviewerwindow.h @@ -143,8 +143,8 @@ class LLViewerWindow : public LLWindowCallbacks void initBase(); void adjustRectanglesForFirstUse(const LLRect& window); void adjustControlRectanglesForFirstUse(const LLRect& window); - void pre_initWorldUI(); void initWorldUI(); + void initWorldUI_postLogin(); // // LLWindowCallback interface implementation From 5cc7263a9113244414493722bb7724275bf52ec8 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 22 Oct 2010 20:48:19 +0200 Subject: [PATCH 070/239] Fix the errors "QCursor: Cannot create bitmap cursor; invalid bitmap(s)" at start up of the webkit plugin. These are caused because builtin resources of QtWebKit weren't initialized. --- linden/indra/media_plugins/webkit/media_plugin_webkit.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index 5058e0ac6..d4c5deb30 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -34,6 +34,7 @@ */ #include "llqtwebkit.h" +#include <qglobal.h> // for Q_INIT_RESOURCE #include "linden_common.h" #include "indra_constants.h" // for indra keyboard codes @@ -720,6 +721,9 @@ MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_ mJavascriptEnabled = true; // default to on mPluginsEnabled = true; // default to on mUserAgent = "LLPluginMedia Web Browser"; + + // Initialize WebCore resource. + Q_INIT_RESOURCE(WebCore); } MediaPluginWebKit::~MediaPluginWebKit() From 66302fb040782e1c6c5cce51f6a782a007771e37 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Fri, 22 Oct 2010 23:43:19 +0200 Subject: [PATCH 071/239] WhiteStar Magic: update the lscript_library to match OpenSim 0.7 --- .../lscript/lscript_library/lscript_library.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/linden/indra/lscript/lscript_library/lscript_library.cpp b/linden/indra/lscript/lscript_library/lscript_library.cpp index 68daa50cc..cc56119ef 100644 --- a/linden/indra/lscript/lscript_library/lscript_library.cpp +++ b/linden/indra/lscript/lscript_library/lscript_library.cpp @@ -484,8 +484,9 @@ void LLScriptLibrary::init() // documented and therefore the description may be incomplete and require further attention. // OpenSimulator is written in C# and not CPP therefore some values for example "double = float" etc. are different. - // OSSL corrections and syntax additions added + set in same order as found in OSSL_stub.cs of OpenSim Source (February 19, 2010) - // based on OpenSimulator Ver. 0.6.9 DEV Git # af265e001d3bf043590e480cd6574a14193f6de0 - Rev 12239 + // OSSL corrections and syntax additions added + set in same order as found in OSSL_stub.cs of OpenSim Source (Updated PM October-21-2010 + // based on OpenSimulator Ver. 0.7.x DEV/Master Git # a7acb650d400a280a7b9edabd304376dff9c81af - a7acb65-r/14142 + // Updates by WhiteStar Magic addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSetRegionWaterHeight", NULL, "f", "osSetRegionWaterHeight(float height)\nAdjusts Water Height on region.\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSetRegionSunSettings", NULL, "iif", "osSetRegionSunSettings(integer useEstateSun, integer sunFixed, float sunHour)\nChanges the Estate Sun Settings, then Triggers a Sun Update\n'sunFixed' TRUE (1) to keep the sun stationary, FALSE (0) to use global time\n'sunHour' The \"Sun Hour\" that is desired, 0...24, with 0 just after SunRise.\n(OpenSim only.)")); @@ -494,8 +495,11 @@ void LLScriptLibrary::init() addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSunGetParam","f", "s", "float osSunGetParam(string param)\nReturns current float values for param\nwhere param = day_length, year_length, day_night_offset, update_interval.\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSunSetParam", "sf", NULL, "osSunSetParam(string param, float value)\nSet's Sun Param for SunSet,\nosSunSetParam(day_length, 24.0)\nwhere param = day_length, year_length, day_night_offset, update_interval.\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osWindActiveModelPluginName", "s", NULL, "string osWindActiveModelPluginName()\nReturns the Current Working Wind Module Installed\nThese are SimpleRandomWind or ConfigurableWind, optionally others.\n(OpenSim only.)")); - addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osWindParamSet", NULL, "ssf", "osWindParamSet(string plugin, string param, float value)Send Param to Specified Wind Plugin with new value.\n(OpenSim only.)")); - addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osWindParamGet", "f", "ss", "float osWindParamGet(string plugin, string param)\n Returns Current param from specified Wind Plugin Module.\n(OpenSim only.)")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osParcelJoin", NULL, "vv", "osParcelJoin(vector pos1, vector pos2))\nJoins Parcels @ X,Y coordinates.\n(OpenSim only.)")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osParcelSubdivide", NULL, "vv", "osParcelSubdivide(vector pos1, vector pos2))\nSubdivides Parcels @ X,Y coordinates.\n(OpenSim only.)")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osParcelSetDetails", NULL, "vv", "osParcelSetDetails(vector pos, list rules))\nSet Parcel details.\n(OpenSim only.)")); + // addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osWindParamSet", NULL, "ssf", "osWindParamSet(string plugin, string param, float value)Send Param to Specified Wind Plugin with new value.\n(OpenSim only.)")); + // addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osWindParamGet", "f", "ss", "float osWindParamGet(string plugin, string param)\n Returns Current param from specified Wind Plugin Module.\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osList2Double", "f", "si", "double osList2Double(list src, int index)\nReturns Double (float) Value from src at index.\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureURL", NULL, "ssssi", "osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams, int timer )\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSetDynamicTextureData", NULL, "ssssi", "osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, int timer)\nWrites text and vector graphics onto a prim face.\n(OpenSim only.)")); @@ -564,7 +568,9 @@ void LLScriptLibrary::init() addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSetSpeed", NULL, "kf", "osSetSpeed(key AVATAR, float SpeedModifier)\nMultiplies the normal running, walking, and flying speed of the specified avatar.\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osCauseDamage", NULL, "kf", "osCauseDamage(key AVATAR, float damage)\nCauses damage to specified AVATAR (UUID).\n(OpenSim only.)")); addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osCauseHealing", NULL, "kf", "osCauseHealing(key AVATAR, float healing)\nCauses Healing to specified AVATAR (UUID).\n(OpenSim only.)")); - + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osGetPrimitiveParams", "l", "kl", "List osGetPrimitiveParams(key prim, list rules)\nGets primitive Params.\n(OpenSim only.)")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSetPrimitiveParams", NULL, "kl", "osSetPrimitiveParams(key prim, list rules)\nSets primitive Params.\n(OpenSim only.)")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "osSetProjectionParams", NULL, "kikfff", "osSetProjectionParams(key prim. bool projection, key texture, float fov, float focus, float amb)\nSet Projection Paramaters (bool = true / false)\n(OpenSim only.)")); // LightShare functions addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "cmSetWindlightScene", "i", "l", "integer cmSetWindlightScene(list rules)\nSet the current WindLight scene. Restricted to estate managers and owners only.")); From 36d557ff2a2290ca3f3a66a504852328e6dc32a2 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Thu, 21 Oct 2010 23:28:59 -0500 Subject: [PATCH 072/239] Fixed #629: Freeze Frame snapshot option breaks the UI. --- linden/indra/newview/llfloatersnapshot.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp index c0e972d6e..a58120dc7 100644 --- a/linden/indra/newview/llfloatersnapshot.cpp +++ b/linden/indra/newview/llfloatersnapshot.cpp @@ -2128,7 +2128,6 @@ BOOL LLFloaterSnapshot::postBuild() //gSnapshotFloaterView->addChild(this); impl.updateControls(this); - impl.updateLayout(this); return TRUE; } From b41717bc60cf72aef2257c6573201bd74210c428 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Fri, 22 Oct 2010 17:20:34 -0500 Subject: [PATCH 073/239] Added FontSizeMultiplier and FontSizeRounding settings. Gives more control over font sizes, addresses font being smaller than some users desire. --- linden/indra/llrender/llfontregistry.cpp | 10 ++++++++- .../indra/newview/app_settings/settings.xml | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/linden/indra/llrender/llfontregistry.cpp b/linden/indra/llrender/llfontregistry.cpp index 9792a91de..c5923cdb0 100644 --- a/linden/indra/llrender/llfontregistry.cpp +++ b/linden/indra/llrender/llfontregistry.cpp @@ -442,7 +442,15 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) std::string font_path = local_path + *file_name_it; BOOL is_fallback = !is_first_found; F32 size_mult = (is_fallback ? 1 : match_desc->getSizeMult()); - F32 size = (F32)llround(point_size * size_mult); + if (gSavedSettings.getF32("FontSizeMultiplier") > 0) + { + size_mult *= gSavedSettings.getF32("FontSizeMultiplier"); + } + F32 size = (F32)(point_size * size_mult); + if (gSavedSettings.getBOOL("FontSizeRounding")) + { + size = (F32)llround(size); + } if (!fontp->loadFace(font_path, size, LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback)) { diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 8c280d405..7b37bb679 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -396,6 +396,28 @@ <key>Value</key> <string>DroidSans</string> </map> + <key>FontSizeMultiplier</key> + <map> + <key>Comment</key> + <string>Multiply all font sizes by this amount. Requires viewer restart.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <string>1.0</string> + </map> + <key>FontSizeRounding</key> + <map> + <key>Comment</key> + <string>Round all font sizes to integer values, to potentially reduce font blurriness. The rounding occurs after FontSizeMultiplier is applied. Requires viewer restart.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>GoAction</key> <map> <key>Comment</key> From 22df58bd35e75d420c20707d7dffdd322d35e4dc Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Fri, 22 Oct 2010 18:06:59 -0500 Subject: [PATCH 074/239] Added FontSizeMultiplier and FontSizeRounding controls to Font prefs. --- linden/indra/newview/impprefsfonts.cpp | 50 +++++++++++++++++-- .../xui/en-us/panel_preferences_fonts.xml | 10 ++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/impprefsfonts.cpp b/linden/indra/newview/impprefsfonts.cpp index 3ce71ebb5..bf0b0284c 100644 --- a/linden/indra/newview/impprefsfonts.cpp +++ b/linden/indra/newview/impprefsfonts.cpp @@ -29,7 +29,9 @@ #include "llviewerprecompiledheaders.h" #include "impprefsfonts.h" +#include "llcheckboxctrl.h" #include "llradiogroup.h" +#include "llspinctrl.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" @@ -61,24 +63,64 @@ void ImpPrefsFonts::refresh() { fonts->setValue( gSavedSettings.getString("FontChoice") ); } + + LLSpinCtrl* font_mult = getChild<LLSpinCtrl>("font_mult"); + if (font_mult) + { + font_mult->setValue( gSavedSettings.getF32("FontSizeMultiplier") ); + } + + LLCheckBoxCtrl* font_round = getChild<LLCheckBoxCtrl>("font_round"); + if (font_round) + { + font_round->setValue( gSavedSettings.getBOOL("FontSizeRounding") ); + } } void ImpPrefsFonts::apply() { - LLRadioGroup* fonts = getChild<LLRadioGroup>("fonts"); + bool changed = false; + LLRadioGroup* fonts = getChild<LLRadioGroup>("fonts"); if (fonts) { std::string font_choice = fonts->getValue().asString(); - if (font_choice != gSavedSettings.getString("FontChoice") && !font_choice.empty()) { gSavedSettings.setString("FontChoice", font_choice); - LLNotifications::instance().add("ChangeFont"); - refresh(); + changed = true; } } + + LLSpinCtrl* font_mult = getChild<LLSpinCtrl>("font_mult"); + if (font_mult) + { + F32 mult = font_mult->getValue().asReal(); + if (mult != gSavedSettings.getF32("FontSizeMultiplier")) + { + gSavedSettings.setF32("FontSizeMultiplier", mult); + changed = true; + } + } + + LLCheckBoxCtrl* font_round = getChild<LLCheckBoxCtrl>("font_round"); + if (font_round) + { + bool round = font_round->getValue().asBoolean(); + if (round != gSavedSettings.getBOOL("FontSizeRounding")) + { + gSavedSettings.setBOOL("FontSizeRounding", round); + changed = true; + } + } + + if (changed) + { + refresh(); + LLNotifications::instance().add("ChangeFont"); + } + } void ImpPrefsFonts::cancel() diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_fonts.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_fonts.xml index 5865becf1..c64ce9fad 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_fonts.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_fonts.xml @@ -46,4 +46,14 @@ Preview: The quick brown fox jumped over the lazy dog. :) </text> + + <spinner name="font_mult" label="Font size multiplier:" label_width="130" + bottom="-280" left="20" height="16" width="180" follows="left|top" + decimal_digits="2" increment="0.01" max_val="3.0" min_val="0.1" + tool_tip="Multiply all font sizes by this amount." /> + + <check_box name="font_round" follows="left|top" + bottom="-300" left="20" height="16" width="300" + label="Force integer font sizes (may fix blurry fonts)" /> + </panel> From 421f337df1923be1657ccf10e6a96b6aa5d04967 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Fri, 22 Oct 2010 18:09:06 -0500 Subject: [PATCH 075/239] Changed Small font size back to 8.5. If this causes blurry fonts for a user, they should enable "Force integer font sizes" in Preferences > Fonts. --- linden/indra/newview/skins/default/xui/en-us/fonts.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/fonts.xml b/linden/indra/newview/skins/default/xui/en-us/fonts.xml index 556407944..7343ac210 100644 --- a/linden/indra/newview/skins/default/xui/en-us/fonts.xml +++ b/linden/indra/newview/skins/default/xui/en-us/fonts.xml @@ -153,7 +153,7 @@ /> <font_size name="Small" comment="Size of small font (points, or 1/72 of an inch)" - size="8" + size="8.5" /> </fonts> From 1724c21bbcf349ceeb7cc5bb013ca498bb130fff Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 07:12:35 -0700 Subject: [PATCH 076/239] Fixed copy_win_libs by removing glib dlls --- linden/indra/cmake/CopyWinLibs.cmake | 8 -------- 1 file changed, 8 deletions(-) diff --git a/linden/indra/cmake/CopyWinLibs.cmake b/linden/indra/cmake/CopyWinLibs.cmake index 2bea40c5a..44d35ed6c 100644 --- a/linden/indra/cmake/CopyWinLibs.cmake +++ b/linden/indra/cmake/CopyWinLibs.cmake @@ -43,10 +43,6 @@ set(all_targets ${all_targets} ${out_targets}) set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") set(plugintest_debug_files libeay32.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll qtcored4.dll qtguid4.dll qtnetworkd4.dll @@ -92,10 +88,6 @@ set(all_targets ${all_targets} ${out_targets}) set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") set(plugintest_release_files libeay32.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll qtcore4.dll qtgui4.dll qtnetwork4.dll From 54a6488d3b0399a2d5ba72b73bf4316f32531d1d Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 18:30:35 -0700 Subject: [PATCH 077/239] Fixed the Advanced preferences panel not appearing last in the preferences window --- linden/indra/newview/llfloaterpreference.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp index 09336cb8f..f8a0a4f7f 100644 --- a/linden/indra/newview/llfloaterpreference.cpp +++ b/linden/indra/newview/llfloaterpreference.cpp @@ -134,8 +134,8 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def mMsgPanel(NULL), mSkinsPanel(NULL), mLCDPanel(NULL), - mPrefsAdvanced(NULL), - mPrefsFonts(NULL) + mPrefsFonts(NULL), + mPrefsAdvanced(NULL) { mGeneralPanel = new LLPanelGeneral(); mTabContainer->addTabPanel(mGeneralPanel, mGeneralPanel->getLabel(), FALSE, onTabChanged, mTabContainer); @@ -195,14 +195,14 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def mTabContainer->addTabPanel(mSkinsPanel, mSkinsPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mSkinsPanel->setDefaultBtn(default_btn); - mPrefsAdvanced = new LLPrefsAdvanced(); - mTabContainer->addTabPanel(mPrefsAdvanced, mPrefsAdvanced->getLabel(), FALSE, onTabChanged, mTabContainer); - mPrefsAdvanced->setDefaultBtn(default_btn); - mPrefsFonts = new ImpPrefsFonts(); mTabContainer->addTabPanel(mPrefsFonts, mPrefsFonts->getLabel(), FALSE, onTabChanged, mTabContainer); mPrefsFonts->setDefaultBtn(default_btn); + mPrefsAdvanced = new LLPrefsAdvanced(); + mTabContainer->addTabPanel(mPrefsAdvanced, mPrefsAdvanced->getLabel(), FALSE, onTabChanged, mTabContainer); + mPrefsAdvanced->setDefaultBtn(default_btn); + if (!mTabContainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) { mTabContainer->selectFirstTab(); From cd14d97b90c0b3270310c00e8a105f17a59d0dcf Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 23 Oct 2010 20:38:54 -0500 Subject: [PATCH 078/239] Changed several Preferences modal alerts to notifications. CacheWillClear, CacheWillBeMoved, ChangeConnectionPort, ChangeSkin, and ChangeFont. There are many other alerts that should be made non-modal in the future, but this should prevent a focus fight with the Vivox policy window. --- .../skins/default/xui/en-us/notifications.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/notifications.xml b/linden/indra/newview/skins/default/xui/en-us/notifications.xml index 333e36273..3b8d19d4f 100644 --- a/linden/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/linden/indra/newview/skins/default/xui/en-us/notifications.xml @@ -902,32 +902,32 @@ Would you like to disable all popups which can be skipped? </notification> <notification - icon="alertmodal.tga" + icon="notify.tga" name="CacheWillClear" - type="alertmodal"> + type="notify"> Cache will be cleared after you restart [VIEWER_NAME]. </notification> <notification - icon="alertmodal.tga" + icon="notify.tga" name="CacheWillBeMoved" - type="alertmodal"> + type="notify"> Cache will be moved after you restart [VIEWER_NAME]. Note: This will clear the cache. </notification> <notification - icon="alertmodal.tga" + icon="notify.tga" name="ChangeConnectionPort" - type="alertmodal"> + type="notify"> Port settings take effect after you restart [VIEWER_NAME]. </notification> <notification - icon="alertmodal.tga" + icon="notify.tga" name="ChangeSkin" - type="alertmodal"> + type="notify"> The new skin will appear after you restart [VIEWER_NAME]. </notification> @@ -7103,8 +7103,8 @@ Apply this region's settings? ("Ignore" will ignore all region setting <notification name="ChangeFont" - icon="alertmodal.tga" - type="alertmodal"> + icon="notify.tga" + type="notify"> The new font will appear after you restart [VIEWER_NAME]. </notification> From 36c25f06e38e357716ecd31df58d70b92a3d8e0e Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Thu, 21 Oct 2010 22:13:28 -0500 Subject: [PATCH 079/239] Prim alignment tool by Qarl, backported by Jacek. Qarl has given permission to use this code under the terms of the GPL v2 + FLOSS exception and/or the LGPL v2.1. --- linden/indra/newview/CMakeLists.txt | 2 + linden/indra/newview/llfloatertools.cpp | 6 +- linden/indra/newview/llfloatertools.h | 1 + linden/indra/newview/qtoolalign.cpp | 585 ++++++++++++++++++ linden/indra/newview/qtoolalign.h | 50 ++ .../skins/default/xui/en-us/floater_tools.xml | 3 + 6 files changed, 646 insertions(+), 1 deletion(-) create mode 100644 linden/indra/newview/qtoolalign.cpp create mode 100644 linden/indra/newview/qtoolalign.h diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index dfd35bf31..1a6ad306c 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -484,6 +484,7 @@ set(viewer_SOURCE_FILES panelradarentry.cpp pipeline.cpp primbackup.cpp + qtoolalign.cpp rlvhandler.cpp rlvhelper.cpp rlvcommon.cpp @@ -936,6 +937,7 @@ set(viewer_HEADER_FILES panelradarentry.h pipeline.h primbackup.h + qtoolalign.h randgauss.h rlvdefines.h rlvhandler.h diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index fc72467c7..daff57375 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -84,7 +84,7 @@ #include "llvograss.h" #include "llvotree.h" #include "lluictrlfactory.h" - +#include "qtoolalign.h" #include "hippoLimits.h" // Globals @@ -273,6 +273,8 @@ BOOL LLFloaterTools::postBuild() childSetCommitCallback("radio stretch",commit_select_tool,LLToolCompScale::getInstance()); mRadioSelectFace = getChild<LLCheckBoxCtrl>("radio select face"); childSetCommitCallback("radio select face",commit_select_tool,LLToolFace::getInstance()); + mRadioAlign = getChild<LLCheckBoxCtrl>("radio align"); + childSetCommitCallback("radio align",commit_select_tool,QToolAlign::getInstance()); mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts"); childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts")); childSetCommitCallback("checkbox edit linked parts",commit_select_component,this); @@ -698,6 +700,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) tool == LLToolCompScale::getInstance() || tool == LLToolFace::getInstance() || tool == LLToolIndividual::getInstance() || + tool == QToolAlign::getInstance() || tool == LLToolPipette::getInstance(); mBtnEdit ->setToggleState( edit_visible ); @@ -720,6 +723,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioPosition ->set( tool == LLToolCompTranslate::getInstance() ); mRadioRotate ->set( tool == LLToolCompRotate::getInstance() ); mRadioStretch ->set( tool == LLToolCompScale::getInstance() ); + mRadioAlign->set( tool == QToolAlign::getInstance() ); if (mComboGridMode) { diff --git a/linden/indra/newview/llfloatertools.h b/linden/indra/newview/llfloatertools.h index ad5be6c86..bbf07ec50 100644 --- a/linden/indra/newview/llfloatertools.h +++ b/linden/indra/newview/llfloatertools.h @@ -140,6 +140,7 @@ class LLFloaterTools LLCheckBoxCtrl *mRadioRotate; LLCheckBoxCtrl *mRadioStretch; LLCheckBoxCtrl *mRadioSelectFace; + LLCheckBoxCtrl *mRadioAlign; LLCheckBoxCtrl *mCheckSelectIndividual; diff --git a/linden/indra/newview/qtoolalign.cpp b/linden/indra/newview/qtoolalign.cpp new file mode 100644 index 000000000..92cab6e50 --- /dev/null +++ b/linden/indra/newview/qtoolalign.cpp @@ -0,0 +1,585 @@ +/** + * @file qtoolalign.cpp + * @brief A tool to align objects + * @author Karl Stiefvater (Qarl) + * + * Karl has given permission to use this code under the terms of + * the GNU GPL v2 plus FLOSS exception and/or the GNU LGPL v2.1. + * + * Backported for Viewer 1.X code base by Jacek Antonelli. + */ + +#include "llviewerprecompiledheaders.h" + +// File includes +#include "qtoolalign.h" + +// Library includes +#include "llbbox.h" +#include "v3math.h" + +// Viewer includes +#include "llagent.h" +#include "llbox.h" +#include "llcylinder.h" +#include "llfloatertools.h" +#include "llselectmgr.h" +#include "llviewercamera.h" +#include "llviewercontrol.h" +#include "llviewerobject.h" +#include "llviewerwindow.h" + + +const F32 MANIPULATOR_SIZE = 5.0; +const F32 MANIPULATOR_SELECT_SIZE = 20.0; + + + +QToolAlign::QToolAlign() +: LLTool(std::string("Align")) +{ +} + + +QToolAlign::~QToolAlign() +{ +} + + + +BOOL QToolAlign::handleMouseDown(S32 x, S32 y, MASK mask) +{ + if (mHighlightedAxis != -1) + { + align(); + } + else + { + gViewerWindow->pickAsync(x, y, mask, pickCallback); + } + + return TRUE; +} + + + +void QToolAlign::pickCallback(const LLPickInfo& pick_info) +{ + LLViewerObject* object = pick_info.getObject(); + + if (object) + { + if (object->isAvatar()) + { + return; + } + + if (pick_info.mKeyMask & MASK_SHIFT) + { + // If object not selected, select it + if ( !object->isSelected() ) + { + LLSelectMgr::getInstance()->selectObjectAndFamily(object); + } + else + { + LLSelectMgr::getInstance()->deselectObjectAndFamily(object); + } + } + else + { + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); + } + + } + else + { + if (!(pick_info.mKeyMask == MASK_SHIFT)) + { + LLSelectMgr::getInstance()->deselectAll(); + } + } + + LLSelectMgr::getInstance()->promoteSelectionToRoot(); +} + + + +void QToolAlign::handleSelect() +{ + // no parts, please + + llwarns << "in select" << llendl; + LLSelectMgr::getInstance()->promoteSelectionToRoot(); +} + + +void QToolAlign::handleDeselect() +{ +} + + +BOOL QToolAlign::findSelectedManipulator(S32 x, S32 y) +{ + mHighlightedAxis = -1; + mHighlightedDirection = 0; + + LLMatrix4 transform; + if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) + { + LLVector4 translation(mBBox.getCenterAgent()); + transform.initRotTrans(mBBox.getRotation(), translation); + LLMatrix4 cfr(OGL_TO_CFR_ROTATION); + transform *= cfr; + LLMatrix4 window_scale; + F32 zoom_level = 2.f * gAgent.mHUDCurZoom; + window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f), + LLQuaternion::DEFAULT, + LLVector3::zero); + transform *= window_scale; + } + else + { + transform.initAll(LLVector3(1.f, 1.f, 1.f), mBBox.getRotation(), mBBox.getCenterAgent()); + + LLMatrix4 projection_matrix = LLViewerCamera::getInstance()->getProjection(); + LLMatrix4 model_matrix = LLViewerCamera::getInstance()->getModelview(); + + transform *= model_matrix; + transform *= projection_matrix; + } + + + //LLRect world_view_rect = getWorldViewRectScaled(); + F32 half_width = (F32)gViewerWindow->getWindowWidth() / 2.f; + F32 half_height = (F32)gViewerWindow->getWindowHeight() / 2.f; + LLVector2 manip2d; + LLVector2 mousePos((F32)x - half_width, (F32)y - half_height); + LLVector2 delta; + + LLVector3 bbox_scale = mBBox.getMaxLocal() - mBBox.getMinLocal(); + + for (S32 axis = VX; axis <= VZ; axis++) + { + for (F32 direction = -1.0; direction <= 1.0; direction += 2.0) + { + LLVector3 axis_vector = LLVector3(0,0,0); + axis_vector.mV[axis] = direction * bbox_scale.mV[axis] / 2.0; + + LLVector4 manipulator_center = LLVector4(axis_vector); + + LLVector4 screen_center = manipulator_center * transform; + screen_center /= screen_center.mV[VW]; + + manip2d.setVec(screen_center.mV[VX] * half_width, screen_center.mV[VY] * half_height); + + delta = manip2d - mousePos; + + if (delta.magVecSquared() < MANIPULATOR_SELECT_SIZE * MANIPULATOR_SELECT_SIZE) + { + mHighlightedAxis = axis; + mHighlightedDirection = direction; + return TRUE; + } + + } + } + + return FALSE; +} + + +BOOL QToolAlign::handleHover(S32 x, S32 y, MASK mask) +{ + if (mask & MASK_SHIFT) + { + mForce = FALSE; + } + else + { + mForce = TRUE; + } + + gViewerWindow->setCursor(UI_CURSOR_ARROW); + return findSelectedManipulator(x, y); +} + + + +void setup_transforms_bbox(LLBBox bbox) +{ + // translate to center + LLVector3 center = bbox.getCenterAgent(); + gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]); + + // rotate + LLQuaternion rotation = bbox.getRotation(); + F32 angle_radians, x, y, z; + rotation.getAngleAxis(&angle_radians, &x, &y, &z); + // gGL has no rotate method (despite having translate and scale) presumably because + // its authors smoke crack. so we hack. + gGL.flush(); + glRotatef(angle_radians * RAD_TO_DEG, x, y, z); + + // scale + LLVector3 scale = bbox.getMaxLocal() - bbox.getMinLocal(); + gGL.scalef(scale.mV[VX], scale.mV[VY], scale.mV[VZ]); +} + + +void render_bbox(LLBBox bbox) +{ + glMatrixMode(GL_MODELVIEW); + gGL.pushMatrix(); + + setup_transforms_bbox(bbox); + + gGL.flush(); + gBox.render(); + + gGL.popMatrix(); +} + +void render_cone_bbox(LLBBox bbox) +{ + glMatrixMode(GL_MODELVIEW); + gGL.pushMatrix(); + + setup_transforms_bbox(bbox); + + gGL.flush(); + gCone.render(CONE_LOD_HIGHEST); + + gGL.popMatrix(); +} + + + +// the selection bbox isn't axis aligned, so we must construct one +// should this be cached in the selection manager? yes. +LLBBox get_selection_axis_aligned_bbox() +{ + LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + LLVector3 position = selection_bbox.getPositionAgent(); + + LLBBox axis_aligned_bbox = LLBBox(position, LLQuaternion(), LLVector3(), LLVector3()); + axis_aligned_bbox.addPointLocal(LLVector3()); + + // cycle over the nodes in selection + for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin(); + selection_iter != LLSelectMgr::getInstance()->getSelection()->end(); + ++selection_iter) + { + LLSelectNode *select_node = *selection_iter; + if (select_node) + { + LLViewerObject* object = select_node->getObject(); + if (object) + { + axis_aligned_bbox.addBBoxAgent(object->getBoundingBoxAgent()); + } + } + } + + + return axis_aligned_bbox; +} + + + +void QToolAlign::computeManipulatorSize() +{ + if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) + { + mManipulatorSize = MANIPULATOR_SIZE / (LLViewerCamera::getInstance()->getViewHeightInPixels() * + gAgent.mHUDCurZoom); + } + else + { + F32 distance = dist_vec(gAgent.getCameraPositionAgent(), mBBox.getCenterAgent()); + + if (distance > 0.001f) + { + // range != zero + F32 fraction_of_fov = MANIPULATOR_SIZE /LLViewerCamera::getInstance()->getViewHeightInPixels(); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians + mManipulatorSize = MANIPULATOR_SIZE * distance * tan(apparent_angle); + } + else + { + // range == zero + mManipulatorSize = MANIPULATOR_SIZE; + } + } +} + + +LLColor4 manipulator_color[3] = { LLColor4(0.7f, 0.0f, 0.0f, 0.5f), + LLColor4(0.0f, 0.7f, 0.0f, 0.5f), + LLColor4(0.0f, 0.0f, 0.7f, 0.5f) }; + + +void QToolAlign::renderManipulators() +{ + computeManipulatorSize(); + LLVector3 bbox_center = mBBox.getCenterAgent(); + LLVector3 bbox_scale = mBBox.getMaxLocal() - mBBox.getMinLocal(); + + for (S32 axis = VX; axis <= VZ; axis++) + for (F32 direction = -1.0; direction <= 1.0; direction += 2.0) + { + F32 size = mManipulatorSize; + LLColor4 color = manipulator_color[axis]; + + if ((axis == mHighlightedAxis) && (direction == mHighlightedDirection)) + { + size *= 2.0; + color *= 1.5; + } + + S32 arrows = 1; + if (mForce) + { + arrows = 2; + } + + for (S32 i = 0; i < arrows; i++) + { + LLVector3 axis_vector = LLVector3(0,0,0); + axis_vector.mV[axis] = direction * (bbox_scale.mV[axis] / 2.0 + i * (size/3.0)); + + LLVector3 manipulator_center = bbox_center + axis_vector; + + LLQuaternion manipulator_rotation; + manipulator_rotation.shortestArc(LLVector3(0,0,1), -1.0 * axis_vector); + + LLBBox manipulator_bbox = LLBBox(manipulator_center, manipulator_rotation, + LLVector3(), LLVector3()); + + manipulator_bbox.addPointLocal(LLVector3(-1, -1, -0.75) * size * 0.5); + manipulator_bbox.addPointLocal(LLVector3(1, 1, 0.75) * size * 0.5); + + gGL.color4fv(color.mV); + // sadly, gCone doesn't use gGL like gBox does (presumably because its author smokes crack) so we + // also set the raw GL color. hopefully this won't screw-up later rendering. + glColor4fv(color.mV); + + render_cone_bbox(manipulator_bbox); + } + } +} + + +void QToolAlign::render() +{ + mBBox = get_selection_axis_aligned_bbox(); + + // Draw bounding box + LLGLSUIDefault gls_ui; + LLGLEnable gl_blend(GL_BLEND); + LLGLEnable gls_alpha_test(GL_ALPHA_TEST); + LLGLDepthTest gls_depth(GL_FALSE); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // render box + LLColor4 default_normal_color( 0.7f, 0.7f, 0.7f, 0.1f ); + gGL.color4fv( default_normal_color.mV ); + + render_bbox(mBBox); + renderManipulators(); +} + +// only works for our specialized (AABB, position centered) bboxes +BOOL bbox_overlap(LLBBox bbox1, LLBBox bbox2) +{ + const F32 FUDGE = 0.001; // because of stupid SL precision/rounding + + LLVector3 delta = bbox1.getCenterAgent() - bbox2.getCenterAgent(); + + LLVector3 half_extent = (bbox1.getExtentLocal() + bbox2.getExtentLocal()) / 2.0; + + return ((fabs(delta.mV[VX]) < half_extent.mV[VX] - FUDGE) && + (fabs(delta.mV[VY]) < half_extent.mV[VY] - FUDGE) && + (fabs(delta.mV[VZ]) < half_extent.mV[VZ] - FUDGE)); +} + + + +// used to sort bboxes before packing +class BBoxCompare +{ +public: + BBoxCompare(S32 axis, F32 direction, std::map<LLPointer<LLViewerObject>, LLBBox >& bboxes) : + mAxis(axis), mDirection(direction), mBBoxes(bboxes) {} + + BOOL operator() (LLViewerObject* object1, LLViewerObject* object2) + { + LLVector3 corner1 = mBBoxes[object1].getCenterAgent() - + mDirection * mBBoxes[object1].getExtentLocal()/2.0; + + LLVector3 corner2 = mBBoxes[object2].getCenterAgent() - + mDirection * mBBoxes[object2].getExtentLocal()/2.0; + + + return mDirection * corner1.mV[mAxis] < mDirection * corner2.mV[mAxis]; + } + + S32 mAxis; + F32 mDirection; + std::map<LLPointer<LLViewerObject>, LLBBox >& mBBoxes; +}; + + +void QToolAlign::align() +{ + // no linkset parts, please + LLSelectMgr::getInstance()->promoteSelectionToRoot(); + + std::vector<LLPointer<LLViewerObject> > objects; + std::map<LLPointer<LLViewerObject>, LLBBox > original_bboxes; + + // cycle over the nodes in selection and collect them into an array + for (LLObjectSelection::root_iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); + selection_iter != LLSelectMgr::getInstance()->getSelection()->root_end(); + ++selection_iter) + { + LLSelectNode *select_node = *selection_iter; + if (select_node) + { + LLViewerObject* object = select_node->getObject(); + if (object) + { + LLVector3 position = object->getPositionAgent(); + + LLBBox bbox = LLBBox(position, LLQuaternion(), LLVector3(), LLVector3()); + bbox.addPointLocal(LLVector3()); + + // add the parent's bbox + bbox.addBBoxAgent(object->getBoundingBoxAgent()); + LLViewerObject::const_child_list_t& children = object->getChildren(); + + for (LLViewerObject::const_child_list_t::const_iterator i = children.begin(); + i != children.end(); i++) + { + // add the child's bbox + LLViewerObject* child = *i; + bbox.addBBoxAgent(child->getBoundingBoxAgent()); + } + + objects.push_back(object); + original_bboxes[object] = bbox; + } + } + } + + S32 axis = mHighlightedAxis; + F32 direction = mHighlightedDirection; + + // sort them into positional order for proper packing + BBoxCompare compare(axis, direction, original_bboxes); + sort(objects.begin(), objects.end(), compare); + + // storage for their new position after alignment - start with original position first + std::map<LLPointer<LLViewerObject>, LLBBox > new_bboxes = original_bboxes; + + // find new positions + for (S32 i = 0; i < objects.size(); i++) + { + LLBBox target_bbox = mBBox; + LLVector3 target_corner = target_bbox.getCenterAgent() - + direction * target_bbox.getExtentLocal() / 2.0; + + LLViewerObject* object = objects[i]; + + LLBBox this_bbox = original_bboxes[object]; + LLVector3 this_corner = this_bbox.getCenterAgent() - + direction * this_bbox.getExtentLocal() / 2.0; + + // for packing, we cycle over several possible positions, taking the smallest that does not overlap + F32 smallest = direction * 9999999; // 999999 guarenteed not to be the smallest + for (S32 j = 0; j <= i; j++) + { + // how far must it move? + LLVector3 delta = target_corner - this_corner; + + // new position moves only on one axis, please + LLVector3 delta_one_axis = LLVector3(0,0,0); + delta_one_axis.mV[axis] = delta.mV[axis]; + + LLVector3 new_position = this_bbox.getCenterAgent() + delta_one_axis; + + // construct the new bbox + LLBBox new_bbox = LLBBox(new_position, LLQuaternion(), LLVector3(), LLVector3()); + new_bbox.addPointLocal(this_bbox.getExtentLocal() / 2.0); + new_bbox.addPointLocal(-1.0 * this_bbox.getExtentLocal() / 2.0); + + // check to see if it overlaps the previously placed objects + BOOL overlap = FALSE; + + llwarns << "i=" << i << " j=" << j << llendl; + + if (!mForce) // well, don't check if in force mode + { + for (S32 k = 0; k < i; k++) + { + LLViewerObject* other_object = objects[k]; + LLBBox other_bbox = new_bboxes[other_object]; + + BOOL overlaps_this = bbox_overlap(other_bbox, new_bbox); + + if (overlaps_this) + { + llwarns << "overlap" << new_bbox.getCenterAgent() << other_bbox.getCenterAgent() << llendl; + llwarns << "extent" << new_bbox.getExtentLocal() << other_bbox.getExtentLocal() << llendl; + } + + overlap = (overlap || overlaps_this); + } + } + + if (!overlap) + { + F32 this_value = (new_bbox.getCenterAgent() - + direction * new_bbox.getExtentLocal() / 2.0).mV[axis]; + + if (direction * this_value < direction * smallest) + { + smallest = this_value; + // store it + new_bboxes[object] = new_bbox; + } + } + + // update target for next time through the loop + if (j < objects.size()) + { + LLBBox next_bbox = new_bboxes[objects[j]]; + target_corner = next_bbox.getCenterAgent() + + direction * next_bbox.getExtentLocal() / 2.0; + } + } + } + + + // now move them + for (S32 i = 0; i < objects.size(); i++) + { + LLViewerObject* object = objects[i]; + + LLBBox original_bbox = original_bboxes[object]; + LLBBox new_bbox = new_bboxes[object]; + + LLVector3 delta = new_bbox.getCenterAgent() - original_bbox.getCenterAgent(); + + LLVector3 original_position = object->getPositionAgent(); + LLVector3 new_position = original_position + delta; + + object->setPosition(new_position); + } + + + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); +} + + diff --git a/linden/indra/newview/qtoolalign.h b/linden/indra/newview/qtoolalign.h new file mode 100644 index 000000000..b2c18b7da --- /dev/null +++ b/linden/indra/newview/qtoolalign.h @@ -0,0 +1,50 @@ +/** + * @file qtoolalign.h + * @brief A tool to align objects + * @author Karl Stiefvater (Qarl) + * + * Karl has given permission to use this code under the terms of + * the GNU GPL v2 plus FLOSS exception and/or the GNU LGPL v2.1. + * + * Backported for Viewer 1.X code base by Jacek Antonelli. + */ + +#ifndef Q_QTOOLALIGN_H +#define Q_QTOOLALIGN_H + +#include "lltool.h" +#include "llbbox.h" + +class LLViewerObject; +class LLPickInfo; +class LLToolSelectRect; + +class QToolAlign +: public LLTool, public LLSingleton<QToolAlign> +{ +public: + QToolAlign(); + virtual ~QToolAlign(); + + virtual void handleSelect(); + virtual void handleDeselect(); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual void render(); + + static void pickCallback(const LLPickInfo& pick_info); + +private: + void align(); + void computeManipulatorSize(); + void renderManipulators(); + BOOL findSelectedManipulator(S32 x, S32 y); + + LLBBox mBBox; + F32 mManipulatorSize; + S32 mHighlightedAxis; + F32 mHighlightedDirection; + BOOL mForce; +}; + +#endif // Q_QTOOLALIGN_H diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index 3e0a5fa58..7438329e0 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -79,6 +79,9 @@ <check_box bottom_delta="-15" follows="left|top" font="SansSerifSmall" height="16" initial_value="false" label="Select faces to texture" left="4" mouse_opaque="true" name="radio select face" radio_style="true" width="114" /> + <check_box bottom_delta="-15" follows="left|top" font="SansSerifSmall" height="16" + initial_value="false" label="Align" left="4" mouse_opaque="true" + name="radio align" radio_style="true" width="114" /> <check_box bottom_delta="-19" control_name="EditLinkedParts" follows="left|top" font="SansSerifSmall" height="16" initial_value="false" label="Edit linked parts" left="4" mouse_opaque="true" From 898a2c7f27798af8587bd513a7a94bc24a270d05 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 18:52:55 -0700 Subject: [PATCH 080/239] Fixed Windows compile errors in qtoolalign.cpp (Qarl's align patch) --- linden/indra/newview/qtoolalign.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/qtoolalign.cpp b/linden/indra/newview/qtoolalign.cpp index 92cab6e50..d7f7ad011 100644 --- a/linden/indra/newview/qtoolalign.cpp +++ b/linden/indra/newview/qtoolalign.cpp @@ -393,7 +393,7 @@ void QToolAlign::render() // only works for our specialized (AABB, position centered) bboxes BOOL bbox_overlap(LLBBox bbox1, LLBBox bbox2) { - const F32 FUDGE = 0.001; // because of stupid SL precision/rounding + const F32 FUDGE = 0.001f; // because of stupid SL precision/rounding LLVector3 delta = bbox1.getCenterAgent() - bbox2.getCenterAgent(); @@ -484,7 +484,7 @@ void QToolAlign::align() std::map<LLPointer<LLViewerObject>, LLBBox > new_bboxes = original_bboxes; // find new positions - for (S32 i = 0; i < objects.size(); i++) + for (S32 i = 0; i < (S32)objects.size(); i++) { LLBBox target_bbox = mBBox; LLVector3 target_corner = target_bbox.getCenterAgent() - @@ -552,7 +552,7 @@ void QToolAlign::align() } // update target for next time through the loop - if (j < objects.size()) + if (j < (S32)objects.size()) { LLBBox next_bbox = new_bboxes[objects[j]]; target_corner = next_bbox.getCenterAgent() + @@ -563,7 +563,7 @@ void QToolAlign::align() // now move them - for (S32 i = 0; i < objects.size(); i++) + for (S32 i = 0; i < (S32)objects.size(); i++) { LLViewerObject* object = objects[i]; From a02b7f5f7385884d3832f633c0c096c685ba866b Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 18:53:57 -0700 Subject: [PATCH 081/239] Fixed Windows compile error in impprefsfonts.cpp (unsafe mix of type 'bool' and type 'BOOL' in operation) --- linden/indra/newview/impprefsfonts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/impprefsfonts.cpp b/linden/indra/newview/impprefsfonts.cpp index bf0b0284c..a4dcd345d 100644 --- a/linden/indra/newview/impprefsfonts.cpp +++ b/linden/indra/newview/impprefsfonts.cpp @@ -107,7 +107,7 @@ void ImpPrefsFonts::apply() LLCheckBoxCtrl* font_round = getChild<LLCheckBoxCtrl>("font_round"); if (font_round) { - bool round = font_round->getValue().asBoolean(); + BOOL round = font_round->getValue().asBoolean(); if (round != gSavedSettings.getBOOL("FontSizeRounding")) { gSavedSettings.setBOOL("FontSizeRounding", round); From 217abd5a4a491a2210bc05deb3fa5f84be51fc59 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 19:04:43 -0700 Subject: [PATCH 082/239] Fixed the link number label overwriting the selected objects when more than one prim is selected with Edit linked parts enabled --- linden/indra/newview/llfloatertools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index daff57375..6744faf5a 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -931,7 +931,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) childSetVisible("Strength:", land_visible); } - if (gSavedSettings.getBOOL("EditLinkedParts")) + if (gSavedSettings.getBOOL("EditLinkedParts") && LLSelectMgr::getInstance()->getEditSelection()->getObjectCount() == 1) { childSetVisible("link_num", !land_visible); } From 6f81d6f3e0c128480a90b0baa509834c4a88b28e Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 19:26:37 -0700 Subject: [PATCH 083/239] Updated the Align tool's label with info about Pack --- .../indra/newview/skins/default/xui/en-us/floater_tools.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index 7438329e0..d7a201312 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -80,8 +80,9 @@ initial_value="false" label="Select faces to texture" left="4" mouse_opaque="true" name="radio select face" radio_style="true" width="114" /> <check_box bottom_delta="-15" follows="left|top" font="SansSerifSmall" height="16" - initial_value="false" label="Align" left="4" mouse_opaque="true" - name="radio align" radio_style="true" width="114" /> + initial_value="false" label="Align (Shift to Pack)" left="4" mouse_opaque="true" + name="radio align" radio_style="true" width="114" + tool_tip="Align aligns all selected prims' edges along an axis, Pack moves all selected prims' edges so they're touching" /> <check_box bottom_delta="-19" control_name="EditLinkedParts" follows="left|top" font="SansSerifSmall" height="16" initial_value="false" label="Edit linked parts" left="4" mouse_opaque="true" From 9b21385e894844b0e4f08aa0a01ed81e07e02269 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 20:07:48 -0700 Subject: [PATCH 084/239] Added the fifth and sixth batch of German translation updates from Eryn --- .../skins/default/xui/de/floater_lagmeter.xml | 14 +++---- .../default/xui/de/floater_media_browser.xml | 4 ++ .../skins/default/xui/de/floater_mini_map.xml | 6 ++- .../skins/default/xui/de/floater_mute.xml | 4 +- .../default/xui/de/floater_mute_object.xml | 2 +- .../xui/de/floater_name_description.xml | 2 +- .../xui/de/floater_new_outfit_dialog.xml | 8 ++-- .../xui/de/floater_notifications_console.xml | 3 ++ .../skins/default/xui/de/floater_pay.xml | 8 ++-- .../default/xui/de/floater_pay_object.xml | 13 ++++--- .../default/xui/de/floater_post_process.xml | 6 +-- .../skins/default/xui/de/floater_postcard.xml | 11 +----- .../default/xui/de/floater_preferences.xml | 3 +- .../xui/de/floater_preview_notecard.xml | 34 ++++++++++++++--- .../floater_preview_notecard_keep_discard.xml | 37 +++++++++++++++---- .../default/xui/de/floater_preview_sound.xml | 4 +- .../default/xui/de/floater_report_abuse.xml | 5 ++- .../default/xui/de/floater_report_bug.xml | 8 ++-- 18 files changed, 114 insertions(+), 58 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/de/floater_lagmeter.xml b/linden/indra/newview/skins/default/xui/de/floater_lagmeter.xml index 4dd9fd6c7..f49fccae0 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_lagmeter.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_lagmeter.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="floater_lagmeter" title="Lag-Anzeige"> - <button name="client_lagmeter" tool_tip="Client-Lag-Status" /> + <button name="client_lagmeter" tool_tip="Lag-Status Client" /> <text name="client"> Client: </text> @@ -14,7 +14,7 @@ <text name="network_text"> Normal </text> - <button name="server_lagmeter" tool_tip="Server-Lag-Status" /> + <button name="server_lagmeter" tool_tip="Lag-Status Server" /> <text name="server"> Server: </text> @@ -27,7 +27,7 @@ Lag-Anzeige </text> <text name="max_width_px"> - 350 + 360 </text> <text name="min_title_msg"> Lag @@ -48,10 +48,10 @@ Normal, Fenster im Hintergrund </text> <text name="client_frame_time_critical_msg"> - Client-Frame-Rate unter [CLIENT_FRAME_RATE_CRITICAL] + Frame-Rate Client unter [CLIENT_FRAME_RATE_CRITICAL] </text> <text name="client_frame_time_warning_msg"> - Client-Frame-Rate zwischen [CLIENT_FRAME_RATE_CRITICAL] und [CLIENT_FRAME_RATE_WARNING] + Frame-Rate Client zwischen [CLIENT_FRAME_RATE_CRITICAL] und [CLIENT_FRAME_RATE_WARNING] </text> <text name="client_frame_time_normal_msg"> Normal @@ -117,10 +117,10 @@ 20 </text> <text name="server_frame_time_critical_msg"> - Simulator-Frame-Rate liegt unter [SERVER_FRAME_RATE_CRITICAL] + Frame-Rate Simulator liegt unter [SERVER_FRAME_RATE_CRITICAL] </text> <text name="server_frame_time_warning_msg"> - Simulator-Frame-Rate liegt zwischen [SERVER_FRAME_RATE_CRITICAL] und [SERVER_FRAME_RATE_WARNING] + Frame-Rate Simulator liegt zwischen [SERVER_FRAME_RATE_CRITICAL] und [SERVER_FRAME_RATE_WARNING] </text> <text name="server_frame_time_normal_msg"> Normal diff --git a/linden/indra/newview/skins/default/xui/de/floater_media_browser.xml b/linden/indra/newview/skins/default/xui/de/floater_media_browser.xml index ee2532127..3bc231ac0 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_media_browser.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_media_browser.xml @@ -6,13 +6,17 @@ <button label="Weiter" name="forward" /> <button label="Neu laden" name="reload" /> <button label="Los" name="go" /> + <button label="Zuhause" name="home" /> </layout_panel> <layout_panel name="parcel_owner_controls"> + <web_browser name="browser" /> <button label="Aktuelle URL an Parzelle senden" name="assign" /> </layout_panel> <layout_panel name="external_controls"> <button label="In meinem Browser öffnen" name="open_browser" /> <check_box label="Immer in meinem Browser öffnen" name="open_always" /> + <button label="Als Zuhause setzen" name="set_home" /> + <button label="Schließen" name="close" /> </layout_panel> </layout_stack> diff --git a/linden/indra/newview/skins/default/xui/de/floater_mini_map.xml b/linden/indra/newview/skins/default/xui/de/floater_mini_map.xml index d38925817..232ec3e31 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_mini_map.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_mini_map.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="minimap"> +<floater name="minimap" short_title="Mini-Karte"> <panel label="Minikarte" name="mini_mapview" tool_tip="(Karte mit Doppelklick öffnen)"/> + <!-- Note: panel contents are defined in panel_radar.xml --> + <panel name="RadarPanel" label="Radar" /> + <button name="toggle_radar" label="" tool_tip="Radar anzeigen oder verstecken" /> + </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_mute.xml b/linden/indra/newview/skins/default/xui/de/floater_mute.xml index 5dbb9fc6e..b39c97ac7 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_mute.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_mute.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="mute floater" title="Stummgeschaltete Einwohner und Objekte" short_title="Stummschalten-Liste"> - <scroll_list name="mutes" tool_tip="List of currently muted residents" /> +<floater name="mute floater" title="Stummgeschaltete Einwohner & Objekte" short_title="Stummschalten-Liste"> + <scroll_list name="mutes" tool_tip="Liste derzeit stummgeschalteter Einwohner" /> <button label="Einwohner stummschalten..." label_selected="Einwohner stummschalten..." name="Mute resident..." tool_tip="Wählen Sie einen Einwohner, um ihn stumm zu schalten" /> diff --git a/linden/indra/newview/skins/default/xui/de/floater_mute_object.xml b/linden/indra/newview/skins/default/xui/de/floater_mute_object.xml index 60c6ff008..bf6059f39 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_mute_object.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_mute_object.xml @@ -2,7 +2,7 @@ <floater name="mute by name" title="Objekt nach Name stummschalten"> <text name="message"> Stummschalten nach Name betrifft nur Chat und IM, keine -Sounds. Sie müssen den Objektnamen exakt angeben. +Klänge. Sie müssen den Objektnamen exakt eingeben. </text> <line_editor name="object_name"> Objektname diff --git a/linden/indra/newview/skins/default/xui/de/floater_name_description.xml b/linden/indra/newview/skins/default/xui/de/floater_name_description.xml index f45b1e0b3..608c3eb7a 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_name_description.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_name_description.xml @@ -7,5 +7,5 @@ Beschreibung: </text> <button label="Abbrechen" name="cancel_btn" width="80" /> - <button label="Hochladen ([AMOUNT] L$)" name="ok_btn" width="120" /> + <button label="Hochladen ([UPLOADFEE])" name="ok_btn" width="120" /> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_new_outfit_dialog.xml b/linden/indra/newview/skins/default/xui/de/floater_new_outfit_dialog.xml index 73c6760be..dbb96ef2c 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_new_outfit_dialog.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_new_outfit_dialog.xml @@ -16,6 +16,9 @@ <check_box label="Unterhemd" name="checkbox_Undershirt" left="90"/> <check_box label="Unterhose" name="checkbox_Underpants" left="90"/> <check_box label="Rock" name="checkbox_Skirt" left="90"/> + <check_box label="Tätowierung" name="checkbox_Tattoo" left="90"/> + <check_box label="Transparenz" name="checkbox_Alpha" left="90"/> + <check_box label="Brust" name="checkbox_Chest" left="190"/> <check_box label="Schädel" name="checkbox_Skull" left="190"/> <check_box label="Linke Schulter" name="checkbox_Left Shoulder" left="190"/> @@ -59,9 +62,8 @@ </text> <text type="string" length="1" name="Outfits are folders that contain clothing and body parts. Drag an outfit folder onto your avatar to put it on. "Make New Outfit" makes a new folder and saves copies of the items you are now wearing into it."> - Outfits sind Ordner, die Kleider und Körperteile enthalten. -Ziehen Sie einen Outfit-Ordner auf Ihren Avatar, um ihn anzuziehen. - + Outfits sind Ordner, die Kleidung und Körperteile enthalten. Ziehen Sie einen Outfit-Ordner auf Ihren Avatar, um ihn anzuziehen. + „Neues Outfit“ erstellt einen neuen Ordner und speichert darin Kopien der Objekte, die Sie gerade tragen. </text> diff --git a/linden/indra/newview/skins/default/xui/de/floater_notifications_console.xml b/linden/indra/newview/skins/default/xui/de/floater_notifications_console.xml index a1cd69899..14318dd9e 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_notifications_console.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_notifications_console.xml @@ -2,4 +2,7 @@ <floater name="notifications_console" title="Konsole: Meldungen"> <combo_box label="Meldungsart auswählen" name="notification_types" width="412" /> <button label="Hinzufügen" name="add_notification" left="417" width="78" /> + <button name="reload_notifications" left="497" width="85" label="Alle Neuladen"/> + <layout_stack name="notification_channels"> + </layout_stack> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_pay.xml b/linden/indra/newview/skins/default/xui/de/floater_pay.xml index dc38697fe..a98894d60 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_pay.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_pay.xml @@ -5,10 +5,10 @@ Schnellzahlung: </text> - <button name="fastpay 1" label="1 L$" left="115" /> - <button name="fastpay 5" label="5 L$" /> - <button name="fastpay 10" label="10 L$" left="115" /> - <button name="fastpay 20" label="20 L$" /> + <button name="fastpay 1" label="1 [CURRENCY]" left="115" /> + <button name="fastpay 5" label="5 [CURRENCY]" /> + <button name="fastpay 10" label="10 [CURRENCY]" left="115" /> + <button name="fastpay 20" label="20 [CURRENCY]" /> <text name="amount text"> Betrag: diff --git a/linden/indra/newview/skins/default/xui/de/floater_pay_object.xml b/linden/indra/newview/skins/default/xui/de/floater_pay_object.xml index 55ad7352b..07dee3717 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_pay_object.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_pay_object.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="Give Money"> +<floater name="Give Money" title="[PAY TYPE] [FIRST] [LAST> <string name="pay group"> Gruppe bezahlen: @@ -16,14 +16,17 @@ Schnellzahlung: </text> - <button name="fastpay 1" label="1 L$" left="115" /> - <button name="fastpay 5" label="5 L$" /> - <button name="fastpay 10" label="10 L$" left="115" /> - <button name="fastpay 20" label="20 L$" /> + <button name="fastpay 1" label="1 [CURRENCY]" left="115" /> + <button name="fastpay 5" label="5 [CURRENCY]" /> + <button name="fastpay 10" label="10 [CURRENCY]" left="115" /> + <button name="fastpay 20" label="20 [CURRENCY]" /> <text name="amount text"> Betrag: </text> + <text name="currency text"> + [CURRENCY] + </text> <button name="pay btn" label="Zahlen" /> <button name="cancel btn" label="Abbrechen" /> diff --git a/linden/indra/newview/skins/default/xui/de/floater_post_process.xml b/linden/indra/newview/skins/default/xui/de/floater_post_process.xml index e10806d25..4baad6927 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_post_process.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_post_process.xml @@ -32,16 +32,16 @@ Rauschen-Stärke </text> </panel> - <panel label="Bloom" name="wmiBloomPanel"> + <panel label="Schleier" name="wmiBloomPanel"> <check_box label="Ein" name="wmiBloomToggle" /> <text name="wmiBloomExtractText"> Luminanz-Extraktion </text> <text name="wmiBloomSizeText"> - Bloom-Größe + Schleier-Größe </text> <text name="wmiBloomStrengthText"> - Bloom-Stärke + Schleier-Stärke </text> </panel> <panel label="Extras" name="Extras"> diff --git a/linden/indra/newview/skins/default/xui/de/floater_postcard.xml b/linden/indra/newview/skins/default/xui/de/floater_postcard.xml index 639a8ffdd..90a3c3d41 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_postcard.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_postcard.xml @@ -22,18 +22,11 @@ <text_editor name="msg_form"> Nachricht hier eingeben. </text_editor> - <check_box label="Im Web veröffentlichen" name="allow_publish_check" - tool_tip="Veröffentlicht diese Postkarte im Web." /> - <check_box label="Ab-18-Inhalt" name="mature_check" - tool_tip="Diese Postkarte enthält nicht jugendfreie Inhalte." /> - <button label="?" name="publish_help_btn" /> - <text name="fine_print"> - Wenn sich der Empfänger bei SL anmeldet, erhalten Sie einen Empfehlungsbonus. - </text> + <button label="Abbrechen" name="cancel_btn" /> <button label="Senden" name="send_btn" /> <text name="default_subject"> - Postkarte aus Second Life. + Postkarte aus [GRID_NAME]. </text> <text name="default_message"> Sehen Sie hier! diff --git a/linden/indra/newview/skins/default/xui/de/floater_preferences.xml b/linden/indra/newview/skins/default/xui/de/floater_preferences.xml index 5f68282b9..ac18f2880 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_preferences.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_preferences.xml @@ -1,8 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="Preferences" title="Einstellungen"> +<floater name="Preferences" title="Voreinstellungen"> <button label="OK" label_selected="OK" name="OK" /> <button label="Abbrechen" label_selected="Abbrechen" name="Cancel" /> <button label="Übernehmen" label_selected="Übernehmen" name="Apply" /> - <button label="Info" label_selected="Info" name="About..." /> <button label="Hilfe" label_selected="Hilfe" name="Help" /> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_preview_notecard.xml b/linden/indra/newview/skins/default/xui/de/floater_preview_notecard.xml index 370f242dd..7925ed6f9 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_preview_notecard.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_preview_notecard.xml @@ -1,16 +1,40 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="preview notecard" title="Hinweis:"> - <button label="Speichern" label_selected="Speichern" name="Save" /> <text type="string" length="1" name="desc txt"> Beschreibung: </text> + + <menu_bar name="motecard_menu"> + <menu name="File"> + <menu_item_call label="Speichern" name="Save Menu" shortcut="control|S" /> + <menu_item_separator /> + <menu_item_call label="Text Exportieren..." name="Export Text..." /> + <menu_item_call label="Text Importieren..." name="Import Text..." /> + </menu> + <menu name="Edit"> + <menu_item_call label="Rückgängig" name="Undo" /> + <menu_item_call label="Wiederherstellen" name="Redo" width="139" /> + <menu_item_separator label="-----------" name="separator1" width="139" /> + <menu_item_call label="Ausschneiden" name="Cut" /> + <menu_item_call label="Kopieren" name="Copy" /> + <menu_item_call label="Einfügen" name="Paste" /> + <menu_item_separator label="-----------" name="separator2" width="139" /> + <menu_item_call label="Alle auswählen" name="Select All" width="139" /> + <menu_item_call label="Deselektieren" name="Deselect" width="139" /> + <menu_item_separator label="-----------" name="separator3" width="139" /> + <menu_item_call label="Suchen / Ersetzen..." + name="Search / Replace..." width="139" /> + </menu> + </menu_bar> + <text_editor type="string" length="1" name="Notecard Editor"> Wird geladen... </text_editor> - <text name="no_object"> + <button label="Sichern" label_selected="Sichern" name="Save" /> + <string name="no_object"> Es wurde kein Objekt gefunden, das diese Notiz enthält. - </text> - <text name="not_allowed"> + </string> + <string name="not_allowed"> Sie können diese Notiz nicht anzeigen. - </text> + </string> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_preview_notecard_keep_discard.xml b/linden/indra/newview/skins/default/xui/de/floater_preview_notecard_keep_discard.xml index 1faf82bc6..7d068fe07 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_preview_notecard_keep_discard.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_preview_notecard_keep_discard.xml @@ -1,16 +1,39 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="preview_notecard"> - <text_editor type="string" length="1" name="Notecard Editor"> - Wird geladen... - </text_editor> +<floater name="preview_notecard" title="Notiz:" > <text type="string" length="1" name="desc txt"> Beschreibung: </text> + <menu_bar name="motecard_menu"> + <menu name="File"> + <menu_item_call label="Sichern" name="Save Menu" /> + <menu_item_separator /> + <menu_item_call label="Text Exportieren..." name="Export Text..." /> + <menu_item_call label="Text Importieren..." name="Import Text..." /> + </menu> + <menu name="Edit"> + <menu_item_call label="Rückgängig" name="Undo" width="139" /> + <menu_item_call label="Wiederherstellen" name="Redo" width="139" /> + <menu_item_separator label="-----------" name="separator1" width="139" /> + <menu_item_call label="Ausschneiden" name="Cut" width="139" /> + <menu_item_call label="Kopieren" name="Copy" width="139" /> + <menu_item_call label="Einfügen" name="Paste" width="139" /> + <menu_item_separator label="-----------" name="separator2" width="139" /> + <menu_item_call label="Alle auswählen" name="Select All" width="139" /> + <menu_item_call label="Deselektieren" name="Deselect" width="139" /> + <menu_item_separator label="-----------" name="separator3" width="139" /> + <menu_item_call label="Suchen / Ersetzen..." + name="Search / Replace..." width="139" /> + </menu> + </menu_bar> + <text_editor type="string" length="1" name="Notecard Editor"> + Wird geladen... + </text_editor> <button label="Behalten" label_selected="Behalten" name="Keep" /> + <button label="Sichern" label_selected="Sichern" name="Save" /> <button label="Verwerfen" label_selected="Verwerfen" name="Discard" /> - <text name="no_object"> - Es wurde kein Objekt gefunden, das diese Notiz enthält: - </text> + <string name="no_object"> + Es wurde kein Objekt gefunden, das diese Notiz enthält. + </string> <string name="not_allowed"> Sie können diese Notiz nicht anzeigen. </string> diff --git a/linden/indra/newview/skins/default/xui/de/floater_preview_sound.xml b/linden/indra/newview/skins/default/xui/de/floater_preview_sound.xml index fd0a824c0..64e3e565d 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_preview_sound.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_preview_sound.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="preview_sound"> +<floater name="preview_sound" width="310"> <text type="string" length="1" name="desc txt"> Beschreibung: </text> @@ -8,5 +8,5 @@ tool_tip="Gibt diesen Sound so wieder, dass andere ihn hören können." /> <button label="Lokal wiedergeben" label_selected="Lokal wiedergeben" name="Sound audition btn" - tool_tip="Gibt diesen Sound so wieder, dass nur Sie ihn hören." /> + tool_tip="Gibt diesen Sound so wieder, dass nur Sie ihn hören." width="130" /> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_report_abuse.xml b/linden/indra/newview/skins/default/xui/de/floater_report_abuse.xml index 6a7246d1e..048066e53 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_report_abuse.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_report_abuse.xml @@ -119,6 +119,7 @@ dann auf das Objekt: <combo_item name="Indecency__Broadly_offensive_content_or_conduct"> Unanständigkeit > Anstößige Inhalte oder Handlungen in der Öffentlichkeit </combo_item> +<!-- 58 = deprecated by AO --> <combo_item name="Indecency__Inappropriate_avatar_name"> Unanständigkeit > Anstößiger Avatarname </combo_item> @@ -138,7 +139,7 @@ dann auf das Objekt: Intoleranz </combo_item> <combo_item name="Land__Abuse_of_sandbox_resources"> - Land > Missbrauch der Sandbox-Ressourcen + Land > Missbrauch von Sandbox-Ressourcen </combo_item> <combo_item name="Land__Encroachment__Objects_textures"> Land > Unbefugte Nutzung > Objekte/Texturen @@ -160,7 +161,7 @@ dann auf das Objekt: Name des Beschuldigten: </text> <button label="Einwohner auswählen" label_selected="" name="select_abuser" tool_tip="Den Namen des Beschuldigten aus einer Liste wählen"/> - <check_box label="Name des Täters ist nicht bekannt" name="omit_abuser_name" tool_tip="Wählen Sie diese Option, wenn Ihnen der Name des Täters unbekannt ist"/> + <check_box label="Name des Täters unbekannt" name="omit_abuser_name" tool_tip="Wählen Sie diese Option, wenn Ihnen der Name des Täters nicht bekannt ist"/> <text name="abuser_name_title2"> Ort des Missbrauchs: </text> diff --git a/linden/indra/newview/skins/default/xui/de/floater_report_bug.xml b/linden/indra/newview/skins/default/xui/de/floater_report_bug.xml index 2c8734ef5..fdcde2040 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_report_bug.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_report_bug.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="bug_reporter" title="Fehler melden"> + <texture_picker label="" name="screenshot"/> + <check_box bottom_delta="-20" label="Screenshot einschließen" name="screen_check"/> <text name="reporter_title"> Melder: </text> @@ -24,13 +26,11 @@ dann auf das Objekt: <text name="owner_name_label"> Eigentümer: </text> - <check_box label="Screenshot einschließen" name="screen_check" /> - <texture_picker label="Arbeitet..." name="screenshot" /> <text name="owner_name"> Hendrerit Vulputate </text> <combo_box name="category_combo" - tool_tip="Category -- select the category that best describes this report"> + tool_tip="Kategorie -- wählen Sie die Kategorie aus, die am besten auf diesen Bericht zutrifft"> <combo_item name="Selectcategory"> Kategorie auswählen </combo_item> @@ -74,7 +74,7 @@ dann auf das Objekt: Skript </combo_item> <combo_item name="Sound"> - Sound + Klang </combo_item> <combo_item name="Stipends"> Stipendium From 27df1e960d9c8c7da63421ece10eb22f097ae518 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 20:28:37 -0700 Subject: [PATCH 085/239] Changed version to Experimental 2010.10.23 --- linden/indra/newview/app_settings/viewerversion.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/app_settings/viewerversion.xml b/linden/indra/newview/app_settings/viewerversion.xml index f50b59420..ab4b720e4 100644 --- a/linden/indra/newview/app_settings/viewerversion.xml +++ b/linden/indra/newview/app_settings/viewerversion.xml @@ -20,6 +20,6 @@ need to be changed manually - MC <viewer version_patch="0" /> <!--string--> - <viewer version_test="Experimental 2010.10.17" /> + <viewer version_test="Experimental 2010.10.23" /> </viewer_version> From 7b589ed52013e212b12061f791996a17452e2a68 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 21:56:20 -0700 Subject: [PATCH 086/239] Fixed xml files from the German translation missing from the repo --- .../xui/de/floater_local_asset_browse.xml | 94 +++++++++++++++++++ .../default/xui/de/floater_prim_import.xml | 4 + .../default/xui/de/floater_rlv_behaviour.xml | 8 ++ 3 files changed, 106 insertions(+) create mode 100644 linden/indra/newview/skins/default/xui/de/floater_local_asset_browse.xml create mode 100644 linden/indra/newview/skins/default/xui/de/floater_prim_import.xml create mode 100644 linden/indra/newview/skins/default/xui/de/floater_rlv_behaviour.xml diff --git a/linden/indra/newview/skins/default/xui/de/floater_local_asset_browse.xml b/linden/indra/newview/skins/default/xui/de/floater_local_asset_browse.xml new file mode 100644 index 000000000..45a19baa6 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/de/floater_local_asset_browse.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- Local Asset Browser: xui --> +<!-- floater definition start --> + +<floater + name="local_bitmap_browser_floater" + title="Lokal Textur-Eigenschaften" + > + + <button + name="add_btn" + label="Hinzufügen" + /> + <button + name="del_btn" + label="Entfernen" + /> + <button + name="upload_btn" + label="Bild hochladen ([UPLOADFEE])..." + /> + + <scroll_list + name="bitmap_list" + > + <column name="bitmap_name" label="Name" dynamicwidth="true" /> + <column name="bitmap_uuid" label="UUID" width="240" /> + </scroll_list> + + <text name="path_caption_text" + > + Lokaler Pfad: + </text> + + <text name="uuid_caption_text" + > + Lokale UUID: + </text> + + <texture_picker + label="Textur" + name="texture_view" + /> + + <check_box + label="Aktualisierungscheck" + name="keep_updating_checkbox" + tool_tip="Periodische Checks ein- oder ausschalten, ob die Quelle auf der Festplatte aktualisiert wurde" + /> + + <combo_box + name="type_combobox" + > + + <combo_item name="type_texture" value="type_texture"> + Textur + </combo_item> + + <combo_item name="type_sculptie" value="type_sculptie"> + Sculptmap + </combo_item> + + <combo_item name="type_layer" value="type_layer"> + Kleidung + </combo_item> + + </combo_box> + + <text name="time_caption_text" + > + Zeit: + </text> + + <text name="time_text" + > + (Hier Datum) + </text> + + <text name="link_caption_text" + > + Link: + </text> + + <text name="link_text" + > + (Linkstatus) + </text> + + <text name="name_caption_text" + > + Name: + </text> + +</floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_prim_import.xml b/linden/indra/newview/skins/default/xui/de/floater_prim_import.xml new file mode 100644 index 000000000..0e5c6b1b0 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/de/floater_prim_import.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="Import" title="Fortschritt des Imports"> + <text name="name_label"> Fortschritt </text> +</floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_rlv_behaviour.xml b/linden/indra/newview/skins/default/xui/de/floater_rlv_behaviour.xml new file mode 100644 index 000000000..a08d9b205 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/de/floater_rlv_behaviour.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="rlvBehaviours" + title="Active RLV-Beschränkungen"> + <scroll_list name="behaviour_list"> + <column label="Beschränkung" name="behaviour" /> + <column label="Objektname" name="name" /> + </scroll_list> +</floater> \ No newline at end of file From 06bbe1bb663e099c5b15c07e8d8433ec065edcc3 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 23 Oct 2010 23:54:22 -0700 Subject: [PATCH 087/239] #637: teleport target location in local chat, ported from Phoenix by Ansariel Hiller --- linden/indra/newview/llagent.cpp | 65 ++++++++++++++++++++++++ linden/indra/newview/llagent.h | 14 +++++ linden/indra/newview/llviewermessage.cpp | 56 ++++++++++++++++++++ linden/indra/newview/llworldmap.cpp | 7 +++ 4 files changed, 142 insertions(+) diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index eb5cf9bce..0a0374c8e 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -226,6 +226,16 @@ LLAgent gAgent; // BOOL LLAgent::sPhantom = FALSE; +BOOL LLAgent::lure_show = FALSE; +std::string LLAgent::lure_name; +LLVector3d LLAgent::lure_posglobal; +U16 LLAgent::lure_global_x; +U16 LLAgent::lure_global_y; +int LLAgent::lure_x; +int LLAgent::lure_y; +int LLAgent::lure_z; +std::string LLAgent::lure_maturity; + const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f; std::map<std::string, std::string> LLAgent::sTeleportErrorMessages; @@ -8080,5 +8090,60 @@ LLVector3 LLAgent::getLastCoords() return mLastCoordinates; } +void LLAgent::showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity) +{ + const LLVector3d posglobal = LLVector3d(F64(global_x), F64(global_y), F64(0)); + LLSimInfo* siminfo; + siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(posglobal); + std::string sim_name; + LLWorldMap::getInstance()->simNameFromPosGlobal( posglobal, sim_name ); + + if(siminfo) + { + + llinfos << fromname << "'s teleport lure is to " << sim_name.c_str() << " (" << maturity << ")" << llendl; + std::string url = LLURLDispatcher::buildSLURL(sim_name.c_str(), S32(x), S32(y), S32(z)); + std::string msg; + msg = llformat("%s's teleport lure is to %s", fromname.c_str(), url.c_str()); + if(maturity != "") + msg.append(llformat(" (%s)", maturity.c_str())); + LLChat chat(msg); + LLFloaterChat::addChat(chat); + } + else + { + LLAgent::lure_show = TRUE; + LLAgent::lure_name = fromname; + LLAgent::lure_posglobal = posglobal; + LLAgent::lure_global_x = U16(global_x / 256); + LLAgent::lure_global_y = U16(global_y / 256); + LLAgent::lure_x = x; + LLAgent::lure_y = y; + LLAgent::lure_z = z; + LLAgent::lure_maturity = maturity; + LLWorldMap::getInstance()->sendMapBlockRequest(lure_global_x, lure_global_y, lure_global_x, lure_global_y, true); + } +} + +void LLAgent::onFoundLureDestination() +{ + LLAgent::lure_show = FALSE; + LLSimInfo* siminfo; + siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(LLAgent::lure_posglobal); + std::string sim_name; + LLWorldMap::getInstance()->simNameFromPosGlobal( LLAgent::lure_posglobal, sim_name ); + + if(siminfo && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))) + { + llinfos << LLAgent::lure_name << " is offering a TP to " << sim_name.c_str() << " (" << LLAgent::lure_maturity << ")" << llendl; + std::string url = LLURLDispatcher::buildSLURL(sim_name.c_str(), S32(LLAgent::lure_x), S32(LLAgent::lure_y), S32(LLAgent::lure_z)); + std::string msg; + msg = llformat("%s is offering a TP to %s", LLAgent::lure_name.c_str(), url.c_str()); + if(LLAgent::lure_maturity != "") + msg.append(llformat(" (%s)", LLAgent::lure_maturity.c_str())); + LLChat chat(msg); + LLFloaterChat::addChat(chat); + } +} // EOF diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 141c72c3d..03b00453e 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -767,6 +767,17 @@ class LLAgent : public LLObservable BOOL mInitialized; + static BOOL lure_show; + static std::string lure_name; + static LLVector3d lure_posglobal; + static U16 lure_global_x; + static U16 lure_global_y; + static int lure_x; + static int lure_y; + static int lure_z; + static std::string lure_maturity; + + S32 mNumPendingQueries; S32* mActiveCacheQueries; @@ -782,6 +793,9 @@ class LLAgent : public LLObservable LLFrameTimer mDoubleTapRunTimer; EDoubleTapRunMode mDoubleTapRunMode; + static void showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity); + static void onFoundLureDestination(); + private: bool mbTeleportKeepsLookAt; bool mbAlwaysRun; // should the avatar run by default rather than walk diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index dbf9d725e..d3ca5f6f7 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -2520,6 +2520,62 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) else { LLNotifications::instance().add("TeleportOffered", args, payload); + if(binary_bucket_size) + { + char* dest = new char[binary_bucket_size]; + strncpy(dest, (char*)binary_bucket, binary_bucket_size-1); /* Flawfinder: ignore */ + dest[binary_bucket_size-1] = '\0'; + + llinfos << "IM_LURE_USER binary_bucket " << dest << llendl; + + std::string str(dest); + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep("|","",boost::keep_empty_tokens); + tokenizer tokens(str, sep); + tokenizer::iterator iter = tokens.begin(); + std::string global_x_str(*iter++); + std::string global_y_str(*iter++); + std::string x_str(*iter++); + std::string y_str(*iter++); + std::string z_str(*iter++); + // skip what I think must be LookAt + if(iter != tokens.end()) + iter++; // x + if(iter != tokens.end()) + iter++; // y + if(iter != tokens.end()) + iter++; // z + std::string mat_str(""); + if(iter != tokens.end()) + mat_str.assign(*iter++); + mat_str = utf8str_trim(mat_str); + + llinfos << "IM_LURE_USER tokenized " << global_x_str << "|" << global_y_str << "|" << x_str << "|" << y_str << "|" << z_str << "|" << mat_str << llendl; + + std::istringstream gxstr(global_x_str); + int global_x; + gxstr >> global_x; + + std::istringstream gystr(global_y_str); + int global_y; + gystr >> global_y; + + std::istringstream xstr(x_str); + int x; + xstr >> x; + + std::istringstream ystr(y_str); + int y; + ystr >> y; + + std::istringstream zstr(z_str); + int z; + zstr >> z; + + llinfos << "IM_LURE_USER parsed " << global_x << "|" << global_y << "|" << x << "|" << y << "|" << z << "|" << mat_str << llendl; + + gAgent.showLureDestination(name, global_x, global_y, x, y, z, mat_str); + } } // [/RLVa:KB] //LLNotifications::instance().add("TeleportOffered", args, payload); diff --git a/linden/indra/newview/llworldmap.cpp b/linden/indra/newview/llworldmap.cpp index c6242f6af..01a66d4cb 100644 --- a/linden/indra/newview/llworldmap.cpp +++ b/linden/indra/newview/llworldmap.cpp @@ -735,6 +735,13 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) callback(handle, LLWorldMap::getInstance()->mSLURL, image_id, LLWorldMap::getInstance()->mSLURLTeleport); } } + if(LLAgent::lure_show) + { + if((x_regions == LLAgent::lure_global_x) && (y_regions == LLAgent::lure_global_y)) + { + gAgent.onFoundLureDestination(); + } + } } if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); From acc8af5913dd22fb67dbf930992b681596432241 Mon Sep 17 00:00:00 2001 From: elektrahesse <sl@ircsystem.net> Date: Sun, 24 Oct 2010 12:59:24 +0200 Subject: [PATCH 088/239] Updated Info.plist for 2010.10.23 release date --- linden/indra/newview/Info-Imprudence.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/Info-Imprudence.plist b/linden/indra/newview/Info-Imprudence.plist index 3fe2000ba..e7dc82d76 100644 --- a/linden/indra/newview/Info-Imprudence.plist +++ b/linden/indra/newview/Info-Imprudence.plist @@ -32,7 +32,7 @@ </dict> </array> <key>CFBundleVersion</key> - <string>Experimental 2010.10.17</string> + <string>Experimental 2010.10.23</string> <key>CSResourcesFileMapped</key> <true/> </dict> From c6aac7d81149a50f895a0f06fdf08b65c8e4bd8c Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Mon, 25 Oct 2010 02:19:54 +0200 Subject: [PATCH 089/239] Added missing textures to artwork. Also fixed textures.xml by adding media_panel_scrollbg.png which is used in the MediaHUD as one of the media_*.png textures, but was lacking from textures.xml. --- .../newview/skins/default/textures/textures.xml | 1 + linden/install.xml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/linden/indra/newview/skins/default/textures/textures.xml b/linden/indra/newview/skins/default/textures/textures.xml index f2189a450..60fb4e062 100644 --- a/linden/indra/newview/skins/default/textures/textures.xml +++ b/linden/indra/newview/skins/default/textures/textures.xml @@ -396,5 +396,6 @@ <texture name="media_btn_scrollup.png"/> <texture name="media_btn_stoploading.png"/> <texture name="media_panel_divider.png"/> + <texture name="media_panel_scrollbg.png"/> </textures> diff --git a/linden/install.xml b/linden/install.xml index 09a58e719..c564b2bc8 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -179,30 +179,30 @@ <key>darwin</key> <map> <key>md5sum</key> - <string>506d8203676998eab8ccbaaf7bc7415f</string> + <string>68fedbc3638d7f081edc59bdccbeffc2</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/extras/imprudence-artwork-20101017.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> </map> <key>linux</key> <map> <key>md5sum</key> - <string>506d8203676998eab8ccbaaf7bc7415f</string> + <string>68fedbc3638d7f081edc59bdccbeffc2</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/extras/imprudence-artwork-20101017.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> </map> <key>linux64</key> <map> <key>md5sum</key> - <string>506d8203676998eab8ccbaaf7bc7415f</string> + <string>68fedbc3638d7f081edc59bdccbeffc2</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/extras/imprudence-artwork-20101017.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> </map> <key>windows</key> <map> <key>md5sum</key> - <string>506d8203676998eab8ccbaaf7bc7415f</string> + <string>68fedbc3638d7f081edc59bdccbeffc2</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/extras/imprudence-artwork-20101017.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> </map> </map> </map> From 164e5c28410df241aa67993c15c4393f42031774 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Mon, 25 Oct 2010 17:02:55 -0500 Subject: [PATCH 090/239] New Japanese UI translations from Hiroshi Kumaki. --- .../skins/default/xui/ja/menu_mini_map.xml | 3 + .../skins/default/xui/ja/menu_viewer.xml | 397 +++++++++++++++--- .../skins/default/xui/ja/notifications.xml | 24 ++ .../skins/default/xui/ja/panel_avatar.xml | 9 +- .../skins/default/xui/ja/panel_groups.xml | 2 + .../skins/default/xui/ja/panel_mini_map.xml | 11 + .../xui/ja/panel_preferences_advanced.xml | 31 +- .../xui/ja/panel_preferences_audio.xml | 7 +- .../xui/ja/panel_preferences_fonts.xml | 9 + .../xui/ja/panel_preferences_general.xml | 8 + .../xui/ja/panel_preferences_graphics1.xml | 1 + .../default/xui/ja/panel_preferences_im.xml | 8 +- .../xui/ja/panel_preferences_input.xml | 31 ++ .../xui/ja/panel_preferences_popups.xml | 1 + .../skins/default/xui/ja/panel_radar.xml | 59 +++ .../xui/ja/panel_windlight_controls.xml | 6 + 16 files changed, 547 insertions(+), 60 deletions(-) create mode 100644 linden/indra/newview/skins/default/xui/ja/panel_preferences_fonts.xml create mode 100644 linden/indra/newview/skins/default/xui/ja/panel_radar.xml create mode 100644 linden/indra/newview/skins/default/xui/ja/panel_windlight_controls.xml diff --git a/linden/indra/newview/skins/default/xui/ja/menu_mini_map.xml b/linden/indra/newview/skins/default/xui/ja/menu_mini_map.xml index c8828a50b..bdd63e834 100644 --- a/linden/indra/newview/skins/default/xui/ja/menu_mini_map.xml +++ b/linden/indra/newview/skins/default/xui/ja/menu_mini_map.xml @@ -3,6 +3,9 @@ <menu_item_call label="ズーム(近)" name="Zoom Close"/> <menu_item_call label="ズーム(中)" name="Zoom Medium"/> <menu_item_call label="ズーム(é ï¼‰" name="Zoom Far"/> + <menu_item_check label="カメラを中央ã«" name="Center on Camera"/> + <menu_item_check label="ミニマップを回転" name="Rotate Mini-Map"/> + <menu_itemcall label="世界地図を表示" name="Show Map"/> <menu_item_call label="追跡をやã‚ã‚‹" name="Stop Tracking"/> <menu_item_call label="プロフィール..." name="Profile"/> </menu> diff --git a/linden/indra/newview/skins/default/xui/ja/menu_viewer.xml b/linden/indra/newview/skins/default/xui/ja/menu_viewer.xml index c69c2e305..bc263bbe4 100644 --- a/linden/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -1,26 +1,39 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu_bar name="Main Menu"> + + + <!-- ファイル --> + <menu label="ファイル" name="File"> <tearoff_menu label="~~~~~~~~~~~" name="~~~~~~~~~~~"/> - <menu label="アップロード" name="upload"> - <menu_item_call label="ç”»åƒ ï¼ˆL$[COST])..." name="Upload Image"/> - <menu_item_call label="サウンド (L$[COST])..." name="Upload Sound"/> - <menu_item_call label="アニメーション (L$[COST])..." name="Upload Animation"/> - <menu_item_call label="一括 (ファイルã«ã¤ãL$[COST])..." name="Bulk Upload"/> + <menu label="アップロード" name="Upload"> + <menu_item_call label="ç”»åƒ ï¼ˆ[UPLOADFEE])..." name="Upload Image"/> + <menu_item_call label="サウンド ([UPLOADFEE])..." name="Upload Sound"/> + <menu_item_call label="アニメーション ([UPLOADFEE])..." name="Upload Animation"/> + <menu_item_call label="一括 (ファイルã«ã¤ã[UPLOADFEE])..." name="Bulk Upload"/> <menu_item_separator label="-----------" name="separator"/> <menu_item_call label="デフォルト権é™ã®è¨­å®š..." name="perm prefs"/> </menu> <menu_item_separator label="-----------" name="separator"/> + <menu_item_call label="オブジェクトã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ..." name="Import"/> + <menu_item_call label="インãƒãƒ¼ãƒˆã¨ã‚¢ãƒƒãƒ—ロード... (テクスãƒãƒ£ã«ã¤ã[UPLOADFEE])" name="ImportUpload"/> + <menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ..." name="Export"/> + <menu_item_separator label="-----------" name="separator2"/> + <menu_item_call label="å…¨ã¦ã®ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’最å°åŒ–" name="Minimize All Windows"/> <menu_item_call label="ウィンドウを閉ã˜ã‚‹" name="Close Window"/> <menu_item_call label="å…¨ã¦ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‰ã˜ã‚‹" name="Close All Windows"/> - <menu_item_separator label="-----------" name="separator2"/> - <menu_item_call label="テクスãƒãƒ£ãƒ¼ã‚’別åã§ä¿å­˜..." name="Save Texture As..."/> <menu_item_separator label="-----------" name="separator3"/> + <menu_item_call label="テクスãƒãƒ£ãƒ¼ã‚’別åã§ä¿å­˜..." name="Save Texture As..."/> + <menu_item_separator label="-----------" name="separator4"/> <menu_item_call label="スナップショットを撮る" name="Take Snapshot"/> <menu_item_call label="スナップショットをディスクã«ä¿å­˜" name="Snapshot to Disk"/> - <menu_item_separator label="-----------" name="separator4"/> + <menu_item_separator label="-----------" name="separator5"/> <menu_item_call label="終了" name="Quit"/> </menu> + + + <!-- 編集 --> + <menu label="編集" name="Edit"> <menu_item_call label="å…ƒã«æˆ»ã™" name="Undo"/> <menu_item_call label="やり直ã—" name="Redo"/> @@ -51,16 +64,21 @@ <menu_item_call label="スカート" name="Skirt"/> <menu_item_call label="ã™ã¹ã¦ã®æœ" name="All Clothes"/> </menu> + <menu_item_call label="容姿ã®å†æç”»" name="Refresh Appearance"/> <menu_item_separator label="-----------" name="separator6"/> - <menu_item_call label="ジェスãƒãƒ£ãƒ¼â€¦" name="Gestures..."/> + <menu_item_call label="ジェスãƒãƒ£ãƒ¼" name="Gestures"/> <menu_item_call label="プロフィール..." name="Profile..."/> <menu_item_call label="容姿..." name="Appearance..."/> <menu_item_separator label="-----------" name="separator7"/> - <menu_item_check label="フレンド..." name="Friends..."/> - <menu_item_call label="グループ..." name="Groups..."/> + <menu_item_check label="フレンド" name="Friends"/> + <menu_item_call label="グループ" name="Groups"/> <menu_item_separator label="-----------" name="separator8"/> <menu_item_call label="環境設定..." name="Preferences..."/> </menu> + + + <!-- 表示 --> + <menu label="表示" name="View"> <tearoff_menu label="~~~~~~~~~~~" name="~~~~~~~~~~~"/> <menu_item_call label="一人称視点(マウスルック)" name="Mouselook"/> @@ -69,23 +87,27 @@ <menu_item_call label="表示をリセット" name="Reset View"/> <menu_item_call label="最後ã®ãƒãƒ£ãƒƒãƒˆã‚’閲覧" name="Look at Last Chatter"/> <menu_item_separator label="-----------" name="separator"/> + <menu_item_call label="ウェブ・ブラウザ" name="Web Browser"/> + <menu_item_separator label="-----------" name="separator2"/> <menu_item_check label="ツールãƒãƒ¼" name="Toolbar"/> <menu_item_check label="ローカル・ãƒãƒ£ãƒƒãƒˆ" name="Chat History"/> <menu_item_check label="コミュニケーション" name="Instant Message"/> <menu_item_check label="æŒã¡ç‰©" name="Inventory"/> <menu_item_check label="ボイスãƒãƒ£ãƒƒãƒˆãƒ»ãƒ¦ãƒ¼ã‚¶ãƒ¼ä¸€è¦§" name="Active Speakers"/> <menu_item_check label="無視リスト" name="Mute List"/> - <menu_item_separator label="-----------" name="separator2"/> + <menu_item_separator label="-----------" name="separator3"/> <menu_item_check label="カメラ・コントロール" name="Camera Controls"/> <menu_item_check label="移動コントロール" name="Movement Controls"/> <menu_item_check label="世界地図" name="World Map"/> <menu_item_check label="ミニマップ" name="Mini-Map"/> - <menu_item_separator label="-----------" name="separator3"/> + <menu_item_separator label="-----------" name="separator4"/> + <menu_item_call label="AO" name="AO"/> + <menu_item_separator label="-----------" name="separator5"/> <menu_item_check label="地域ã®çµ±è¨ˆæƒ…å ±" name="Statistics Bar"/> <menu_item_check label="土地ã®å¢ƒç•Œç·š" name="Property Lines"/> <menu_item_check label="ç«‹å…¥ç¦æ­¢ãƒ©ã‚¤ãƒ³" name="Banlines"/> <menu_item_check label="土地オーナー" name="Land Owners"/> - <menu_item_separator label="-----------" name="separator4"/> + <menu_item_separator label="-----------" name="separator6"/> <menu label="ヒントã®ãƒãƒƒãƒ—アップ" name="Hover Tips"> <menu_item_check label="ヒントを表示" name="Show Tips"/> <menu_item_separator label="-----------" name="separator"/> @@ -96,14 +118,21 @@ <menu_item_check label="ビーコン(標識)" name="beacons"/> <menu_item_check label="パーティクルをéžè¡¨ç¤º" name="Hide Particles"/> <menu_item_check label="HUD装ç€ç‰©ã‚’表示" name="Show HUD Attachments"/> - <menu_item_separator label="-----------" name="separator5"/> - <menu_item_call label="カメラ・ズームイン" name="Zoom In"/> - <menu_item_call label="カメラ・デフォルト" name="Zoom Default"/> - <menu_item_call label="カメラ・ズームアウト" name="Zoom Out"/> - <menu_item_separator label="-----------" name="separator6"/> + <menu_item_separator label="-----------" name="separator7"/> + <menu label="ズーム" name="Zoom Level"> + <menu_item_call label="カメラ・ズームイン" name="Zoom In"/> + <menu_item_call label="カメラ・デフォルト" name="Zoom Default"/> + <menu_item_call label="カメラ・ズームアウト" name="Zoom Out"/> + </menu> <menu_item_call label="[全画é¢è¡¨ç¤º]" name="Toggle Fullscreen"/> <menu_item_call label="UIã‚µã‚¤ã‚ºã‚’æ¨™æº–è¨­å®šã«æˆ»ã™" name="Set UI Size to Default"/> + <menu_item_separator label="-----------" name="separator8"/> + <menu_item_check label="アドãƒãƒ³ã‚¹ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’表示" name="Toggle Advanced Menu"/> </menu> + + + <!-- 世界 --> + <menu label="世界" name="World"> <menu_item_call label="ãƒãƒ£ãƒƒãƒˆ" name="Chat"/> <menu_item_check label="常ã«èµ°ã‚‹" name="Always Run"/> @@ -116,9 +145,11 @@ <menu_item_separator label="-----------" name="separator3"/> <menu_item_call label="離席中ã«è¨­å®š" name="Set Away"/> <menu_item_call label="å–り込ã¿ä¸­ã«è¨­å®š" name="Set Busy"/> + <menu_item_call label="IMã«è‡ªå‹•応答ã™ã‚‹" name="Auto-Respond to IMs"/> + <menu_item_separator label="-----------" name="separator4"/> <menu_item_call label="自分ã®ã‚¢ãƒã‚¿ãƒ¼ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’åœæ­¢" name="Stop Animating My Avatar"/> <menu_item_call label="キー制御を解除" name="Release Keys"/> - <menu_item_separator label="-----------" name="separator4"/> + <menu_item_separator label="-----------" name="separator5"/> <menu_item_call label="アカウントã®å±¥æ­´..." name="Account History..."> <on_click name="AccountHistory_url" userdata="WebLaunchAccountHistory,http://secondlife.com/account/transactions.php?lang=ja"/> </menu_item_call> @@ -126,12 +157,12 @@ <on_click name="ManageMyAccount_url" userdata="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=ja"/> </menu_item_call> <menu_item_call label="L$(リンデン・ドル)を購入" name="Buy and Sell L$..."/> - <menu_item_separator label="-----------" name="separator5"/> - <menu_item_call label="自分ã®åœŸåœ°..." name="My Land..."/> - <menu_item_call label="土地情報..." name="About Land..."/> - <menu_item_call label="土地を購入..." name="Buy Land..."/> - <menu_item_call label="地域ï¼ä¸å‹•産..." name="Region/Estate..."/> <menu_item_separator label="-----------" name="separator6"/> + <menu_item_call label="自分ã®åœŸåœ°" name="My Land"/> + <menu_item_call label="土地情報" name="About Land"/> + <menu_item_call label="土地を購入..." name="Buy Land..."/> + <menu_item_call label="地域ï¼ä¸å‹•産" name="Region/Estate"/> + <menu_item_separator label="-----------" name="separator7"/> <menu label="環境ã®è¨­å®š" name="Environment Settings"> <menu_item_call label="æ—¥ã®å‡º" name="Sunrise"/> <menu_item_call label="æ­£åˆ" name="Noon"/> @@ -142,6 +173,10 @@ <menu_item_call label="環境編集" name="Environment Editor"/> </menu> </menu> + + + <!-- ツール --> + <menu label="ツール" name="Tools"> <menu label="ツールをé¸ã¶" name="Select Tool"> <menu_item_call label="フォーカス" name="Focus"/> @@ -151,28 +186,43 @@ <menu_item_call label="土地" name="Land"/> </menu> <menu_item_separator label="-----------" name="separator"/> - <menu_item_check label="自分ã®ã‚ªãƒ–ジェクトã®ã¿é¸æŠž" name="Select Only My Objects"/> - <menu_item_check label="移動å¯èƒ½ãªã‚ªãƒ–ジェクトã®ã¿é¸æŠž" name="Select Only Movable Objects"/> - <menu_item_check label="環境ã§é¸æŠž" name="Select By Surrounding"/> - <menu_item_check label="隠れãŸä½ç½®ã®é¸æŠžã‚‚表示" name="Show Hidden Selection"/> - <menu_item_check label="é¸æŠžã—ãŸã‚‚ã®ã®å…‰æºç¯„囲を表示" name="Show Light Radius for Selection"/> - <menu_item_check label="é¸æŠžãƒ“ãƒ¼ãƒ ã‚’è¡¨ç¤º" name="Show Selection Beam"/> + <menu_item_call label="é¸æŠžå¯¾è±¡ã«è¦–点移動" name="Focus on Selection"/> + <menu_item_call label="é¸æŠžç¯„å›²ã«ã‚ºãƒ¼ãƒ ã‚¤ãƒ³" name="Zoom to Selection"/> + <menu label="é¸æŠžã‚ªãƒ—ã‚·ãƒ§ãƒ³" name="Selection Options"> + <menu_item_check label="自分ã®ã‚ªãƒ–ジェクトã®ã¿é¸æŠž" name="Select Only My Objects"/> + <menu_item_check label="移動å¯èƒ½ãªã‚ªãƒ–ジェクトã®ã¿é¸æŠž" name="Select Only Movable Objects"/> + <menu_item_check label="コピーå¯èƒ½ãªã‚ªãƒ–ジェクトã®ã¿é¸æŠž" name="Select Only Copyable Objects"/> + <menu_item_check label="環境ã§é¸æŠž" name="Select By Surrounding"/> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_check label="隠れãŸä½ç½®ã®é¸æŠžã‚‚表示" name="Show Hidden Selection"/> + <menu_item_check label="é¸æŠžã—ãŸã‚‚ã®ã®å…‰æºç¯„囲を表示" name="Show Light Radius for Selection"/> + <menu_item_check label="é¸æŠžã—ãŸã‚‚ã®ã®è¼ªéƒ­ã‚’表示" name="Show Selection Outlines"/> + <menu_item_check label="é¸æŠžãƒ“ãƒ¼ãƒ ã‚’è¡¨ç¤º" name="Show Selection Beam"/> + </menu> <menu_item_separator label="-----------" name="separator2"/> <menu_item_check label="グリッドã«ã‚¹ãƒŠãƒƒãƒ—" name="Snap to Grid"/> <menu_item_call label="オブジェクトã®XY移動をグリッドã«åˆã‚ã›ã‚‹" name="Snap Object XY to Grid"/> <menu_item_call label="グリッドをオブジェクトã®ä½ç½®åŸºæº–ã§å†è¨­å®š" name="Use Selection for Grid"/> <menu_item_call label="グリッドã®ã‚ªãƒ—ション..." name="Grid Options..."/> + <menu_item_call label="高度ãªåˆ¶ä½œã‚ªãƒ—ション" name="Advanced Build Options..."/> <menu_item_separator label="-----------" name="separator3"/> <menu_item_check label="リンクã•れãŸä¸€éƒ¨ã‚’編集" name="Edit Linked Parts"/> + <menu label="リンクã—ãŸéƒ¨åˆ†ã‚’é¸æŠžã™ã‚‹" name="Select Linked Parts"> + <menu_item_call label="次ã®éƒ¨åˆ†ã‚’é¸æŠžã™ã‚‹" name="Select Next Part"/> + <menu_item_call label="å‰å›žã®éƒ¨åˆ†ã‚’é¸æŠžã™ã‚‹" name="Select Previous Part"/> + <menu_item_call label="次ã®éƒ¨åˆ†ã‚’å«ã‚ã‚‹" name="Include Next Part"/> + <menu_item_call label="å‰å›žã®éƒ¨åˆ†ã‚’å«ã‚ã‚‹" name="Include Previous Part"/> + </menu> <menu_item_call label="リンク" name="Link"/> <menu_item_call label="リンク解除" name="Unlink"/> <menu_item_separator label="-----------" name="separator4"/> - <menu_item_call label="é¸æŠžå¯¾è±¡ã«è¦–点移動" name="Focus on Selection"/> - <menu_item_call label="é¸æŠžç¯„å›²ã«ã‚ºãƒ¼ãƒ ã‚¤ãƒ³" name="Zoom to Selection"/> + <menu_item_call label="複製" name="Duplicate"/> <menu_item_call label="オブジェクトを購入" name="Menu Object Take"> <on_enable userdata="購入,å–ã‚‹" name="EnableBuyOrTake"/> </menu_item_call> <menu_item_call label="コピーをå–ã‚‹" name="Take Copy"/> + <menu_item_separator label="-----------" name="separator5"/> + <menu_item_call label="オブジェクトを返å´" name="Return..."/> <menu_item_call label="ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã‚’ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãƒ»ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«æˆ»ã—ã¦ä¿å­˜" name="Save Object Back to Object Contents"/> <menu_item_separator label="-----------" name="separator6"/> <menu_item_call label="スクリプト警告ï¼ã‚¨ãƒ©ãƒ¼ãƒ»ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示" name="Show Script Warning/Error Window"/> @@ -183,37 +233,274 @@ <menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ジェクトã®ä¸­ã®ã‚¹ã‚¯ãƒªãƒ—トをリセット" name="Reset Scripts in Selection"/> <menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ジェクトã®ä¸­ã®ã‚¹ã‚¯ãƒªãƒ—トを起動ã™ã‚‹" name="Set Scripts to Running in Selection"/> <menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ジェクトã®ä¸­ã®ã‚¹ã‚¯ãƒªãƒ—ãƒˆã‚’åœæ­¢ã™ã‚‹" name="Set Scripts to Not Running in Selection"/> + <menu_item_separator label="-----------" name="separator7"/> + <menu_item_call label="一括権é™è¨­å®š" name="Set permissions on selected task inventory"/> </menu> + + + <!-- ヘルプ --> + <menu label="ヘルプ" name="Help"> - <menu_item_call label="Second Life ヘルプ" name="Second Life Help"/> + <menu_item_call label="ヘルプ" name="Grid Help"/> <menu_item_call label="ãƒãƒ¥ãƒ¼ãƒˆãƒªã‚¢ãƒ«" name="Tutorial"/> <menu_item_separator label="-----------" name="separator"/> - <menu_item_call label="Lindenå…¬å¼ãƒ–ログ..." name="Official Linden Blog..."/> + <menu_item_call label="Imprudenceブログ" name="Imprudence Blog"/> + <menu_item_call label="Imprudenceフォーラム" name="Imprudence Forums"/> <menu_item_separator label="-----------" name="separator2"/> - <menu_item_call label="スクリプト・ãƒãƒ¼ã‚¿ãƒ«..." name="Scripting Portal..."> + <menu_item_call label="スクリプト・ãƒãƒ¼ã‚¿ãƒ«" name="Scripting Portal"> <on_click name="ScriptingPortal_url" userdata="WebLaunchLSLWiki,http://wiki.secondlife.com/wiki/LSL_Portal/ja" /> </menu_item_call> <menu_item_separator label="-----------" name="separator3"/> <menu_item_call label="嫌ãŒã‚‰ã›ã®å ±å‘Š..." name="Report Abuse..."/> - <menu_item_call label="è¡çªã®è¨˜éŒ²..." name="Bumps, Pushes &amp; Hits..."/> + <menu_item_call label="è¡çªã®è¨˜éŒ²" name="Bumps, Pushes &amp; Hits"/> <menu_item_call label="ラグ メーター" name="Lag Meter"/> - <menu_item_separator label="-----------" name="separator7"/> - <menu label="ãƒã‚°ã®å ±å‘Š" name="Bug Reporting"> - <menu_item_call label="パブリックå•題トラッカー..." name="Public Issue Tracker..."/> - <menu_item_call label="パブリックå•題トラッカー ヘルプ..." name="Publc Issue Tracker Help..."> - <on_click name="PublicIssueTrackerHelp_url" userdata="WebLaunchPublicIssueHelp,http://wiki.secondlife.com/wiki/Issue_tracker/ja" /> - </menu_item_call> - <menu_item_separator label="-----------" name="separator7"/> - <menu_item_call label="ãƒã‚°ã®å ±å‘Š 101..." name="Bug Reporing 101..."> - <on_click name="BugReporting101_url" userdata="WebLaunchBugReport101,http://wiki.secondlife.com/wiki/Bug_Reporting_101"/> - </menu_item_call> - <menu_item_call label="セキュリティå•題..." name="Security Issues..."> - <on_click name="SecurityIssues_url" userdata="WebLaunchSecurityIssues,http://wiki.secondlife.com/wiki/Security_issues/ja"/> - </menu_item_call> - <menu_item_call label="å“質ä¿è¨¼é–¢é€£Wiki..." name="QA Wiki..."/> - <menu_item_separator label="-----------" name="separator9"/> - <menu_item_call label="ãƒã‚°ã®å ±å‘Š..." name="Report Bug..."/> - </menu> - <menu_item_call label="Second Lifeã«ã¤ã„ã¦" name="About Second Life..."/> + <menu_item_separator label="-----------" name="separator4"/> + <menu_item_call label="Imprudenceã«ã¤ã„ã¦" name="About Imprudence"/> + </menu> + + + <!-- アドãƒãƒ³ã‚¹--> + + <menu label="アドãƒãƒ³ã‚¹" name="Advanced" drop_shadow="true"> + <menu label="コンソール" name="Consoles"> + <menu_item_check label="フレームã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Frame Console"/> + <menu_item_check label="テクスãƒãƒ£ã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Console"/> + <menu_item_check label="デãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Debug Console"/> + <menu_item_check label="ファーストタイマー" name="Fast Timers"/> + <menu_item_separator label="-----------" name="separator"/> <menu_item_call label="通知コンソール" name="Notifications Console"/> + <menu_item_separator label="-----------" name="separator2"/> <menu_item_call label="リージョン情報をデãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Region Info to Debug Console"/> + <menu_item_call label="グループ情報をデãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Group Info to Debug Console"/> + <menu_item_call label="性能情報をデãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Capabilities Info to Debug Console"/> + </menu> + <menu label="HUD情報" name="HUD Info"> + <menu_item_check label="速度" name="Velocity"/> + <menu_item_check label="カメラ" name="Camera"/> + <menu_item_check label="風" name="Wind"/> + <menu_item_check label="FOV (視野角)" name="FOV"/> + </menu> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_call label="ã“ã“ã«ã™ã‚ã‚‹" name="Ground Sit"/> + <menu_item_call label="地上ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆ" name="Teleport to Ground"/> + <menu_item_check label="ã‚¢ãƒã‚¿ãƒ¼ã‚’ファントムã«ã™ã‚‹" name="Phantom"/> + <menu_item_check label="アニメーション・リスト" name="Animation List"/> + <menu_item_check label="ã“ã®ã‚¨ãƒªã‚¢ã®ã‚ªãƒ–ジェクトを検索" name="Area Object Search"/> + <menu_item_check label="テクスãƒãƒ£ãƒ»ãƒ–ラウザ" name="asset browser"/> + <menu_item_separator label="-----------" name="separator2"/> + <menu label="レンダリング" name="Rendering"> + <menu label="種類" name="Types"> + <menu_item_check label="シンプル" name="Simple"/> + <menu_item_check label="アルファ" name="Alpha"/> + <menu_item_check label="木" name="Tree"/> + <menu_item_check label="ã‚¢ãƒã‚¿ãƒ¼" name="Character"/> + <menu_item_check label="地表" name="SurfacePatch"/> + <menu_item_check label="空" name="Sky"/> + <menu_item_check label="æ°´" name="Water"/> + <menu_item_check label="地é¢" name="Ground"/> + <menu_item_check label="ボリューム" name="Volume"/> + <menu_item_check label="è‰" name="Grass"/> + <menu_item_check label="雲" name="Clouds"/> + <menu_item_check label="パーティクル" name="Particles"/> + <menu_item_check label="è¡çª" name="Bump"/> + </menu> + <menu label="機能" name="Features"> + <menu_item_check label="UI" name="UI"/> + <menu_item_check label="é¸æŠžæ¸ˆ" name="Selected"/> + <menu_item_check label="ãƒã‚¤ãƒ©ã‚¤ãƒˆ" name="Highlighted"/> + <menu_item_check label="ダイナミックテクスãƒãƒ£" name="Dynamic Textures"/> + <menu_item_check label="è¶³ã®å½±" name="Foot Shadows"/> + <menu_item_check label="ãもり" name="Fog"/> + <menu_item_check label="FRInfo ã®ãƒ†ã‚¹ãƒˆ" name="Test FRInfo"/> + <menu_item_check label="フレキシブルオブジェクト" name="Flexible Objects"/> + </menu> + <menu label="情報を表示" name="Info Displays"> + <menu_item_check label="検証" name="Verify"/> + <menu_item_check label="ãƒã‚¦ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ãƒœãƒƒã‚¯ã‚¹" name="BBoxes"/> + <menu_item_check label="先端" name="Points"/> + <menu_item_check label="オクトリー" name="Octree"/> + <menu_item_check label="オクルージョン" name="Occlusion"/> + <menu_item_check label="ãƒãƒƒãƒã®æç”»" name="Render Batches"/> + <menu_item_check label="アニメーション・テクスãƒãƒ£" name="Animated Textures"/> + <menu_item_check label="テクスãƒãƒ£å„ªå…ˆåº¦" name="Texture Priority"/> + <menu_item_check label="ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã‚³ã‚¹ãƒˆã‚’表示ã™ã‚‹" name="Avatar Rendering Cost"/> + <menu_item_check label="テクスãƒãƒ£ã®ç¯„囲" name="Texture Area (sqrt(A))"/> + <menu_item_check label="å´é¢" name="Face Area (sqrt(A))"/> + <menu_item_check label="å…‰" name="Lights"/> + <menu_item_check label="パーティクル" name="Particles"/> + </menu> + <menu label="レンダーテスト" name="Render Tests"> + <menu_item_check label="カメラオフセット" name="Camera Offset"/> + <menu_item_check label="フレームレートをランダム化" name="Randomize Framerate"/> + <menu_item_check label="定期的ã«é…ã„フレームを挿入ã™ã‚‹" name="Periodic Slow Frame"/> + <menu_item_check label="フレームテスト" name="Frame Test"/> + </menu> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_check label="軸" name="Axes"/> + <menu_item_separator label="-----------" name="separator2"/> + <menu_item_check label="é¸æŠžã—ãŸã‚‚ã®ã‚’éžè¡¨ç¤ºã«ã™ã‚‹" name="Hide Selected"/> + <menu_item_separator label="-----------" name="separator3"/> + <menu_item_check label="接線基底" name="Tangent Basis"/> + <menu_item_call label="é¸æŠžã—ãŸãƒ†ã‚¯ã‚¹ãƒãƒ£æƒ…å ±" name="Selected Texture Info"/> + <menu_item_check label="ワイヤーフレーム" name="Wireframe"/> + <menu_item_check label="オブジェクト間オクルージョン" name="Object-Object Occlusion"/> + <menu_item_check label="GL デãƒãƒƒã‚°" name="Debug GL"/> + <menu_item_check label="経路をデãƒãƒƒã‚°" name="Debug Pipeline"/> + <menu_item_check label="ファーストアルファ" name="Fast Alpha"/> + <menu_item_check label="木ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³" name="Animate Trees"/> + <menu_item_check label="テクスãƒãƒ£ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³" name="Animate Textures"/> + <menu_item_check label="テクスãƒãƒ£ã‚’無効ã«ã™ã‚‹" name="Disable Textures"/> + <menu_item_check label="マルãƒã‚¹ãƒ¬ãƒƒãƒ‰å‡¦ç†" name="Run Multiple Threads"/> + <menu_item_check label="ãƒãƒ¼ã‚¸ãƒ¼ãƒ“ーコン" name="Cheesy Beacon"/> + <menu_item_check label="装ç€ã•れãŸå…‰æºã‚’æç”»ã™ã‚‹" name="Attached Lights"/> + <menu_item_check label="装ç€ã•れãŸãƒ‘ーティクルをæç”»ã™ã‚‹" name="Attached Particles"/> + </menu> + <menu label="世界" name="World"> + <menu_item_check label="シムã®å¤ªé™½ã®è¨­å®šã‚’無視ã™ã‚‹" name="Sim Sun Override"/> + <menu_item_call label="スクリプト付ãカメラをダンプ" name="Dump Scripted Camera"/> + <menu_item_check label="固定ã•れãŸå¤©æ°—" name="Fixed Weather"/> + <menu_item_call label="リージョンオブジェクトã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’ダンプã™ã‚‹" name="Dump Region Object Cache"/> + </menu> + <menu label="RLVa" name="RLVa"> + <menu label="デãƒãƒƒã‚°" name="Debug"> + <menu_item_check label="デãƒãƒƒã‚°ãƒ»ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示" name="Show Debug Messages"/> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_check label="å¤ã„å称を有効ã«ã™ã‚‹" name="Enable Legacy Naming"/> + </menu> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_check label="装ç€ã‚’有効ã«ã™ã‚‹" name="Enable Wear"/> + <menu_item_separator label="-----------" name="separator2"/> + <menu_item_check label="ロックã•れãŸãƒ¬ã‚¤ãƒ¤ãƒ¼ã‚’éžè¡¨ç¤º" name="Hide locked layers"/> + <menu_item_check label="ロックã•れãŸã‚¢ã‚¿ãƒƒãƒãƒ¡ãƒ³ãƒˆã‚’éžè¡¨ç¤º" name="Hide locked attachments"/> + <menu_item_separator label="-----------" name="separator3"/> + <menu_item_check label="#RLVフォルダã®å…±æœ‰ã‚’ç¦æ­¢" name="Forbid Give to #RLV"/> + <menu_item_check label="タグを表示" name="Show Name Tags"/> + <menu_item_separator label="-----------" name="separator4"/> + <menu_item_call label="制é™..." name="Restrictions..."/> + </menu> + <menu label="UI" name="UI"> + <menu_item_check label="デフォルトã®ã‚«ãƒ©ãƒ¼ãƒ»ãƒ”ッカーを使用ã™ã‚‹" name="Use default system color picker"/> + <menu_item_check label="メニュー・ãƒãƒ¼ã«æ¤œç´¢ãƒœãƒƒã‚¯ã‚¹ã‚’表示" name="Show search panel in overlay bar"/> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_call label="Web ブラウザã®ãƒ†ã‚¹ãƒˆ" name="Web Browser Test"/> + <menu_item_call label="UIを編集å¯èƒ½ã«ã™ã‚‹" name="Editable UI"/> + <menu_item_call label="SelectMgrをダンプ" name="Dump SelectMgr"/> + <menu_item_call label="æŒã¡ç‰©ã®å‡ºåŠ›" name="Dump Inventory"/> + <menu_item_call label="フォーカスホールダーをダンプ" name="Dump Focus Holder"/> + <menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ジェクト情報をプリント" name="Print Selected Object Info"/> + <menu_item_call label="エージェント情報をプリント" name="Print Agent Info"/> + <menu_item_call label="メモリ使用状æ³" name="Memory Stats"/> + <menu_item_call label="グループ情報ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’クリア" name="Clear Cached Group Info"/> + <menu_item_separator label="-----------" name="separator2"/> + <menu_item_check label="SelectMgr ã®ãƒ‡ãƒãƒƒã‚°" name="Debug SelectMgr"/> + <menu_item_check label="ダブルクリック" name="Debug Clicks"/> + <menu_item_check label="表示ã®ãƒ‡ãƒãƒƒã‚°" name="Debug Views"/> + <menu_item_check label="å称ツールãƒãƒƒãƒ—ã®ãƒ‡ãƒãƒƒã‚°" name="Show Name Tooltips"/> + <menu_item_check label="マウスæ“作ã«ã‚ˆã‚‹ã‚¤ãƒ™ãƒ³ãƒˆã®ãƒ‡ãƒãƒƒã‚°" name="Debug Mouse Events"/> + <menu_item_check label="キーã®ãƒ‡ãƒãƒƒã‚°" name="Debug Keys"/> + <menu_item_check label="WindowProcã®ãƒ‡ãƒãƒƒã‚°" name="Debug WindowProc"/> + <menu_item_check label="テキスト・エディタã®ãƒ’ントをデãƒãƒƒã‚°" name="Debug Text Editor Tips"/> + <menu_item_separator label="-----------" name="separator3"/> + <menu_item_check label="時間を表示ã™ã‚‹" name="Show Time"/> + <menu_item_check label="æç”»æƒ…報を表示ã™ã‚‹" name="Show Render Info"/> + <menu_item_check label="マトリックスを表示ã™ã‚‹" name="Show Matrices"/> + <menu_item_check label="カーソルを乗ã›ãŸå ´æ‰€ã®è‰²ã‚’表示ã™ã‚‹" name="Show Color Under Cursor"/> + </menu> + <menu label="XUI" name="XUI"> + <menu_item_call label="ウィンドウã®ãƒ†ã‚¹ãƒˆ" name="Floater Test"/> + <menu_item_call label="フォントã®ãƒ†ã‚¹ãƒˆ" name="Font Test"/> + <menu_item_call label="メニューをXMLã§æ›¸ã出ã—..." name="Export Menus to XML..."/> + <menu_item_call label="UIã®ç·¨é›†..." name="Edit UI..."/> + <menu_item_call label="XMLã‹ã‚‰èª­ã¿è¾¼ã‚€" name="Load from XML..."/> + <menu_item_call label="XMLã§ä¿å­˜ã™ã‚‹" name="Save to XML..."/> + <menu_item_check label="XUIãƒãƒ¼ãƒ ã‚’表示ã™ã‚‹" name="Show XUI Names"/> + <menu_item_call label="テスト用 IM ã‚’é€ä¿¡ã™ã‚‹" name="Send Test IMs"/> + </menu> + <menu label="ã‚¢ãƒã‚¿ãƒ¼" name="Character"> + <menu label="ベークドテクスãƒãƒ£ã‚’å–å¾—ã™ã‚‹" name="Grab Baked Texture"> + <menu_item_call label="çž³" name="Iris"/> + <menu_item_call label="é ­" name="Head"/> + <menu_item_call label="上åŠèº«" name="Upper Body"/> + <menu_item_call label="下åŠèº«" name="Lower Body"/> + <menu_item_call label="スカート" name="Skirt"/> + </menu> + <menu label="キャラクターテスト" name="Character Tests"> + <menu_item_call label="容姿を XML ã«ä¿å­˜ã™ã‚‹" name="Appearance To XML"/> + <menu_item_call label="キャラクタジオメトリã®åˆ‡ã‚Šæ›¿ãˆ" name="Toggle Character Geometry"/> + <menu_item_call label="男性アãƒã‚¿ãƒ¼ã®ãƒ†ã‚¹ãƒˆ" name="Test Male"/> + <menu_item_call label="女性アãƒã‚¿ãƒ¼ã®ãƒ†ã‚¹ãƒˆ" name="Test Female"/> + <menu_item_call label="PGを有効ã«ã™ã‚‹" name="Toggle PG"/> + <menu_item_check label="ã‚¢ãƒã‚¿ãƒ¼ã®é¸æŠžã‚’許å¯" name="Allow Select Avatar"/> + </menu> + <menu_item_check label="ボイスã«åˆã‚ã›ã¦å”‡ã‚’å‹•ã‹ã™" name="Enable Lip Sync (Beta)"/> + <menu_item_check label="矢å°ã‚­ãƒ¼ã®Tap-Tap-Holdã§èµ°ã‚‹" name="Tap-Tap-Hold To Run"/> + <menu_item_call label="パラメータを強制的ã«ãƒ‡ãƒ•ォルトã«ã™ã‚‹" name="Force Params to Default"/> + <menu_item_call label="頂点シェーダã®å†èª­è¾¼" name="Reload Vertex Shader"/> + <menu_item_check label="アニメーション情報" name="Animation Info"/> + <menu_item_check label="スローモーションã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³" name="Slow Motion Animations"/> + <menu_item_check label="見ã¦ã„ã‚‹ã‚‚ã®ã‚’表示ã™ã‚‹" name="Show Look At"/> + <menu_item_check label="クリックã—ãŸå ´æ‰€ã‚’表示ã™ã‚‹" name="Show Point At"/> + <menu_item_check label="見ã¦ã„ã‚‹ã‚‚ã®ã‚’自分ã«ã ã‘表示" name="Private Look At"/> + <menu_item_check label="クリックã—ãŸå ´æ‰€ã‚’自分ã«ã ã‘表示" name="Private Point At"/> + <menu_item_check label="çµåˆéƒ¨ã®ã‚¢ãƒƒãƒ—デートã®ãƒ‡ãƒãƒƒã‚°" name="Debug Joint Updates"/> + <menu_item_check label="LOD を無効ã«ã™ã‚‹" name="Disable LOD"/> + <menu_item_check label="キャラクターVis ã®ãƒ‡ãƒãƒƒã‚°" name="Debug Character Vis"/> + <menu_item_check label="骨組ã¿ã®è¡çªåˆ¤å®šã‚’表示ã™ã‚‹" name="Show Collision Skeleton"/> + <menu_item_check label="エージェントã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚’表示ã™ã‚‹" name="Display Agent Target"/> + <menu_item_check label="回転をデãƒãƒƒã‚°" name="Debug Rotation"/> + <menu_item_call label="アタッãƒãƒ¡ãƒ³ãƒˆã‚’ダンプ" name="Dump Attachments"/> + </menu> + <menu label="クラッシュ" name="Crash"> + <menu_item_call label="ãƒãƒƒãƒ‰ãƒ¡ãƒ¢ãƒªã‚¢ã‚¯ã‚»ã‚¹ã‚’実行ã™ã‚‹" name="Force Bad Memory Access"/> + <menu_item_call label="LLErrorã¨ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚’実行ã™ã‚‹" name="Force LLError And Crash"/> + <menu_item_call label="ç„¡é™ãƒ«ãƒ¼ãƒ—" name="Force Infinite Loop"/> + <menu_item_call label="ドライãƒã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚’実行ã™ã‚‹" name="Force Driver Crash"/> + <menu_item_call label="ãƒ“ãƒ¥ãƒ¼ãƒ¯ã®æŽ¥ç¶šé®æ–­ã‚’実行ã™ã‚‹" name="Force Disconnect Viewer"/> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_check label="デãƒãƒƒã‚°ç”¨ã®ãƒŸãƒ‹ãƒ€ãƒ³ãƒ—を出力ã™ã‚‹" name="Output Debug Minidump"/> + </menu> + <menu label="ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯" name="Network"> + <menu_item_call label="メッセージログを有効ã«ã™ã‚‹" name="Enable Message Log"/> + <menu_item_call label="メッセージログを使用ä¸å¯ã«ã™ã‚‹" name="Disable Message Log"/> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_check label="é€ŸåŠ›ãŒæŒ¿å…¥ã•れãŸã‚ªãƒ–ジェクト" name="Velocity Interpolate Objects"/> + <menu_item_check label="挿入ã•れãŸã‚ªãƒ–ジェクトã®ä½ç½®ã® Ping" name="Ping Interpolate Object Positions"/> + <menu_item_separator label="-----------" name="separator2"/> + <menu_item_call label="パケットドロップ" name="Drop a Packet"/> + </menu> + <menu label="レコーダー" name="Recorder"> + <menu_item_call label="全セッションã®ãƒ­ã‚°ã‚’記録" name="Full Session Logging"/> + <menu_item_call label="ログã®è¨˜éŒ²é–‹å§‹" name="Start Logging"/> + <menu_item_call label="ログã®è¨˜éŒ²åœæ­¢" name="Stop Logging"/> + <menu_item_call label="10秒間ログを記録" name="Log 10 Seconds"/> + <menu_item_call label="30秒間ログを記録" name="Log 30 Seconds"/> + <menu_item_call label="60秒間ログを記録" name="Log 60 Seconds"/> + <menu_item_separator label="-----------" name="separator"/> + <menu_item_call label="å†ç”Ÿé–‹å§‹" name="Start Playback"/> + <menu_item_call label="å†ç”Ÿåœæ­¢" name="Stop Playback"/> + <menu_item_check label="å†ç”Ÿã‚’ループ" name="Loop Playback"/> + <menu_item_call label="記録開始" name="Start Record"/> + <menu_item_call label="è¨˜éŒ²åœæ­¢" name="Stop Record"/> + </menu> + <menu label="管ç†è€…オプション" name="Admin Options"> + <menu_item_check label="管ç†è€…メニューを表示ã™ã‚‹" name="View Admin Options"/> + <menu_item_call label="管ç†è€…ステータスã®å‘¼ã³å‡ºã—" name="Request Admin Status"/> + <menu_item_call label="管ç†è€…ステータス解除" name="Leave Admin Status"/> + </menu> + <menu_item_separator label="-----------" name="separator3"/> + <menu_item_check label="オブジェクトã®ã‚¢ãƒƒãƒ—デートを表示ã™ã‚‹" name="Show Updates"/> + <menu_item_separator label="-----------" name="separator4"/> + <menu_item_check label="シャッター音ã¨ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãªã—ã§ã‚¹ãƒŠãƒƒãƒ—ショットをディスクã«ä¿å­˜ã™ã‚‹" name="Quiet Snapshots to Disk"/> + <menu_item_call label="ç”»åƒã‚’圧縮" name="Compress Image..."/> + <menu_item_check label="ãƒ“ãƒ«ãƒ‰ã®æœ€å¤§åˆ¶é™ã‚’解除" name="Disable Max Build Constraints"/> + <menu_item_check label="権é™ã®è©³ç´°ã‚’表示ã™ã‚‹" name="Debug Permissions"/> + <menu_item_check label="マウスã®å‹•ãをスムーズã«" name="Mouse Smoothing"/> + <menu_item_check label="マウスルック時ã«å字カーソルを表示" name="Show Mouselook Crosshairs"/> + <menu_item_separator label="-----------" name="separator5"/> + <menu_item_check label="次回ã®èµ·å‹•時ã«ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示ã™ã‚‹" name="Console Window"/> + <menu_item_check label="Restrained Loveã®ä½¿ç”¨" name="Restrained Love Support"/> + <menu_item_check label="複数ã®Imprudenceã®åŒæ™‚起動を許å¯" name="Allow Multiple Instances"/> + <menu_item_call label="ログアウト" name="Logout"/> + <menu_item_call label="デãƒãƒƒã‚°è¨­å®šã‚’表示ã™ã‚‹" name="Debug Settings"/> </menu> + + </menu_bar> diff --git a/linden/indra/newview/skins/default/xui/ja/notifications.xml b/linden/indra/newview/skins/default/xui/ja/notifications.xml index 77c60689e..6da6cccc1 100644 --- a/linden/indra/newview/skins/default/xui/ja/notifications.xml +++ b/linden/indra/newview/skins/default/xui/ja/notifications.xml @@ -3271,6 +3271,30 @@ Macã®å ´åˆã¯ã€Cmd-Opt-Shift-Dを押ã—ã¦ãã ã•ã„。 <notification name="UnableToOpenCommandURL"> クリックã—ãŸURLã¯ã“ã®ã‚¦ã‚§ãƒ–ブラウザã§ã¯é–‹ã‘ã¾ã›ã‚“ </notification> + + +<!-- ã“ã“ã‹ã‚‰ Imprudence 固有ã®é€šçŸ¥ --> + + + <notification name="ConfirmAutoPilot"> + 本当ã«ã“ã“ã¾ã§æ­©ãã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="オートパイロットã™ã‚‹æ™‚" name="okcancelignore" notext="キャンセル" yestext="æ­©ã"/> + </notification> + + <notification name="ConfirmDoubleClickTP"> + 本当ã«ã“ã“ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã—ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="ダブルクリックテレãƒãƒ¼ãƒˆæ™‚" name="okcancelignore" notext="キャンセル" yestext="テレãƒãƒ¼ãƒˆ"/> + </notification> + + <notification name="ConfirmTeleportHome"> + 本当ã«ãƒ›ãƒ¼ãƒ ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã—ã¾ã™ã‹ï¼Ÿ + <usetemplate ignoretext="ホームã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã™ã‚‹æ™‚" name="okcancelignore" notext="キャンセル" yestext="テレãƒãƒ¼ãƒˆ"/> + </notification> + + +<!-- ã“ã“ã¾ã§ Imprudence 固有ã®é€šçŸ¥ --> + + <global name="UnsupportedCPU"> - ã‚ãªãŸã® CPU ã®é€Ÿåº¦ã¯å¿…é ˆå‹•ä½œç’°å¢ƒã®æ¡ä»¶ã‚’満ãŸã—ã¦ã„ã¾ã›ã‚“。 </global> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_avatar.xml b/linden/indra/newview/skins/default/xui/ja/panel_avatar.xml index a3745a274..147a5f6b5 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_avatar.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_avatar.xml @@ -60,6 +60,7 @@ <text name="Photo:"> 写真: </text> + <button label="UUIDコピー" name="btn_copy_uuid"/> <texture_picker label="" name="img" tool_tip="写真をクリックã—ã¦é¸æŠž"/> <text name="Groups:"> グループ: @@ -77,8 +78,11 @@ </text> <view_border name="drop_target_rect" /> <view_border name="drop_target_rect_vis" /> - <text name="Give inventory" tool_tip="ã“ã“ã«ç‰©å“目をドロップã—ã¦ã“ã®äººã«è´ˆã‚Šã¾ã™"> - æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’ã“ã“ã«ãƒ‰ãƒ­ãƒƒãƒ—ã—ã¾ã™ + <text name="drop target" tool_tip="ã“ã“ã«æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’ドロップã—ã¦ã“ã®äººã«è´ˆã‚Šã¾ã™"> + æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’ + </text> + <text name="Give inventory 2" tool_tip="ã“ã“ã«æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’ドロップã—ã¦ã“ã®äººã«è´ˆã‚Šã¾ã™"> + ã“ã“ã«ãƒ‰ãƒ­ãƒƒãƒ—ã—ã¾ã™ </text> <check_box label="検索ã«è¡¨ç¤º" name="allow_publish" tool_tip="検索ã§ã€è©³ç´°ã‚„イメージãªã©ã•らãªã‚‹ãƒ—ロフィール情報を公開ã™ã‚‹ã€‚"/> <button label="?" label_selected="?" name="?"/> @@ -87,6 +91,7 @@ <button label="フレンドã«è¿½åŠ " label_selected="フレンドã«è¿½åŠ " name="Add Friend..." /> <button label="支払ã†" label_selected="支払ã†" name="Pay..."/> <button label="IMã‚’é€ã‚‹" label_selected="IMã‚’é€ã‚‹" name="Instant Message..." tool_tip="インスタント・メッセージ (IM)" /> + <button label="ã‚°ãƒ«ãƒ¼ãƒ—ã«æ‹›å¾…..." label_selected="ã‚°ãƒ«ãƒ¼ãƒ—ã«æ‹›å¾…" name="Invite to Group..." /> <button label="無視ã™ã‚‹" label_selected="無視ã™ã‚‹" name="Mute" /> </panel> <panel label="ウェブ" name="WebProfile"> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_groups.xml b/linden/indra/newview/skins/default/xui/ja/panel_groups.xml index adfdcd49c..f326a1373 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_groups.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_groups.xml @@ -13,6 +13,8 @@ <button label="抜ã‘ã‚‹" name="Leave" /> <button label="作æˆ..." name="Create" /> <button label="検索..." name="Search..." /> + <button label="招待..." name="Invite..." /> + <button label="タイトル..." name="Titles..." /> <string name="none"> グループãªã— </string> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_mini_map.xml b/linden/indra/newview/skins/default/xui/ja/panel_mini_map.xml index fdc4465c9..2f0711627 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_mini_map.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_mini_map.xml @@ -24,4 +24,15 @@ <text name="nw_label" width="40"> 北西 </text> + + <string name="tooltip_tp"> + ダブルクリックã§ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã—ã¾ã™ + </string> + <string name="tooltip_pan"> + Shift+ドラッグã§ãƒ‘ンã—ã¾ã™ + </string> + <string name="tooltip_map"> + ダブルクリックã§åœ°å›³ã‚’é–‹ãã¾ã™ + </string> + </panel> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml index ef13a7500..4b5a2bb0f 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml @@ -1,4 +1,33 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="advanced_panel"> +<panel label="高度ãªè¨­å®š" name="advanced_panel"> + <check_box label="ログインï¼ãƒ­ã‚°ã‚¢ã‚¦ãƒˆç”»é¢ã‚’éžè¡¨ç¤º" name="disable_log_screen_check"/> + <check_box label="テレãƒãƒ¼ãƒˆç”»é¢ã‚’éžè¡¨ç¤º" name="disable_tp_screen_check"/> + <check_box label="åå‰ã‚¿ã‚°ã«ä½¿ç”¨ãƒ“ューワã®å称を表示" name="client_name_tag_check"/> + <check_box label="ビューワを色ã§è­˜åˆ¥" name="client_name_color_check"/> + <check_box label="ビューワã®åç§°ã«ãƒ’ントを表示" name="client_name_hover_check"/> + <check_box label="自分ã®ãƒ“ューワåç§°ã‚’ã‚¿ã‚°ã«è¡¨ç¤º" name="client_name_tag_broadcast_check"/> + <check_box label="影を有効ã«ã™ã‚‹ï¼ˆè­¦å‘Šï¼šå‹•作ãŒä¸å®‰å®šã«ãªã‚Šã€é«˜ã„グラフィック性能ãŒå¿…è¦ã§ã™ã€‚)" name="shadows_check"/> + <text bottom_delta="-25" left="16" height="15" width="300" + follows="top|left"> + LightShare機能ã®ä½¿ç”¨ï¼ˆOpenSimã®ã¿ï¼‰ï¼š + </text> + <combo_box name="lightshare_combo"> + <combo_item name="never"> + 使用ã—ãªã„ + </combo_item> + <combo_item name="ask"> + æ¯Žå›žç¢ºèª + </combo_item> + <combo_item name="always"> + 常ã«ä½¿ç”¨ + </combo_item> + </combo_box> + <check_box label="HTTPテクスãƒãƒ£ã‚’ä½¿ç”¨ï¼ˆè©¦é¨“ä¸­ã®æ©Ÿèƒ½ï¼‰" name="http_texture_check"/> + <check_box label="é è·é›¢ã®æç”»ã‚’スキップã—ã¦æ—©ã読ã¿è¾¼ã‚€" name="speed_rez_check"/> + <check_box label="容姿編集中ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’表示" name="appearance_anim_check"/> + <check_box label="ä¼çµ±çš„ãªãƒ‘イメニューを使用" name="legacy_pie_menu_checkbox"/> <check_box label="言語をオブジェクトã¨å…±æœ‰" name="language_is_public" tool_tip="優先言語をインワールドã®ã‚ªãƒ–ジェクトãŒèªè­˜ã™ã‚‹"/> + <check_box label="ãƒãƒ£ãƒƒãƒˆã¨IMã§ MU* ãƒãƒ¼ã‚ºãƒ»ã‚¹ã‚¿ã‚¤ãƒ«ã‚’使用" name="allow_mupose"/> + <check_box label="OOCãƒãƒ£ãƒƒãƒˆã®è‡ªå‹•クローズ" name="auto_close_ooc"/> + <button label="å…¨ã¦ã®è¨­å®šã‚’åˆæœŸå€¤ã«æˆ»ã™" name="reset_btn"/> </panel> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_audio.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_audio.xml index 9a8d1757a..c617ba18a 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_preferences_audio.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_audio.xml @@ -20,6 +20,7 @@ </text> <check_box label="音楽ãŒã‚ã‚‹å ´åˆå†ç”Ÿã™ã‚‹ï¼ˆé€šä¿¡ãŒé‡ããªã‚‹ï¼‰" name="streaming_music" /> + <check_box label="音楽ã®ã‚¿ã‚¤ãƒˆãƒ«ã‚’ãƒãƒ£ãƒƒãƒˆã«è¡¨ç¤º" name="show_stream_title"/> <check_box label="ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ãƒ»ãƒ¡ãƒ‡ã‚£ã‚¢ä½¿ç”¨å¯æ™‚ã«å†ç”Ÿï¼ˆå¸¯åŸŸå¹…ã®æ¶ˆè²»å¢—)" name="streaming_video" /> @@ -35,11 +36,15 @@ <text type="string" length="1" name="ui_volume_text"> UI音é‡ï¼š </text> + <text name="ambient_prefs_text"> + 環境音: + </text> + <check_box label="風ã®ç™ºç”Ÿã‚’有効ã«ã™ã‚‹" name="mute_wind_check"/> <slider label="ドップラー効果" name="Doppler Effect" /> <slider label="é éš”è¦å› " name="Distance Factor" /> <slider label="ロールオフ係数" name="Rolloff Factor" /> <spinner label="L$変更基準点" name="L$ Change Threshold" /> - <spinner label="ヘルス変化基準点" name="Health Change Threshold" /> + <spinner label="ヘルス変化基準点" name="Health change threshold" /> <text type="string" length="1" name="doppler_effect_text"> オーディオ環境設定: </text> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_fonts.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_fonts.xml new file mode 100644 index 000000000..3cf54b7fa --- /dev/null +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_fonts.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + +<panel label="フォント" name="font_panel"> + + <text> + ユーザー・インターフェースã®ãƒ•ォントを変更ã§ãã¾ã™ã€‚(å†èµ·å‹•å¾Œã«æœ‰åŠ¹ï¼‰ + </text> + +</panel> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_general.xml index 83b21b87d..ee9937323 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_preferences_general.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_general.xml @@ -32,8 +32,16 @@ UI サイズ: </text> <check_box label="è§£åƒåº¦ç‹¬ç«‹ã‚¹ã‚±ãƒ¼ãƒ«ã‚’使用" name="ui_auto_scale"/> + <check_box label="æ“作ã—ã¦ã„ãªã„時ã¯é€€å¸­ï¼AFK" name="afk_timeout_checkbox"/> <spinner label="退席ã¾ã§ã®æ™‚間:" name="afk_timeout_spinner"/> + <!-- リンデン・ドル支払ï¼å—å–ã®é€šçŸ¥ã¯ã€Œãƒãƒƒãƒ—アップã€ã‚¿ãƒ–ã¸ç§»å‹• <check_box label="リンデン・ドル(L$ï¼‰ã®æ”¯æ‰•ã„/å—ã‘å–りを通知" name="notify_money_change_checkbox"/> + --> + <text name="Mini-Map Notify:"> + ミニマップ通知: + </text> + <check_box label="ãƒãƒ£ãƒƒãƒˆç¯„囲ã«å…¥ã£ãŸæ™‚" name="mini_map_notify_chat"/> + <check_box label="SIMã«å…¥ã£ãŸæ™‚" name="mini_map_notify_sim"/> <text name="maturity_desired_label"> レーティング区分: </text> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml index 167bc2a1c..bca61d9b7 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml @@ -5,6 +5,7 @@ </text> <button label="?" name="GraphicsPreferencesHelpButton" /> <check_box label="ウィンドウ内㧠Second Life ã‚’èµ·å‹•" name="windowed mode" /> + <check_box label="Windlightツールãƒãƒ¼ã‚’表示" name="toggle_windlight_control"/> <text_editor name="voice_chat_description"> ãƒã‚§ãƒƒã‚¯ç„¡ã—ã®å ´åˆã¯ã€ãƒ­ã‚°ã‚¤ãƒ³æ™‚ã«ãƒ•ルスクリーン表示 </text_editor> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_im.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_im.xml index a2c13bb5d..8d4a56451 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_preferences_im.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_im.xml @@ -11,9 +11,14 @@ ログインã—ã¦å¤‰æ›´ã—ã¦ãã ã•ã„ </text> <check_box label="IMã‚’é›»å­ãƒ¡ãƒ¼ãƒ«ï¼ˆ[EMAIL])ã¸é€ä¿¡" name="send_im_to_email"/> - <check_box label="ãƒãƒ£ãƒƒãƒˆã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã«IMを表示ã™ã‚‹" name="include_im_in_chat_console"/> + <text name="show_ims_label"> + IMã®è¡¨ç¤ºï¼š + </text> + <check_box label="ãƒãƒ£ãƒƒãƒˆã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã«è¡¨ç¤º" name="include_im_in_chat_console" left="208"/> + <check_box label="ãƒãƒ£ãƒƒãƒˆå±¥æ­´ã«è¡¨ç¤º" name="include_im_in_chat_history" left="358"/> <check_box label="IMã«ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—を表示" name="show_timestamps_check"/> <check_box label="オンライン・フレンド通知を表示" name="friends_online_notify_checkbox"/> + <check_box label="IMタブを縦並ã³ã«ï¼ˆå†èµ·å‹•å¾Œã«æœ‰åŠ¹ï¼‰" name="vertical-imtabs-toggle"/> <text name="text_box4"> 記録オプション: </text> @@ -29,4 +34,5 @@ å–り込ã¿ä¸­ 応答メッセージ: </text> + <button label="IM応答オプション" name="busy_adv_btn"/> </panel> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_input.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_input.xml index ded6f9df3..ed20af239 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_preferences_input.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_input.xml @@ -21,11 +21,42 @@ <text name="Camera Follow Distance:"> カメラ追従è·é›¢ï¼š </text> + <text name="Camera Transition Time:"> + カメラ切替時間: + </text> + <text name="Camera Smoothing:"> + ã‚«ãƒ¡ãƒ©ã®æ»‘らã‹ã•: + </text> + <check_box label="編集カメラã®è‡ªå‹•移動" name="edit_camera_movement" tool_tip="編集モードã®é–‹å§‹ã€çµ‚了時ã¯ã‚«ãƒ¡ãƒ©è‡ªå‹•ä½ç½®èª¿æ•´ã‚’使用"/> <check_box label="容姿カメラã®è‡ªå‹•移動" name="appearance_camera_movement" tool_tip="編集モードã§ã¯ã€ã‚«ãƒ¡ãƒ©è‡ªå‹•ä½ç½®èª¿æ•´ã‚’使用"/> + <check_box label="カメラ移動ã®åˆ¶é™ã‚’解除" name="Disable camera constraints"/> + <check_box label="ã‚ºãƒ¼ãƒ ã®æœ€çŸ­è·é›¢åˆ¶é™ã‚’解除" name="disable_min_zoom_check"/> <text name="text2"> ã‚¢ãƒã‚¿ãƒ¼è¡¨ç¤ºï¼š </text> <check_box label="ã‚¢ãƒã‚¿ãƒ¼ã‚’一人称視点(マウスルック)ã§è¡¨ç¤º" name="first_person_avatar_visible"/> <button label="ジョイスティック設定" name="joystick_setup_button"/> + <text name="double_click_action_label"> + ダブルクリック時ã®å‹•作: + </text> + <combo_box name="double_click_action"> + <combo_item name="None"> + ãªã— + </combo_item> + <combo_item name="Go"> + オートパイロット + </combo_item> + </combo_box> + <text name="go_action_label"> + オートパイロットã®ç¨®é¡žï¼š + </text> + <combo_box name="go_action"> + <combo_item name="Move"> + æ­©ã + </combo_item> + <combo_item name="Teleport"> + テレãƒãƒ¼ãƒˆ + </combo_item> + </combo_box> </panel> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_preferences_popups.xml b/linden/indra/newview/skins/default/xui/ja/panel_preferences_popups.xml index 9c1ca6edc..75b316c1b 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_preferences_popups.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_preferences_popups.xml @@ -18,4 +18,5 @@ <button width="235" label="ãƒãƒƒãƒ—アップ全ã¦ã‚’有効化..." label_selected="「次回表示ã€ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ãƒªã‚»ãƒƒãƒˆ..." name="reset_dialogs_btn" tool_tip="å…¨ã¦ã®ã‚ªãƒ—ショナルãƒãƒƒãƒ—アップã¨ã€Œåˆå›žä½¿ç”¨ã€é€šçŸ¥ã‚’有効ã«ã—ã¦ãã ã•ã„。"/> <button width="235" label="ã“れらã®ãƒãƒƒãƒ—アップ全ã¦ã‚’無効化..." name="skip_dialogs_btn" tool_tip="å…¨ã¦ã®ã‚ªãƒ—ショナルãƒãƒƒãƒ—アップã¨ã€Œåˆå›žä½¿ç”¨ã€é€šçŸ¥ã‚’無効ã«ã—ã¦ãã ã•ã„。"/> <check_box label="æ–°ãŸã«å—ã‘å–ã£ãŸã‚ªãƒ–ジェクトをæŒã¡ç‰©ã«è‡ªå‹•çš„ã«è¡¨ç¤º" name="show_in_inventory"/> + <check_box label="[CURRENCY]を使用・å—ã‘å–る時ã«é€šçŸ¥" name="notify_money_change_checkbox"/> </panel> diff --git a/linden/indra/newview/skins/default/xui/ja/panel_radar.xml b/linden/indra/newview/skins/default/xui/ja/panel_radar.xml new file mode 100644 index 000000000..ae86ae641 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/ja/panel_radar.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> + +<!-- Note: panel rect (size) is specified in floater_mini_map.xml --> + +<panel name="RadarPanel" label="レーダー"> + + <string name="no_one_near"> + è¿‘ãã«èª°ã‚‚ã„ã¾ã›ã‚“ + </string> + <string name="is_muted"> + (ミュート) + </string> + <string name="is_typing"> + (タイプ中) + </string> + <string name="entering_chat_range"> + [NAME] ã•ã‚“ãŒãƒãƒ£ãƒƒãƒˆãƒ¬ãƒ³ã‚¸ã«å…¥ã£ã¦ãã¾ã—ãŸã€‚ ([DISTANCE]m) + </string> + <string name="entering_sim_range"> + [NAME] ã•ã‚“ãŒSIMã«å…¥ã£ã¦ãã¾ã—ãŸã€‚ ([DISTANCE]m) + </string> + <string name="avatars_in_singular"> + [COUNT]人ã®ã‚¢ãƒã‚¿ãƒ¼ + </string> + <string name="avatars_in_plural"> + [COUNT]人ã®ã‚¢ãƒã‚¿ãƒ¼ + </string> + <string name="unknown_avatar"> + (䏿˜Ž) + </string> + + <tab_container name="radar_tab_container"> + <panel name="avatar_tab" label="ã‚¢ãƒã‚¿ãƒ¼"> + <button name="im_btn" label="IM/コール" tool_tip="IMウィンドウを開ãã¾ã™" /> + <button name="profile_btn" label="プロフィール" tool_tip="å†™çœŸã€æ‰€å±žã‚°ãƒ«ãƒ¼ãƒ—ã€ãã®ä»–ã®æƒ…å ±"/> + <button name="offer_teleport_btn" label="TPã‚’é€ã‚‹" tool_tip="ã“ã®äººã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’é€ã£ã¦è‡ªåˆ†ã®ã¨ã“ã‚ã«å‘¼ã³ã¾ã™"/> + <button name="teleport_btn" label="居場所ã¸TP" tool_tip="ã“ã®äººã®ã„ã‚‹ã¨ã“ã‚ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã—ã¾ã™"/> + <button name="track_btn" label="追跡ã™ã‚‹" tool_tip="地図上ã®ãƒ•レンドã«ãƒ“ーコンを作æˆã€è¿½è·¡ã—ã¾ã™"/> + <button name="invite_btn" label="招待..." tool_tip="ã“ã®äººã‚’è‡ªåˆ†ã®æ‰€å±žã‚°ãƒ«ãƒ¼ãƒ—ã«æ‹›å¾…ã—ã¾ã™"/> + <button name="add_btn" label="追加..." tool_tip="ã“ã®äººã«ãƒ•レンドè¦è«‹ã‚’é€ã‚Šã¾ã™"/> + </panel> + <panel name="estate_tab" label="ä¸å‹•産管ç†"> + <button name="cam_btn" label="カメラ追跡"/> + <button name="freeze_btn" label="å‹•ã‘ãªãã™ã‚‹..."/> + <button name="eject_btn" label="追ã„出ã™..."/> + <button name="ban_btn" label="ç«‹å…¥ç¦æ­¢..."/> + <button name="mute_btn" label="ミュート..."/> + <button name="unmute_btn" label="ï¾ï½­ï½°ï¾„解除..."/> + <button name="ar_btn" label="報告..."/> + </panel> + </tab_container> + + <scroll_list name="RadarList"> + <column name="avatar_name" label="åå‰"/> + <column name="avatar_distance" label="è·é›¢"/> + </scroll_list> + +</panel> + diff --git a/linden/indra/newview/skins/default/xui/ja/panel_windlight_controls.xml b/linden/indra/newview/skins/default/xui/ja/panel_windlight_controls.xml new file mode 100644 index 000000000..bfe6a423f --- /dev/null +++ b/linden/indra/newview/skins/default/xui/ja/panel_windlight_controls.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel name="windlight_controls"> + <button label="環境編集" name="Environment"/> + <flyout_button label="空" name="Presets"> + </flyout_button> +</panel> From 150a190ac5ece99fe9e2c8eafaf6dbf0af02dca1 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 25 Oct 2010 19:48:41 -0700 Subject: [PATCH 091/239] Cleaned up the ugly Phoenix code for #637 and made it translatable --- linden/indra/newview/llagent.cpp | 82 ++++++++++--------- linden/indra/newview/llagent.h | 25 +++--- linden/indra/newview/llworldmap.cpp | 4 +- .../skins/default/xui/en-us/strings.xml | 6 ++ 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 0a0374c8e..758cae25b 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -109,6 +109,7 @@ #include "lltoolmgr.h" #include "lltoolpie.h" #include "lltoolview.h" +#include "lltrans.h" #include "llui.h" // for make_ui_sound #include "llurldispatcher.h" #include "llviewercamera.h" @@ -226,16 +227,6 @@ LLAgent gAgent; // BOOL LLAgent::sPhantom = FALSE; -BOOL LLAgent::lure_show = FALSE; -std::string LLAgent::lure_name; -LLVector3d LLAgent::lure_posglobal; -U16 LLAgent::lure_global_x; -U16 LLAgent::lure_global_y; -int LLAgent::lure_x; -int LLAgent::lure_y; -int LLAgent::lure_z; -std::string LLAgent::lure_maturity; - const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f; std::map<std::string, std::string> LLAgent::sTeleportErrorMessages; @@ -415,7 +406,17 @@ LLAgent::LLAgent() : mWearablesLoaded(FALSE), mTextureCacheQueryID(0), mAppearanceSerialNum(0), - mbTeleportKeepsLookAt(false) + mbTeleportKeepsLookAt(false), + + mLureShow(FALSE), + mLureName(""), + mLurePosGlobal(), + mLureGlobalX(0), + mLureGlobalY(0), + mLureX(0), + mLureY(0), + mLureZ(0), + mLureMaturityString("") { U32 i; for (i = 0; i < TOTAL_CONTROLS; i++) @@ -8090,7 +8091,7 @@ LLVector3 LLAgent::getLastCoords() return mLastCoordinates; } -void LLAgent::showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity) +void LLAgent::showLureDestination(const std::string fromname, const S32 global_x, const S32 global_y, const S32 x, const S32 y, const S32 z, const std::string maturity) { const LLVector3d posglobal = LLVector3d(F64(global_x), F64(global_y), F64(0)); LLSimInfo* siminfo; @@ -8098,49 +8099,54 @@ void LLAgent::showLureDestination(const std::string fromname, const int global_x std::string sim_name; LLWorldMap::getInstance()->simNameFromPosGlobal( posglobal, sim_name ); - if(siminfo) + if (siminfo) { - llinfos << fromname << "'s teleport lure is to " << sim_name.c_str() << " (" << maturity << ")" << llendl; - std::string url = LLURLDispatcher::buildSLURL(sim_name.c_str(), S32(x), S32(y), S32(z)); - std::string msg; - msg = llformat("%s's teleport lure is to %s", fromname.c_str(), url.c_str()); - if(maturity != "") + LLStringUtil::format_map_t args; + args["[NAME]"] = fromname; + args["[DESTINATION]"] = LLURLDispatcher::buildSLURL(sim_name.c_str(), S32(x), S32(y), S32(z)); + std::string msg = LLTrans::getString("TeleportLureMaturity", args); + if (maturity != "") + { msg.append(llformat(" (%s)", maturity.c_str())); + } LLChat chat(msg); LLFloaterChat::addChat(chat); } else { - LLAgent::lure_show = TRUE; - LLAgent::lure_name = fromname; - LLAgent::lure_posglobal = posglobal; - LLAgent::lure_global_x = U16(global_x / 256); - LLAgent::lure_global_y = U16(global_y / 256); - LLAgent::lure_x = x; - LLAgent::lure_y = y; - LLAgent::lure_z = z; - LLAgent::lure_maturity = maturity; - LLWorldMap::getInstance()->sendMapBlockRequest(lure_global_x, lure_global_y, lure_global_x, lure_global_y, true); + mLureShow = TRUE; + mLureName = fromname; + mLurePosGlobal = posglobal; + mLureGlobalX = U16(global_x / 256); + mLureGlobalY = U16(global_y / 256); + mLureX = x; + mLureY = y; + mLureZ = z; + mLureMaturityString = maturity; + LLWorldMap::getInstance()->sendMapBlockRequest(mLureGlobalX, mLureGlobalY, mLureGlobalX, mLureGlobalY, true); } } void LLAgent::onFoundLureDestination() { - LLAgent::lure_show = FALSE; + mLureShow = FALSE; LLSimInfo* siminfo; - siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(LLAgent::lure_posglobal); + siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(mLurePosGlobal); std::string sim_name; - LLWorldMap::getInstance()->simNameFromPosGlobal( LLAgent::lure_posglobal, sim_name ); + LLWorldMap::getInstance()->simNameFromPosGlobal( mLurePosGlobal, sim_name ); - if(siminfo && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))) + if (siminfo && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))) { - llinfos << LLAgent::lure_name << " is offering a TP to " << sim_name.c_str() << " (" << LLAgent::lure_maturity << ")" << llendl; - std::string url = LLURLDispatcher::buildSLURL(sim_name.c_str(), S32(LLAgent::lure_x), S32(LLAgent::lure_y), S32(LLAgent::lure_z)); - std::string msg; - msg = llformat("%s is offering a TP to %s", LLAgent::lure_name.c_str(), url.c_str()); - if(LLAgent::lure_maturity != "") - msg.append(llformat(" (%s)", LLAgent::lure_maturity.c_str())); + llinfos << mLureName << " is offering a TP to " << sim_name.c_str() << " (" << mLureMaturityString << ")" << llendl; + LLStringUtil::format_map_t args; + args["[NAME]"] = mLureName; + args["[DESTINATION]"] = LLURLDispatcher::buildSLURL(sim_name.c_str(), S32(mLureX), S32(mLureY), S32(mLureZ)); + std::string msg = LLTrans::getString("TeleportOfferMaturity", args); + if (mLureMaturityString != "") + { + msg.append(llformat(" (%s)", mLureMaturityString.c_str())); + } LLChat chat(msg); LLFloaterChat::addChat(chat); } diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 03b00453e..6bc4dac78 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -767,17 +767,6 @@ class LLAgent : public LLObservable BOOL mInitialized; - static BOOL lure_show; - static std::string lure_name; - static LLVector3d lure_posglobal; - static U16 lure_global_x; - static U16 lure_global_y; - static int lure_x; - static int lure_y; - static int lure_z; - static std::string lure_maturity; - - S32 mNumPendingQueries; S32* mActiveCacheQueries; @@ -793,8 +782,18 @@ class LLAgent : public LLObservable LLFrameTimer mDoubleTapRunTimer; EDoubleTapRunMode mDoubleTapRunMode; - static void showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity); - static void onFoundLureDestination(); + BOOL mLureShow; + std::string mLureName; + LLVector3d mLurePosGlobal; + U16 mLureGlobalX; + U16 mLureGlobalY; + S32 mLureX; + S32 mLureY; + S32 mLureZ; + std::string mLureMaturityString; + + void showLureDestination(const std::string fromname, const S32 global_x, const S32 global_y, const S32 x, const S32 y, const S32 z, const std::string maturity); + void onFoundLureDestination(); private: bool mbTeleportKeepsLookAt; diff --git a/linden/indra/newview/llworldmap.cpp b/linden/indra/newview/llworldmap.cpp index 01a66d4cb..43d742615 100644 --- a/linden/indra/newview/llworldmap.cpp +++ b/linden/indra/newview/llworldmap.cpp @@ -735,9 +735,9 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) callback(handle, LLWorldMap::getInstance()->mSLURL, image_id, LLWorldMap::getInstance()->mSLURLTeleport); } } - if(LLAgent::lure_show) + if(gAgent.mLureShow) { - if((x_regions == LLAgent::lure_global_x) && (y_regions == LLAgent::lure_global_y)) + if((x_regions == gAgent.mLureGlobalX) && (y_regions == gAgent.mLureGlobalY)) { gAgent.onFoundLureDestination(); } diff --git a/linden/indra/newview/skins/default/xui/en-us/strings.xml b/linden/indra/newview/skins/default/xui/en-us/strings.xml index ceb699480..d3c9df13c 100644 --- a/linden/indra/newview/skins/default/xui/en-us/strings.xml +++ b/linden/indra/newview/skins/default/xui/en-us/strings.xml @@ -23,6 +23,12 @@ <string name="copy_obj_key_info"> Copied key(s) for: </string> + <string name="TeleportOfferMaturity"> + [NAME] is offering a TP to [DESTINATION] + </string> + <string name="TeleportLureMaturity"> + [NAME]'s teleport lure is to [DESTINATION] + </string> <!-- Login --> <string name="LoginInProgress">Logging in. [APP_NAME] may appear frozen. Please wait.</string> From 209535f2e8c9e0553cb08b6a47fefb0a86c1ea61 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 26 Oct 2010 15:54:01 +0200 Subject: [PATCH 092/239] IMP-670: Uninstall packages that are renewed Uninstall old files when a new package with the same name is being installed. See http://redmine.imprudenceviewer.org/issues/670 --- linden/doc/contributions.txt | 1 + linden/scripts/install.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index 2b4010431..e5e3eb043 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -86,6 +86,7 @@ Aleric Inglewood IMP-663 IMP-664 IMP-667 + IMP-670 Alissa Sabre VWR-81 VWR-83 diff --git a/linden/scripts/install.py b/linden/scripts/install.py index a16034f9d..f09fc4818 100755 --- a/linden/scripts/install.py +++ b/linden/scripts/install.py @@ -534,24 +534,24 @@ def _build_ifiles(self, platform, cache_dir): platform, cache_dir)) to_install = [] + to_uninstall = [] #print "self._installed",self._installed for ifile in ifiles: if ifile.pkgname not in self._installed: to_install.append(ifile) elif ifile.url not in self._installed[ifile.pkgname].urls(): + to_uninstall.append(ifile.pkgname) to_install.append(ifile) elif ifile.md5sum != \ self._installed[ifile.pkgname].get_md5sum(ifile.url): - # *TODO: We may want to uninstall the old version too - # when we detect it is installed, but the md5 sum is - # different. + to_uninstall.append(ifile.pkgname) to_install.append(ifile) else: #print "Installation up to date:", # ifile.pkgname,ifile.platform_path pass #print "to_install",to_install - return to_install + return [to_install, to_uninstall] def _install(self, to_install, install_dir): for ifile in to_install: @@ -620,12 +620,17 @@ def install(self, installables, platform, install_dir, cache_dir): cache_dir = os.path.realpath(cache_dir) _mkdir(install_dir) _mkdir(cache_dir) - to_install = self._build_ifiles(platform, cache_dir) + to_install_uninstall = self._build_ifiles(platform, cache_dir) + to_install = to_install_uninstall[0] + to_uninstall = to_install_uninstall[1] # Filter for files which we actually requested to install. to_install = [ifl for ifl in to_install if ifl.pkgname in installables] + to_uninstall = [ifl for ifl in to_uninstall if ifl in installables] for ifile in to_install: ifile.fetch_local() + if to_uninstall: + self.uninstall(to_uninstall, install_dir) self._install(to_install, install_dir) def do_install(self, installables, platform, install_dir, cache_dir=None, From 534779caf41bb0ec7480e2403d3dfc20f1aec06c Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 26 Oct 2010 19:59:06 +0200 Subject: [PATCH 093/239] Add missing skin thumbnail to artwork and move them to the right directory. --- linden/install.xml | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index c564b2bc8..4a6cb23a4 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -176,33 +176,12 @@ <string>creative commons attribution-share alike 3.0</string> <key>packages</key> <map> - <key>darwin</key> - <map> - <key>md5sum</key> - <string>68fedbc3638d7f081edc59bdccbeffc2</string> - <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> - </map> - <key>linux</key> - <map> - <key>md5sum</key> - <string>68fedbc3638d7f081edc59bdccbeffc2</string> - <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> - </map> - <key>linux64</key> - <map> - <key>md5sum</key> - <string>68fedbc3638d7f081edc59bdccbeffc2</string> - <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> - </map> - <key>windows</key> + <key>common</key> <map> <key>md5sum</key> - <string>68fedbc3638d7f081edc59bdccbeffc2</string> + <string>a2cde4f24bdcc260b661e139846b8acd</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101025.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101026.tar.bz2</uri> </map> </map> </map> From 70907fe347852a640c0a34f59edcb113d2c155f1 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Tue, 26 Oct 2010 20:31:18 -0500 Subject: [PATCH 094/239] Removed duplicate 'BulkChangeIncludeAnimations' in settings.xml. --- .../indra/newview/app_settings/settings.xml | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 7b37bb679..576a5535a 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -2903,39 +2903,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>BulkChangeIncludeAnimations</key> - <map> - <key>Comment</key> - <string>Bulk permission changes affect animations</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>BulkChangeIncludeAnimations</key> - <map> - <key>Comment</key> - <string>Bulk permission changes affect animations</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>BulkChangeIncludeAnimations</key> - <map> - <key>Comment</key> - <string>Bulk permission changes affect animations</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>BulkChangeIncludeBodyParts</key> <map> <key>Comment</key> From fff44ef5ad556464a41c160ac6031c67ef40cb63 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Tue, 26 Oct 2010 20:41:40 -0500 Subject: [PATCH 095/239] Removed getvoice.sh for Linux. It's no longer needed. --- linden/indra/newview/linux_tools/getvoice.sh | 34 -------------------- linden/indra/newview/viewer_manifest.py | 1 - 2 files changed, 35 deletions(-) delete mode 100755 linden/indra/newview/linux_tools/getvoice.sh diff --git a/linden/indra/newview/linux_tools/getvoice.sh b/linden/indra/newview/linux_tools/getvoice.sh deleted file mode 100755 index 13b632f36..000000000 --- a/linden/indra/newview/linux_tools/getvoice.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -SCRIPTSRC=`readlink -f "$0" || echo "$0"` -RUN_PATH=`dirname "${SCRIPTSRC}" || echo .` - -#if mozilla-runtime-linux-x86_64 is present we are using 64bit Imprudence on 64bit Linux -if [ -d "${RUN_PATH}/app_settings/mozilla-runtime-linux-x86_64/" ]; then - LIB_INSTALLDIR="lib32/" # It's 32bit voice on 64bit Linux and 64bit viewer. Not using lib/ for avoiding ambiguity. -else - LIB_INSTALLDIR="lib/" # It's 32bit voice on 32 or 64bit Linux and 32bit viewer. -fi - -mkdir -p $LIB_INSTALLDIR -wget http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-linux-20090309.tar.bz2 -tar -C ./bin --strip-components 4 -xjf vivox-*.tar.bz2 --wildcards '*SLVoice' -tar -C ./$LIB_INSTALLDIR --strip-components 4 -xjf vivox-*.tar.bz2 --wildcards '*.so*' -rm vivox-*.tar.bz2 - -#now we have Vivox' OpenAL, but we want Imprudence (32bit for voice) OpenAL which is way better: -wget http://imprudenceviewer.org/download/libs/openal-linux32-20100426.tar.bz2 -tar -C ./$LIB_INSTALLDIR --strip-components 3 -xjf openal-*.tar.bz2 --wildcards '*openal.so*' -rm openal-*.tar.bz2 - -# For 64bit viewer on 64bit Linux we also need a 32bit libidn.so.11 and libuuid.so.1 -if [ -d ${RUN_PATH}/lib32/ ]; then - wget http://imprudenceviewer.org/download/libs/libidn20100312.tar.bz2 - tar -C $LIB_INSTALLDIR --strip-components 1 -xjf libidn*.tar.bz2 --wildcards '*.so*' - rm libidn*.tar.bz2 - - wget http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libuuid-linux-20090417.tar.bz2 - tar -C ./$LIB_INSTALLDIR --strip-components 3 -xjf libuuid-*.tar.bz2 --wildcards '*.so*' - rm libuuid-*.tar.bz2 -fi - diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index ff59aec75..bccfa8f9d 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -845,7 +845,6 @@ def construct(self): self.path("wrapper.sh","imprudence") self.path("handle_secondlifeprotocol.sh") self.path("register_secondlifeprotocol.sh") - self.path("getvoice.sh") self.end_prefix("linux_tools") self.gather_documents() From 447b85de620dd217cb13233d814de8e80e1b9eb7 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 26 Oct 2010 20:09:25 -0700 Subject: [PATCH 096/239] Set LL_GSTREAMER010_ENABLED to true for Linux-only until gstreamer loading can be sorted on windows --- linden/indra/cmake/GStreamer010Plugin.cmake | 2 ++ .../gstreamer010/llmediaimplgstreamervidplug.cpp | 4 ++-- .../media_plugins/gstreamer010/llmediaimplgstreamervidplug.h | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/linden/indra/cmake/GStreamer010Plugin.cmake b/linden/indra/cmake/GStreamer010Plugin.cmake index cafcd4c6a..878d3c056 100644 --- a/linden/indra/cmake/GStreamer010Plugin.cmake +++ b/linden/indra/cmake/GStreamer010Plugin.cmake @@ -8,6 +8,7 @@ if (STANDALONE) pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10) endif (STANDALONE) +if (LINUX) use_prebuilt_binary(gstreamer) # possible libxml should have its own .cmake file instead use_prebuilt_binary(libxml) @@ -18,6 +19,7 @@ endif (STANDALONE) ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 ) +endif (LINUX) if (WINDOWS) # We don't need to explicitly link against gstreamer itself, because diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index 1fee54593..e194bf7c6 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -33,7 +33,7 @@ * @endcond */ -///#if LL_GSTREAMER010_ENABLED +#if LL_GSTREAMER010_ENABLED #include "linden_common.h" @@ -569,4 +569,4 @@ void gst_slvideo_init_class (void) (const gchar *)"http://www.secondlife.com/" ); } -///#endif // LL_GSTREAMER010_ENABLED +#endif // LL_GSTREAMER010_ENABLED diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index 0ad8cf176..5e8c72c98 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -36,7 +36,7 @@ #ifndef __GST_SLVIDEO_H__ #define __GST_SLVIDEO_H__ -///#if LL_GSTREAMER010_ENABLED +#if LL_GSTREAMER010_ENABLED extern "C" { #include <gst/gst.h> @@ -108,6 +108,6 @@ void gst_slvideo_init_class (void); G_END_DECLS -///#endif // LL_GSTREAMER010_ENABLED +#endif // LL_GSTREAMER010_ENABLED #endif /* __GST_SLVIDEO_H__ */ From 45438a88354927942315ad5c4872cc76515d1891 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 26 Oct 2010 20:26:00 -0700 Subject: [PATCH 097/239] Fixed media plugin test not compiling --- .../llplugintest/llmediaplugintest.cpp | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp b/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp index 27cb52a50..bc3703d57 100644 --- a/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/linden/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -1169,8 +1169,8 @@ void LLMediaPluginTest::keyboard( int key ) exit( 0 ); }; - mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 ); - mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0 ); + mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 , LLSD()); + mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0, LLSD()); }; //////////////////////////////////////////////////////////////////////////////// @@ -1529,7 +1529,21 @@ void LLMediaPluginTest::addMediaPanel( std::string url ) #elif LL_WINDOWS std::string launcher_name( "SLPlugin.exe" ); #endif - media_source->init( launcher_name, plugin_name ); + + // for this test app, use the cwd as the user data path (ugh). +#if LL_WINDOWS + std::string user_data_path = ".\\"; +#else + char cwd[ FILENAME_MAX ]; + if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) + { + std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl; + return; + } + std::string user_data_path = std::string( cwd ) + "/"; +#endif + media_source->setUserDataPath(user_data_path); + media_source->init( launcher_name, plugin_name, false ); media_source->setDisableTimeout(mDisableTimeout); // make a new panel and save parameters @@ -1752,7 +1766,22 @@ void LLMediaPluginTest::replaceMediaPanel( mediaPanel* panel, std::string url ) #elif LL_WINDOWS std::string launcher_name( "SLPlugin.exe" ); #endif - media_source->init( launcher_name, plugin_name ); + + // for this test app, use the cwd as the user data path (ugh). +#if LL_WINDOWS + std::string user_data_path = ".\\"; +#else + char cwd[ FILENAME_MAX ]; + if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) + { + std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl; + return; + } + std::string user_data_path = std::string( cwd ) + "/"; +#endif + + media_source->setUserDataPath(user_data_path); + media_source->init( launcher_name, plugin_name, false ); media_source->setDisableTimeout(mDisableTimeout); // make a new panel and save parameters From 74749fc1ed3b6f6eda57739712c3e01ba126c7b6 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Wed, 27 Oct 2010 02:17:31 -0700 Subject: [PATCH 098/239] Fixed mime_types.xml not being copied on Windows (also fixes plugin dll copying error) --- linden/indra/newview/CMakeLists.txt | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index e113d052d..bec20d991 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1525,6 +1525,7 @@ ADD_VIEWER_BUILD_TEST(llagentaccess viewer) # Don't do these for DARWIN or LINUX here -- they're taken care of by viewer_manifest.py if (WINDOWS) + get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION) add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD @@ -1549,17 +1550,17 @@ if (WINDOWS) COMMENT "Copying WebKit Plugin to the runtime folder." ) - get_target_property(BUILT_GSTREAMER_PLUGIN media_plugin_gstreamer010 LOCATION) - add_custom_command( - TARGET ${VIEWER_BINARY_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - copy_if_different - ${BUILT_GSTREAMER_PLUGIN} - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin - COMMENT "Copying Gstreamer Plugin to the runtime folder." - ) + #get_target_property(BUILT_GSTREAMER_PLUGIN media_plugin_gstreamer010 LOCATION) + # add_custom_command( + # TARGET ${VIEWER_BINARY_NAME} POST_BUILD + # COMMAND ${CMAKE_COMMAND} + # ARGS + # -E + # copy_if_different + # ${BUILT_GSTREAMER_PLUGIN} + # ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin + # COMMENT "Copying Gstreamer Plugin to the runtime folder." + # ) get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION) add_custom_command( @@ -1573,8 +1574,20 @@ if (WINDOWS) COMMENT "Copying Quicktime Plugin to the runtime folder." ) - - + # Copying the mime_types.xml file to app_settings + set(mime_types_source "${CMAKE_SOURCE_DIR}/newview/skins/default/xui/en-us") + set(mime_types_dest "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/app_settings") + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${mime_types_source}/mime_types_windows.xml + ${mime_types_dest}/mime_types.xml + COMMENT "Copying mime_types_windows.xml to mime_types.xml." + ) + endif (WINDOWS) if (DARWIN) From d2a3064b8abc37853839441bdd1db0ce99ac5ef2 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Wed, 27 Oct 2010 02:38:23 -0700 Subject: [PATCH 099/239] Use quicktime instead of gstreamer on Windows --- .../default/xui/en-us/mime_types_windows.xml | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml index 5ff3b19eb..abc7f1a85 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml @@ -109,7 +109,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </scheme> <mimetype name="blank"> @@ -120,7 +120,7 @@ none </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="none/none"> @@ -163,7 +163,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="application/javascript"> @@ -214,7 +214,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -241,7 +241,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="audio/mpeg"> @@ -252,7 +252,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="audio/x-aiff"> @@ -263,7 +263,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="audio/x-wav"> @@ -274,7 +274,7 @@ audio </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype menu="1" name="image/bmp"> @@ -384,7 +384,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="video/mp4"> @@ -395,7 +395,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype menu="1" name="video/gstreamer"> @@ -406,7 +406,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="video/x-ms-asf"> @@ -417,7 +417,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype name="video/x-ms-wmv"> @@ -428,7 +428,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> <mimetype menu="1" name="video/x-msvideo"> @@ -439,7 +439,7 @@ movie </widgettype> <impl> - media_plugin_gstreamer + media_plugin_quicktime </impl> </mimetype> </mimetypes> From d3ecf0f84bdb72cc28df16d59c736b9ffba7a57f Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 27 Oct 2010 15:53:42 +0200 Subject: [PATCH 100/239] Remove the need for qglobal.h on non-standalone. --- .../media_plugins/webkit/media_plugin_webkit.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index d4c5deb30..d01cd9e11 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -34,7 +34,9 @@ */ #include "llqtwebkit.h" -#include <qglobal.h> // for Q_INIT_RESOURCE +#ifdef LL_STANDALONE +#include <qglobal.h> +#endif #include "linden_common.h" #include "indra_constants.h" // for indra keyboard codes @@ -80,6 +82,16 @@ extern "C" { } #endif +// We don't provide Qt headers, so define this here for non-standalone. +#ifndef QT_MANGLE_NAMESPACE +#define QT_MANGLE_NAMESPACE(name) name +#endif +#ifndef Q_INIT_RESOURCE +#define Q_INIT_RESOURCE(name) \ + do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \ + QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (0) +#endif + //////////////////////////////////////////////////////////////////////////////// // class MediaPluginWebKit : From 190bd7d2b622efda788a7b1e7da5996c5095de54 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Wed, 27 Oct 2010 02:56:22 -0700 Subject: [PATCH 101/239] Load mime_types_windows.xml instead of mime_types.xml so we can fallback on the version in the skins directory correctly --- linden/indra/newview/CMakeLists.txt | 4 ++-- linden/indra/newview/llappviewer.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index bec20d991..6596d39ad 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1584,8 +1584,8 @@ if (WINDOWS) -E copy_if_different ${mime_types_source}/mime_types_windows.xml - ${mime_types_dest}/mime_types.xml - COMMENT "Copying mime_types_windows.xml to mime_types.xml." + ${mime_types_dest}/mime_types_windows.xml + COMMENT "Copying mime_types_windows.xml to the runtime app_settings folder." ) endif (WINDOWS) diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 5b34e8254..97deca0b4 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -724,7 +724,7 @@ bool LLAppViewer::init() #elif LL_LINUX mime_types_name = "mime_types_linux.xml"; #else - mime_types_name = "mime_types.xml"; + mime_types_name = "mime_types_windows.xml"; #endif LLMIMETypes::parseMIMETypes( mime_types_name ); From 6f2faa65f9841919566b567d74b258a1c559ec0e Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 27 Oct 2010 22:28:48 +0200 Subject: [PATCH 102/239] Load prebuilt glib when needed. Don't compile gstreamer plugin on windows. Also, darwin doesn't use quicktime, so disabled compiling that plugin for darwin. --- linden/indra/cmake/DBusGlib.cmake | 1 + linden/indra/cmake/GStreamer010Plugin.cmake | 14 ++++++++------ linden/indra/cmake/UI.cmake | 3 ++- linden/indra/media_plugins/CMakeLists.txt | 8 +++++--- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/linden/indra/cmake/DBusGlib.cmake b/linden/indra/cmake/DBusGlib.cmake index dfda0ad0b..b78a0b1e7 100644 --- a/linden/indra/cmake/DBusGlib.cmake +++ b/linden/indra/cmake/DBusGlib.cmake @@ -7,6 +7,7 @@ if (STANDALONE) pkg_check_modules(DBUSGLIB REQUIRED dbus-glib-1) elseif (LINUX) + use_prebuilt_binary(glib) # dbusglib needs glib use_prebuilt_binary(dbusglib) set(DBUSGLIB_FOUND ON FORCE BOOL) set(DBUSGLIB_INCLUDE_DIRS diff --git a/linden/indra/cmake/GStreamer010Plugin.cmake b/linden/indra/cmake/GStreamer010Plugin.cmake index 878d3c056..90ed35c81 100644 --- a/linden/indra/cmake/GStreamer010Plugin.cmake +++ b/linden/indra/cmake/GStreamer010Plugin.cmake @@ -6,12 +6,13 @@ if (STANDALONE) pkg_check_modules(GSTREAMER010 REQUIRED gstreamer-0.10) pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10) -endif (STANDALONE) -if (LINUX) - use_prebuilt_binary(gstreamer) - # possible libxml should have its own .cmake file instead +else (STANDALONE) + + # Possibly libxml and glib should have their own .cmake file instead... + use_prebuilt_binary(glib) # gstreamer needs glib use_prebuilt_binary(libxml) + use_prebuilt_binary(gstreamer) set(GSTREAMER010_FOUND ON FORCE BOOL) set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL) set(GSTREAMER010_INCLUDE_DIRS @@ -19,8 +20,9 @@ if (LINUX) ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 ) -endif (LINUX) - + +endif (STANDALONE) + if (WINDOWS) # We don't need to explicitly link against gstreamer itself, because # LLMediaImplGStreamer probes for the system's copy at runtime. diff --git a/linden/indra/cmake/UI.cmake b/linden/indra/cmake/UI.cmake index 9d068c4bf..7a02dff83 100644 --- a/linden/indra/cmake/UI.cmake +++ b/linden/indra/cmake/UI.cmake @@ -31,8 +31,9 @@ if (STANDALONE) add_definitions(${${pkg}_CFLAGS_OTHERS}) endforeach(pkg) else (STANDALONE) - use_prebuilt_binary(gtk-etc) if (LINUX) + use_prebuilt_binary(glib) # gtk-etc needs glib + use_prebuilt_binary(gtk-etc) set(UI_LIBRARIES atk-1.0 cairo diff --git a/linden/indra/media_plugins/CMakeLists.txt b/linden/indra/media_plugins/CMakeLists.txt index cc03d9cb7..c4f255527 100755 --- a/linden/indra/media_plugins/CMakeLists.txt +++ b/linden/indra/media_plugins/CMakeLists.txt @@ -4,10 +4,12 @@ add_subdirectory(base) add_subdirectory(webkit) -add_subdirectory(gstreamer010) +if (LINUX OR DARWIN) + add_subdirectory(gstreamer010) +endif (LINUX OR DARWIN) -if (WINDOWS OR DARWIN) +if (WINDOWS) add_subdirectory(quicktime) -endif (WINDOWS OR DARWIN) +endif (WINDOWS) add_subdirectory(example) From 686f5fdf0f710387c7aa84b41434f0bab8cd6875 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Thu, 28 Oct 2010 00:08:50 +0200 Subject: [PATCH 103/239] Only initialize WebCore resource(s) on linux. I searched the darwin and windows llqtwebkit tarballs and neither qInitResources_WebCore nor qInitResources_WebCore_QT_NAMESPACE exist in there... No idea why, but then we can't call it to initialize it now can we? --- .../media_plugins/webkit/media_plugin_webkit.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index d01cd9e11..0fb64bb82 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -34,9 +34,6 @@ */ #include "llqtwebkit.h" -#ifdef LL_STANDALONE -#include <qglobal.h> -#endif #include "linden_common.h" #include "indra_constants.h" // for indra keyboard codes @@ -82,14 +79,18 @@ extern "C" { } #endif -// We don't provide Qt headers, so define this here for non-standalone. -#ifndef QT_MANGLE_NAMESPACE +#ifdef LL_STANDALONE +#include <qglobal.h> +#elif defined(LL_LINUX) +// We don't provide Qt headers for non-standalone, therefore define this here. +// Our prebuilt is built with QT_NAMESPACE undefined. #define QT_MANGLE_NAMESPACE(name) name -#endif -#ifndef Q_INIT_RESOURCE #define Q_INIT_RESOURCE(name) \ do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \ QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (0) +#else +// Apparently this symbol doesn't exist in the windows and Mac tar balls provided by LL. +#define Q_INIT_RESOURCE(name) /*nothing*/ #endif //////////////////////////////////////////////////////////////////////////////// From 230a5e1114988486540ac4840a63854d4298cfa2 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Thu, 28 Oct 2010 16:00:44 +0200 Subject: [PATCH 104/239] Remove explicit dependency of windows on media_plugin_gstreamer010 --- linden/indra/newview/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index fb674231d..829aa69f4 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1350,7 +1350,7 @@ if (WINDOWS) DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit media_plugin_gstreamer010) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) # Removed media_plugin_gstreamer010 if (PACKAGE) add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat) From 694e64db099caa07ca7a1ef740f8dac524eb2479 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Fri, 29 Oct 2010 15:49:14 +0200 Subject: [PATCH 105/239] Fix Bug #671 (aka VWR-1603): Duckwalk is too fast Slow down AO-less avatars' walk animation by 2x. Patch by Gigs Taggart from https://jira.secondlife.com/browse/VWR-1603 --- linden/indra/llcharacter/llkeyframewalkmotion.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linden/indra/llcharacter/llkeyframewalkmotion.cpp b/linden/indra/llcharacter/llkeyframewalkmotion.cpp index b5817e5bd..4aa9d2ae3 100644 --- a/linden/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/linden/indra/llcharacter/llkeyframewalkmotion.cpp @@ -50,6 +50,7 @@ const F32 MIN_WALK_SPEED = 0.1f; // minimum speed at which we use velocity for d const F32 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation const F32 SPEED_ADJUST_MAX = 2.5f; // maximum adjustment of walk animation playback speed const F32 SPEED_ADJUST_MAX_SEC = 3.f; // maximum adjustment to walk animation playback speed for a second +const F32 SPEED_FINAL_SCALING = 0.5f; // final scaling for walk animation const F32 DRIFT_COMP_MAX_TOTAL = 0.07f;//0.55f; // maximum drift compensation overall, in any direction const F32 DRIFT_COMP_MAX_SPEED = 4.f; // speed at which drift compensation total maxes out const F32 MAX_ROLL = 0.6f; @@ -314,6 +315,7 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) } mAnimSpeed = (mAvgSpeed + mSpeedAdjust) * mRelativeDir; + mAnimSpeed = mAnimSpeed * SPEED_FINAL_SCALING; // char debug_text[64]; // sprintf(debug_text, "Foot slip vel: %.2f", footSlipVelocity); // mCharacter->addDebugText(debug_text); From 34a5639792b97b3dc33ee2dfd1b15ee907c4634f Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 30 Oct 2010 19:44:04 +0200 Subject: [PATCH 106/239] Fix bug #672: Failed bake uploads don't retry Add a retry counter and a small delay for retyring failed bake uploads. This is one possible cause of outfit changes (and un-ruthing) not propagating from the viewer to the sim until the user manually rebakes. --- .../indra/newview/llassetuploadresponders.h | 1 + linden/indra/newview/lltexlayer.cpp | 57 +++++++++++++++---- linden/indra/newview/lltexlayer.h | 4 ++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/linden/indra/newview/llassetuploadresponders.h b/linden/indra/newview/llassetuploadresponders.h index c08f2999f..9102f6bc1 100644 --- a/linden/indra/newview/llassetuploadresponders.h +++ b/linden/indra/newview/llassetuploadresponders.h @@ -74,6 +74,7 @@ class LLNewAgentInventoryResponder : public LLAssetUploadResponder class LLBakedUploadData; class LLSendTexLayerResponder : public LLAssetUploadResponder { + LOG_CLASS(LLSendTexLayerResponder); public: LLSendTexLayerResponder(const LLSD& post_data, const LLUUID& vfile_id, diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp index 5175cbb77..c8e12980d 100644 --- a/linden/indra/newview/lltexlayer.cpp +++ b/linden/indra/newview/lltexlayer.cpp @@ -61,6 +61,8 @@ using namespace LLVOAvatarDefines; +const S32 MAX_BAKE_UPLOAD_ATTEMPTS = 4; + // static S32 LLTexLayerSetBuffer::sGLByteCount = 0; @@ -98,6 +100,8 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 he mNeedsUpdate( TRUE ), mNeedsUpload( FALSE ), mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates + mUploadFailCount( 0 ), + mUploadAfter( 0 ), mTexLayerSet( owner ) { LLTexLayerSetBuffer::sGLByteCount += getSize(); @@ -151,6 +155,18 @@ void LLTexLayerSetBuffer::requestUpload() { mNeedsUpload = TRUE; mUploadPending = TRUE; + mUploadAfter = 0; + } +} + +// request an upload to start delay_usec microseconds from now +void LLTexLayerSetBuffer::requestDelayedUpload(U64 delay_usec) +{ + if (!mNeedsUpload) + { + mNeedsUpload = TRUE; + mUploadPending = TRUE; + mUploadAfter = LLFrameTimer::getTotalTime() + delay_usec; } } @@ -161,6 +177,14 @@ void LLTexLayerSetBuffer::cancelUpload() mNeedsUpload = FALSE; } mUploadPending = FALSE; + mUploadAfter = 0; +} + +// do we need to upload, and do we have sufficient data to create an uploadable composite? +BOOL LLTexLayerSetBuffer::needsUploadNow() const +{ + BOOL upload = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && (gAgent.mNumPendingQueries == 0); + return (upload && (LLFrameTimer::getTotalTime() > mUploadAfter)); } void LLTexLayerSetBuffer::pushProjection() @@ -187,7 +211,7 @@ void LLTexLayerSetBuffer::popProjection() BOOL LLTexLayerSetBuffer::needsRender() { LLVOAvatar* avatar = mTexLayerSet->getAvatar(); - BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && gAgent.mNumPendingQueries == 0; + BOOL upload_now = needsUploadNow(); BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating; if (needs_update) { @@ -229,9 +253,6 @@ BOOL LLTexLayerSetBuffer::render() // Default color mask for tex layer render gGL.setColorMask(true, true); - // do we need to upload, and do we have sufficient data to create an uploadable composite? - // When do we upload the texture if gAgent.mNumPendingQueries is non-zero? - BOOL upload_now = (gAgent.mNumPendingQueries == 0 && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal()); BOOL success = TRUE; // Composite the color data @@ -239,7 +260,7 @@ BOOL LLTexLayerSetBuffer::render() success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); gGL.flush(); - if( upload_now ) + if( needsUploadNow() ) { if (!success) { @@ -387,7 +408,8 @@ void LLTexLayerSetBuffer::readBackAndUpload() std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture"); if(!url.empty() - && !LLPipeline::sForceOldBakedUpload) // Toggle the debug setting UploadBakedTexOld to change between the new caps method and old method + && !LLPipeline::sForceOldBakedUpload // Toggle the debug setting UploadBakedTexOld to change between the new caps method and old method + && (mUploadFailCount < MAX_BAKE_UPLOAD_ATTEMPTS-1)) // allow last ditch attempt via asset store, since capabilty seems prone to transient failures. { llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl; @@ -436,12 +458,14 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user LLVOAvatar* avatar = gAgent.getAvatarObject(); - if (0 == result && - avatar && !avatar->isDead() && + if (avatar && !avatar->isDead() && + baked_upload_data && baked_upload_data->mAvatar == avatar && // Sanity check: only the user's avatar should be uploading textures. baked_upload_data->mLayerSet->hasComposite()) { LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mLayerSet->getComposite(); + S32 failures = layerset_buffer->mUploadFailCount; + layerset_buffer->mUploadFailCount = 0; if (layerset_buffer->mUploadID.isNull()) { @@ -469,9 +493,20 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user } else { - // Avatar appearance is changing, ignore the upload results - llinfos << "Baked upload failed. Reason: " << result << llendl; - // *FIX: retry upload after n seconds, asset server could be busy + ++failures; + llinfos << "Baked upload failed (attempt " << failures << "/" << MAX_BAKE_UPLOAD_ATTEMPTS << "), "; + if (failures >= MAX_BAKE_UPLOAD_ATTEMPTS) + { + llcont << "giving up."; + } + else + { + const F32 delay = 5.f; + llcont << llformat("retrying in %.2f seconds.", delay); + layerset_buffer->mUploadFailCount = failures; + layerset_buffer->requestDelayedUpload((U64)(delay * 1000000)); + } + llcont << llendl; } } else diff --git a/linden/indra/newview/lltexlayer.h b/linden/indra/newview/lltexlayer.h index 020ba86f1..31b175ec9 100644 --- a/linden/indra/newview/lltexlayer.h +++ b/linden/indra/newview/lltexlayer.h @@ -218,6 +218,7 @@ class LLTexLayerSetBuffer : public LLDynamicTexture BOOL needsRender(); void requestUpdate(); void requestUpload(); + void requestDelayedUpload(U64 delay_usec); void cancelUpload(); BOOL uploadPending() { return mUploadPending; } BOOL render( S32 x, S32 y, S32 width, S32 height ); @@ -234,12 +235,15 @@ class LLTexLayerSetBuffer : public LLDynamicTexture private: void pushProjection(); void popProjection(); + BOOL needsUploadNow() const; private: BOOL mNeedsUpdate; BOOL mNeedsUpload; BOOL mUploadPending; LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) + S32 mUploadFailCount; + U64 mUploadAfter; // delay upload until after this time (in microseconds) LLTexLayerSet* mTexLayerSet; static S32 sGLByteCount; From af6877fbfe94e80948c559cf77f008049f8168dc Mon Sep 17 00:00:00 2001 From: RevolutionSmythe <asdfisbetterthanjkl@gmail.com> Date: Wed, 20 Oct 2010 16:31:09 -0500 Subject: [PATCH 107/239] Finishes the OpenRegionSettings module, adds a new panel to Region/Estate for OpenRegionSettings, adds the new CAPS based WindLight Settings module, cleans up a few UI parts, and rebuilds the ToS window to support OpenSim regions better. --- linden/etc/message.xml | 10 +- linden/indra/llcommon/lltimer.cpp | 28 + linden/indra/llcommon/lltimer.h | 1 + linden/indra/newview/CMakeLists.txt | 9 + linden/indra/newview/hippoLimits.cpp | 123 +- linden/indra/newview/hippoLimits.h | 33 +- .../indra/newview/kowopenregionsettings.cpp | 92 +- linden/indra/newview/llagent.cpp | 10 +- linden/indra/newview/llagent.h | 2 + linden/indra/newview/llappviewer.cpp | 2 +- linden/indra/newview/llcloud.cpp | 30 +- linden/indra/newview/llfloaterenvsettings.cpp | 8 +- linden/indra/newview/llfloaterenvsettings.h | 3 + linden/indra/newview/llfloatermap.cpp | 4 +- linden/indra/newview/llfloaterregioninfo.cpp | 6734 +++++++++-------- linden/indra/newview/llfloaterregioninfo.h | 20 + linden/indra/newview/llfloatertools.cpp | 49 +- linden/indra/newview/llfloatertos.cpp | 594 +- linden/indra/newview/llfloaterwater.cpp | 8 + linden/indra/newview/llfloaterwindlight.cpp | 58 +- linden/indra/newview/llfloaterwindlight.h | 4 + .../indra/newview/llhomelocationresponder.cpp | 2 + linden/indra/newview/llmaniptranslate.cpp | 2 +- linden/indra/newview/llprefschat.cpp | 5 + linden/indra/newview/llsurface.cpp | 26 +- linden/indra/newview/llsurface.h | 2 + linden/indra/newview/lltooldraganddrop.cpp | 10 +- linden/indra/newview/llviewerdisplay.cpp | 20 +- linden/indra/newview/llviewerinventory.cpp | 2 +- linden/indra/newview/llviewermessage.cpp | 16 +- linden/indra/newview/llviewerregion.cpp | 9 + linden/indra/newview/llviewerregion.h | 4 +- linden/indra/newview/llvoavatar.cpp | 3 +- linden/indra/newview/llvoavatar.h | 1 + linden/indra/newview/llwaterparammanager.cpp | 38 +- linden/indra/newview/llwaterparammanager.h | 7 + linden/indra/newview/llwaterparamset.cpp | 92 + linden/indra/newview/llwlparammanager.cpp | 42 + linden/indra/newview/llwlparammanager.h | 7 + linden/indra/newview/llwlparamset.cpp | 5 + linden/indra/newview/llworld.cpp | 11 +- linden/indra/newview/llworld.h | 2 + linden/indra/newview/pipeline.cpp | 4 + .../xui/en-us/floater_avatar_picker.xml | 2 +- .../xui/en-us/floater_env_settings.xml | 10 +- .../xui/en-us/floater_script_ed_panel.xml | 2 +- .../skins/default/xui/en-us/floater_tos.xml | 9 +- .../skins/default/xui/en-us/floater_water.xml | 549 +- .../xui/en-us/floater_windlight_manager.xml | 35 + .../xui/en-us/floater_windlight_options.xml | 45 +- .../en-us/floater_windlight_remote_save.xml | 123 + .../default/xui/en-us/floater_world_map.xml | 366 +- .../xui/en-us/legacy_menu_pie_attachment.xml | 46 +- .../skins/default/xui/en-us/notifications.xml | 84 + .../skins/default/xui/en-us/panel_avatar.xml | 10 +- .../xui/en-us/panel_preferences_chat.xml | 8 +- .../xui/en-us/panel_preferences_general.xml | 46 +- .../xui/en-us/panel_preferences_skins.xml | 28 +- .../skins/default/xui/en-us/panel_radar.xml | 8 +- .../default/xui/en-us/panel_region_estate.xml | 13 +- .../xui/en-us/panel_region_general.xml | 13 +- .../panel_region_open_region_settings.xml | 76 + linden/indra/newview/viewertime.cpp | 20 +- linden/indra/newview/viewertime.h | 3 + .../indra/newview/windlightsettingsupdate.cpp | 200 + linden/indra/newview/wlfloatermanager.cpp | 281 + linden/indra/newview/wlfloatermanager.h | 93 + .../indra/newview/wlfloaterwindlightsend.cpp | 300 + linden/indra/newview/wlfloaterwindlightsend.h | 88 + linden/indra/newview/wlretrievesettings.cpp | 238 + linden/indra/newview/wlretrievesettings.h | 59 + linden/indra/newview/wlsettingsmanager.cpp | 249 + linden/indra/newview/wlsettingsmanager.h | 90 + 73 files changed, 7006 insertions(+), 4220 deletions(-) create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_windlight_manager.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_windlight_remote_save.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/panel_region_open_region_settings.xml create mode 100644 linden/indra/newview/windlightsettingsupdate.cpp create mode 100644 linden/indra/newview/wlfloatermanager.cpp create mode 100644 linden/indra/newview/wlfloatermanager.h create mode 100644 linden/indra/newview/wlfloaterwindlightsend.cpp create mode 100644 linden/indra/newview/wlfloaterwindlightsend.h create mode 100644 linden/indra/newview/wlretrievesettings.cpp create mode 100644 linden/indra/newview/wlretrievesettings.h create mode 100644 linden/indra/newview/wlsettingsmanager.cpp create mode 100644 linden/indra/newview/wlsettingsmanager.h diff --git a/linden/etc/message.xml b/linden/etc/message.xml index f9baf0bfe..c53e84604 100644 --- a/linden/etc/message.xml +++ b/linden/etc/message.xml @@ -378,7 +378,15 @@ <boolean>true</boolean> </map> - <key>ParcelVoiceInfo</key> + <key>WindLightSettingsUpdate</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ParcelVoiceInfo</key> <map> <key>flavor</key> <string>llsd</string> diff --git a/linden/indra/llcommon/lltimer.cpp b/linden/indra/llcommon/lltimer.cpp index fa6efaf38..fb3e1ef27 100644 --- a/linden/indra/llcommon/lltimer.cpp +++ b/linden/indra/llcommon/lltimer.cpp @@ -527,6 +527,34 @@ struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) } +struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST) +{ + if (DST) + { + //Subtract one then + offset--; + } + + // We subtract off the PST/PDT offset _before_ getting + // "UTC" time, because this will handle wrapping around + // for 5 AM UTC -> 10 PM PDT of the previous day. + utc_time -= offset * MIN_PER_HOUR * SEC_PER_MIN; + + // Internal buffer to PST/PDT (see above) + struct tm* internal_time = gmtime(&utc_time); + + /* + // Don't do this, this won't correctly tell you if daylight savings is active in CA or not. + if (pacific_daylight_time) + { + internal_time->tm_isdst = 1; + } + */ + + return internal_time; +} + + void microsecondsToTimecodeString(U64 current_time, std::string& tcstring) { U64 hours; diff --git a/linden/indra/llcommon/lltimer.h b/linden/indra/llcommon/lltimer.h index e2cf1c768..a6532334e 100644 --- a/linden/indra/llcommon/lltimer.h +++ b/linden/indra/llcommon/lltimer.h @@ -166,6 +166,7 @@ BOOL is_daylight_savings(); // utc_time = time_corrected(); // struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight); struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); +struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST); void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); void secondsToTimecodeString(F32 current_time, std::string& tcstring); diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 1a6ad306c..c3c656666 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -493,6 +493,11 @@ set(viewer_SOURCE_FILES rlvfloaterbehaviour.cpp viewertime.cpp viewerversion.cpp + windlightsettingsupdate.cpp + wlfloatermanager.cpp + wlfloaterwindlightsend.cpp + wlretrievesettings.cpp + wlsettingsmanager.cpp ) set(VIEWER_BINARY_NAME "imprudence-bin" CACHE STRING @@ -950,6 +955,10 @@ set(viewer_HEADER_FILES VorbisFramework.h viewertime.h viewerversion.h + wlfloatermanager.h + wlfloaterwindlightsend.h + wlretrievesettings.h + wlsettingsmanager.h ) source_group("CMake Rules" FILES ViewerInstall.cmake) diff --git a/linden/indra/newview/hippoLimits.cpp b/linden/indra/newview/hippoLimits.cpp index 92e2ed32e..88b86a9dc 100644 --- a/linden/indra/newview/hippoLimits.cpp +++ b/linden/indra/newview/hippoLimits.cpp @@ -43,11 +43,30 @@ void HippoLimits::setLimits() void HippoLimits::setOpenSimLimits() { mMaxAgentGroups = gHippoGridManager->getConnectedGrid()->getMaxAgentGroups(); - if (mMaxAgentGroups < 0) mMaxAgentGroups = 50; + + if (mMaxAgentGroups < 0) + mMaxAgentGroups = 50; + mMaxPrimScale = 256.0f; mMinPrimScale = 0.001f; + mMinPrimXPos = 0; + mMinPrimYPos = 0; + mMinPrimZPos = 0; + mMaxPrimXPos = F32_MAX; + mMaxPrimYPos = F32_MAX; + mMaxPrimZPos = F32_MAX; mMaxHeight = 10000.0f; mMaxLinkedPrims = -1; + mMaxPhysLinkedPrims = -1; + mAllowParcelWindLight = TRUE; + mAllowMinimap = TRUE; + mMaxInventoryItemsTransfer = -1; + mRenderName = 2; + mAllowPhysicalPrims = TRUE; + skyUseClassicClouds = TRUE; + mEnableTeenMode = FALSE; + mEnforceMaxBuild = FALSE; + mRenderWater = TRUE; if (gHippoGridManager->getConnectedGrid()->isRenderCompat()) { llinfos << "Using rendering compatible OpenSim limits" << llendl; @@ -72,11 +91,27 @@ void HippoLimits::setSecondLifeLimits() mMinHoleSize = 0.05f; mMaxHollow = 0.95f; mMaxLinkedPrims = 255; + mMaxPhysLinkedPrims = 32; + mMinPrimXPos = 0; + mMinPrimYPos = 0; + mMinPrimZPos = 0; + mMaxPrimXPos = 256; + mMaxPrimYPos = 256; + mMaxPrimZPos = 4096; + mAllowParcelWindLight = FALSE; + mAllowMinimap = TRUE; + mMaxInventoryItemsTransfer = 42; + mRenderName = 2; + mAllowPhysicalPrims = TRUE; + skyUseClassicClouds = TRUE; + mEnableTeenMode = FALSE; + mEnforceMaxBuild = FALSE; + mRenderWater = TRUE; } F32 HippoLimits::getMaxPrimScale() const { - if (gSavedSettings.getBOOL("DisableMaxBuildConstraints")) + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) { return FLT_MAX; } @@ -85,3 +120,87 @@ F32 HippoLimits::getMaxPrimScale() const return mMaxPrimScale; } } + +F32 HippoLimits::getMinPrimScale() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return 0; + } + else + { + return mMinPrimScale; + } +} + +F32 HippoLimits::getMaxPrimXPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMaxPrimXPos; + } +} + +F32 HippoLimits::getMaxPrimYPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMaxPrimYPos; + } +} + +F32 HippoLimits::getMaxPrimZPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMaxPrimZPos; + } +} + +F32 HippoLimits::getMinPrimXPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMinPrimXPos; + } +} + +F32 HippoLimits::getMinPrimYPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMinPrimYPos; + } +} + +F32 HippoLimits::getMinPrimZPos() const +{ + if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) + { + return FLT_MAX; + } + else + { + return mMinPrimZPos; + } +} diff --git a/linden/indra/newview/hippoLimits.h b/linden/indra/newview/hippoLimits.h index a5fe3518c..a5493eb2d 100644 --- a/linden/indra/newview/hippoLimits.h +++ b/linden/indra/newview/hippoLimits.h @@ -11,12 +11,23 @@ class HippoLimits const F32& getMaxHeight() const { return mMaxHeight; } const F32& getMinHoleSize() const { return mMinHoleSize; } const F32& getMaxHollow() const { return mMaxHollow; } - const F32& getMinPrimScale() const { return mMinPrimScale; } const S32& getMaxLinkedPrims() const { return mMaxLinkedPrims; } + const F32& getMaxDragDistance() const { return mMaxDragDistance; } + const S32& getMaxPhysLinkedPrims() const { return mMaxPhysLinkedPrims; } + const F32& getMaxInventoryItemsTransfer() const { return mMaxInventoryItemsTransfer; } + // Returns the max prim size we can use on a grid + F32 getMinPrimScale() const; F32 getMaxPrimScale() const; + F32 getMinPrimXPos() const; + F32 getMinPrimYPos() const; + F32 getMinPrimZPos() const; + F32 getMaxPrimXPos() const; + F32 getMaxPrimYPos() const; + F32 getMaxPrimZPos() const; + void setLimits(); S32 mMaxAgentGroups; @@ -27,6 +38,26 @@ class HippoLimits F32 mMaxPrimScale; F32 mMinPrimScale; S32 mMaxLinkedPrims; + S32 mMaxPhysLinkedPrims; + F32 mMaxPrimXPos; + F32 mMaxPrimYPos; + F32 mMaxPrimZPos; + F32 mMinPrimXPos; + F32 mMinPrimYPos; + F32 mMinPrimZPos; + + S32 mRenderName; + + F32 mMaxInventoryItemsTransfer; + F32 mMaxDragDistance; + + BOOL skyUseClassicClouds; + BOOL mAllowParcelWindLight; + BOOL mAllowMinimap; + BOOL mAllowPhysicalPrims; + BOOL mEnableTeenMode; + BOOL mEnforceMaxBuild; + BOOL mRenderWater; private: void setOpenSimLimits(); diff --git a/linden/indra/newview/kowopenregionsettings.cpp b/linden/indra/newview/kowopenregionsettings.cpp index f568473aa..3cceb0cb3 100644 --- a/linden/indra/newview/kowopenregionsettings.cpp +++ b/linden/indra/newview/kowopenregionsettings.cpp @@ -30,6 +30,12 @@ #include "hippoLimits.h" #include "llfloatertools.h" #include "llviewercontrol.h" +#include "llagent.h" +#include "llsurface.h" +#include "llviewerregion.h" +#include "llviewerobject.h" +#include "llfloaterregioninfo.h" +#include "llfloaterworldmap.h" //DEBUG includes //#include "llsdserialize.h" //LLSDNotationStreamer - for dumping LLSD to string @@ -62,19 +68,20 @@ class OpenRegionInfoUpdate : public LLHTTPNode if ( body.has("AllowMinimap") ) { - //IMPLEMENT ME + gHippoLimits->mAllowMinimap = body["AllowMinimap"].asInteger() == 1; } if ( body.has("AllowPhysicalPrims") ) { - //IMPLEMENT ME + gHippoLimits->mAllowPhysicalPrims = body["AllowPhysicalPrims"].asInteger() == 1; + limitschanged = TRUE; } if ( body.has("DrawDistance") ) { - //IMPLEMENT ME + gAgent.mDrawDistance = body["DrawDistance"].asReal(); } if ( body.has("ForceDrawDistance") ) { - //IMPLEMENT ME + gAgent.mLockedDrawDistance = body["ForceDrawDistance"].asInteger() == 1; } if ( body.has("LSLFunctions") ) { @@ -82,19 +89,23 @@ class OpenRegionInfoUpdate : public LLHTTPNode } if ( body.has("MaxDragDistance") ) { - //IMPLEMENT ME + gHippoLimits->mMaxDragDistance = body["MaxDragDistance"].asReal(); } if ( body.has("MinHoleSize") ) { + //Note: does NOT update correctly gHippoLimits->mMinHoleSize = body["MinHoleSize"].asReal(); + limitschanged = TRUE; } if ( body.has("MaxHollowSize") ) { + //Note: does NOT update correctly gHippoLimits->mMaxHollow = body["MaxHollowSize"].asReal(); + limitschanged = TRUE; } if ( body.has("MaxInventoryItemsTransfer") ) { - //IMPLEMENT ME + gHippoLimits->mMaxInventoryItemsTransfer = body["MaxInventoryItemsTransfer"].asReal(); } if ( body.has("MaxLinkCount") ) { @@ -102,22 +113,28 @@ class OpenRegionInfoUpdate : public LLHTTPNode } if ( body.has("MaxLinkCountPhys") ) { - //IMPLEMENT ME + gHippoLimits->mMaxPhysLinkedPrims = body["MaxLinkCountPhys"].asInteger(); } - if ( body.has("MaxPhysPrimScale") ) + if ( body.has("MaxPos") ) { - //IMPLEMENT ME + gHippoLimits->mMaxPrimXPos = body["MaxPosX"].asReal(); + gHippoLimits->mMaxPrimYPos = body["MaxPosY"].asReal(); + gHippoLimits->mMaxPrimZPos = body["MaxPosZ"].asReal(); + limitschanged = TRUE; } - if ( body.has("MaxPos") ) + if ( body.has("MinPos") ) { - //IMPLEMENT ME + gHippoLimits->mMinPrimXPos = body["MinPosX"].asReal(); + gHippoLimits->mMinPrimYPos = body["MinPosY"].asReal(); + gHippoLimits->mMinPrimZPos = body["MinPosZ"].asReal(); + limitschanged = TRUE; } if ( body.has("MaxPrimScale") ) { gHippoLimits->mMaxPrimScale = body["MaxPrimScale"].asReal(); limitschanged = TRUE; } - if ( body.has("MinPos") ) + if ( body.has("MaxPhysPrimScale") ) { //IMPLEMENT ME } @@ -128,32 +145,69 @@ class OpenRegionInfoUpdate : public LLHTTPNode } if ( body.has("OffsetOfUTC") ) { - //IMPLEMENT ME + gSavedSettings.setS32("TimeOffset", body["OffsetOfUTC"].asReal()); + gSavedSettings.setBOOL("UseTimeOffset", true); + } + if ( body.has("OffsetOfUTCDST") ) + { + gSavedSettings.setBOOL("TimeOffsetDST", body["OffsetOfUTCDST"].asInteger() == 1 ? TRUE : FALSE); } if ( body.has("RenderWater") ) { - gSavedSettings.setBOOL("RenderWater", body["RenderWater"].asBoolean()); + gHippoLimits->mRenderWater = body["RenderWater"].asInteger() == 1 ? TRUE : FALSE; + gAgent.getRegion()->rebuildWater(); } if ( body.has("SayDistance") ) { - //IMPLEMENT ME + gSavedSettings.setU32("ChatDistance", body["SayDistance"].asReal()); } if ( body.has("ShoutDistance") ) { //IMPLEMENT ME } + if ( body.has("WhisperDistance") ) + { + //IMPLEMENT ME + } if ( body.has("ToggleTeenMode") ) { - gSavedSettings.setBOOL("ToggleTeenMode", body["ToggleTeenMode"].asBoolean()); - + gHippoLimits->mEnableTeenMode = body["ToggleTeenMode"].asInteger() == 1 ? TRUE : FALSE; } - if ( body.has("WhisperDistance") ) + if ( body.has("SetTeenMode") ) { - //IMPLEMENT ME + gAgent.setTeen( body["SetTeenMode"].asInteger() == 1 ? TRUE : FALSE ); + LLFloaterWorldMap::reloadIcons(NULL); + llinfos << "PG status set to " << (S32)gAgent.isTeen() << llendl; + } + if ( body.has("ShowTags") ) + { + gHippoLimits->mRenderName = body["ShowTags"].asReal(); + } + if ( body.has("EnforceMaxBuild") ) + { + gHippoLimits->mEnforceMaxBuild = body["EnforceMaxBuild"].asInteger() == 1 ? TRUE : FALSE; + limitschanged = TRUE; + } + if ( body.has("MaxGroups") ) + { + gHippoLimits->mMaxAgentGroups = body["MaxGroups"].asReal(); + } + if ( body.has("AllowParcelWindLight") ) + { + gHippoLimits->mAllowParcelWindLight = body["AllowParcelWindLight"].asInteger() == 1; } if (limitschanged) gFloaterTools->updateToolsSizeLimits(); + + //Update the floater if its around + LLPanelRegionOpenSettingsInfo* floater; + floater = LLFloaterRegionInfo::getPanelOpenSettings(); + + if(floater != NULL) + { + floater->refreshFromRegion(gAgent.getRegion()); + } } }; diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 758cae25b..de1fc841c 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -36,7 +36,6 @@ #include "stdenums.h" #include "llagent.h" - #include "llcamera.h" #include "llcoordframe.h" #include "indra_constants.h" @@ -441,6 +440,7 @@ LLAgent::LLAgent() : void LLAgent::init() { mDrawDistance = gSavedSettings.getF32("RenderFarClip"); + mLockedDrawDistance = FALSE; // *Note: this is where LLViewerCamera::getInstance() used to be constructed. @@ -6026,6 +6026,14 @@ void LLAgent::setHomePosRegion( const U64& region_handle, const LLVector3& pos_r mHomePosRegion = pos_region; } +void LLAgent::takeHomeScreenshot() +{ + std::string snap_filename = gDirUtilp->getLindenUserDir(); + snap_filename += gDirUtilp->getDirDelimiter(); + snap_filename += SCREEN_HOME_FILENAME; + gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight(), FALSE, FALSE); +} + BOOL LLAgent::getHomePosGlobal( LLVector3d* pos_global ) { if(!mHaveHomePosition) diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 6bc4dac78..fe50bf5a7 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -584,6 +584,7 @@ class LLAgent : public LLObservable EPointAtType getPointAtType(); void setHomePosRegion( const U64& region_handle, const LLVector3& pos_region ); + void takeHomeScreenshot(); BOOL getHomePosGlobal( LLVector3d* pos_global ); void setCameraAnimating( BOOL b ) { mCameraAnimating = b; } BOOL getCameraAnimating( ) { return mCameraAnimating; } @@ -742,6 +743,7 @@ class LLAgent : public LLObservable LLUUID mSecureSessionID; // secure token for this login session F32 mDrawDistance; + BOOL mLockedDrawDistance; U64 mGroupPowers; BOOL mHideGroupTitle; diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 4485cdfe3..c53ced64d 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -360,7 +360,7 @@ void request_initial_instant_messages() static BOOL requested = FALSE; if (!requested && gMessageSystem - && LLMuteList::getInstance()->isLoaded() + //&& LLMuteList::getInstance()->isLoaded() //We don't always want to have a mute list module && gAgent.getAvatarObject()) { // Auto-accepted inventory items may require the avatar object diff --git a/linden/indra/newview/llcloud.cpp b/linden/indra/newview/llcloud.cpp index 0099817de..f4f5761b2 100644 --- a/linden/indra/newview/llcloud.cpp +++ b/linden/indra/newview/llcloud.cpp @@ -38,6 +38,7 @@ #include "v4math.h" #include "llquaternion.h" #include "v4color.h" +#include "llviewercontrol.h" #include "llwind.h" #include "llcloud.h" @@ -56,15 +57,6 @@ extern LLPipeline gPipeline; -const F32 CLOUD_UPDATE_RATE = 1.0f; // Global time dilation for clouds -const F32 CLOUD_GROW_RATE = 0.05f; -const F32 CLOUD_DECAY_RATE = -0.05f; -const F32 CLOUD_VELOCITY_SCALE = 0.01f; -const F32 CLOUD_DENSITY = 25.f; -const S32 CLOUD_COUNT_MAX = 20; -const F32 CLOUD_HEIGHT_RANGE = 48.f; -const F32 CLOUD_HEIGHT_MEAN = 192.f; - enum { LL_PUFF_GROWING = 0, @@ -80,7 +72,7 @@ S32 LLCloudPuff::sPuffCount = 0; LLCloudPuff::LLCloudPuff() : mAlpha(0.01f), - mRate(CLOUD_GROW_RATE*CLOUD_UPDATE_RATE), + mRate((gSavedSettings.getF32("CloudGrowRate")/100)*gSavedSettings.getF32("CloudUpdateRate")), mLifeState(LL_PUFF_GROWING) { } @@ -121,7 +113,7 @@ void LLCloudGroup::updatePuffs(const F32 dt) mVOCloudsp->setPositionRegion(mCenterRegion); mVOCloudsp->setScale(LLVector3(256.f/CLOUD_GROUPS_PER_EDGE + CLOUD_PUFF_WIDTH, 256.f/CLOUD_GROUPS_PER_EDGE + CLOUD_PUFF_WIDTH, - CLOUD_HEIGHT_RANGE + CLOUD_PUFF_HEIGHT)*0.5f); + gSavedSettings.getF32("ClassicCloudRange") + CLOUD_PUFF_HEIGHT)*0.5f); gPipeline.createObject(mVOCloudsp); } @@ -132,7 +124,7 @@ void LLCloudGroup::updatePuffs(const F32 dt) { LLCloudPuff &puff = mCloudPuffs[i]; velocity = mCloudLayerp->getRegion()->mWind.getCloudVelocity(mCloudLayerp->getRegion()->getPosRegionFromGlobal(puff.mPositionGlobal)); - velocity *= CLOUD_VELOCITY_SCALE*CLOUD_UPDATE_RATE; + velocity *= (gSavedSettings.getF32("CloudVelocityScale")/100)*gSavedSettings.getF32("CloudUpdateRate"); vel_d.setVec(velocity); mCloudPuffs[i].mPositionGlobal += vel_d; mCloudPuffs[i].mAlpha += mCloudPuffs[i].mRate * dt; @@ -163,7 +155,7 @@ void LLCloudGroup::updatePuffOwnership() { //llinfos << "Killing puff not in group" << llendl; mCloudPuffs[i].setLifeState(LL_PUFF_DYING); - mCloudPuffs[i].mRate = CLOUD_DECAY_RATE*CLOUD_UPDATE_RATE; + mCloudPuffs[i].mRate = (gSavedSettings.getF32("CloudDecayRate")/100)*gSavedSettings.getF32("CloudUpdateRate"); i++; continue; } @@ -185,9 +177,9 @@ void LLCloudGroup::updatePuffCount() return; } S32 i; - S32 target_puff_count = llround(CLOUD_DENSITY * mDensity); + S32 target_puff_count = llround((S32)gSavedSettings.getF32("CloudDensity") * mDensity); target_puff_count = llmax(0, target_puff_count); - target_puff_count = llmin(CLOUD_COUNT_MAX, target_puff_count); + target_puff_count = llmin((S32)gSavedSettings.getF32("CloudCountMax"), target_puff_count); S32 current_puff_count = (S32) mCloudPuffs.size(); // Create a new cloud if we need one if (current_puff_count < target_puff_count) @@ -199,7 +191,7 @@ void LLCloudGroup::updatePuffCount() puff_pos_global = mVOCloudsp->getPositionGlobal(); F32 x = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE; F32 y = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE; - F32 z = ll_frand(CLOUD_HEIGHT_RANGE) - 0.5f*CLOUD_HEIGHT_RANGE; + F32 z = ll_frand(gSavedSettings.getF32("ClassicCloudRange")) - 0.5f*gSavedSettings.getF32("ClassicCloudRange"); puff_pos_global += LLVector3d(x, y, z); mCloudPuffs[i].mPositionGlobal = puff_pos_global; mCloudPuffs[i].mAlpha = 0.01f; @@ -227,7 +219,7 @@ void LLCloudGroup::updatePuffCount() { //llinfos << "Killing extra live cloud" << llendl; mCloudPuffs[i].setLifeState(LL_PUFF_DYING); - mCloudPuffs[i].mRate = CLOUD_DECAY_RATE*CLOUD_UPDATE_RATE; + mCloudPuffs[i].mRate = (gSavedSettings.getF32("CloudDecayRate")/100)*gSavedSettings.getF32("CloudUpdateRate"); new_dying_count--; } i++; @@ -294,7 +286,7 @@ LLCloudLayer::LLCloudLayer() x = (0.5f + j)*(256.f/CLOUD_GROUPS_PER_EDGE); mCloudGroups[i][j].setCloudLayerp(this); - mCloudGroups[i][j].setCenterRegion(LLVector3(x, y, CLOUD_HEIGHT_MEAN)); + mCloudGroups[i][j].setCenterRegion(LLVector3(x, y, gSavedSettings.getF32("ClassicCloudHeight"))); } } } @@ -348,8 +340,6 @@ void LLCloudLayer::destroy() void LLCloudLayer::reset() { } - - void LLCloudLayer::setWindPointer(LLWind *windp) { if (mWindp) diff --git a/linden/indra/newview/llfloaterenvsettings.cpp b/linden/indra/newview/llfloaterenvsettings.cpp index 557a5e1d6..801ff49d3 100644 --- a/linden/indra/newview/llfloaterenvsettings.cpp +++ b/linden/indra/newview/llfloaterenvsettings.cpp @@ -47,6 +47,7 @@ #include "llwaterparammanager.h" #include "llmath.h" #include "llviewerwindow.h" +#include "wlfloatermanager.h" #include "pipeline.h" @@ -87,7 +88,7 @@ void LLFloaterEnvSettings::initCallbacks(void) // WL Top childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL); childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL); - childSetAction("EnvSubmitWindlight", onSubmitWindlight, NULL); + childSetAction("EnvWLManager", onOpenWLManager, NULL); childSetAction("EnvUseEstateTimeButton", onUseEstateTime, NULL); childSetAction("EnvSettingsHelpButton", onClickHelp, this); } @@ -285,6 +286,11 @@ void LLFloaterEnvSettings::onOpenAdvancedWater(void* userData) LLFloaterWater::show(); } +void LLFloaterEnvSettings::onOpenWLManager(void* userData) +{ + WLFloaterManager::show(); +} + void LLFloaterEnvSettings::onSubmitWindlight(void* userData) { Meta7WindlightPacket * wl = new Meta7WindlightPacket(); diff --git a/linden/indra/newview/llfloaterenvsettings.h b/linden/indra/newview/llfloaterenvsettings.h index 49bf4fd0d..8b4462105 100644 --- a/linden/indra/newview/llfloaterenvsettings.h +++ b/linden/indra/newview/llfloaterenvsettings.h @@ -78,6 +78,9 @@ class LLFloaterEnvSettings : public LLFloater /// open the advanced water settings menu static void onOpenAdvancedWater(void* userData); + /// open the windlight manager floater + static void onOpenWLManager(void* userData); + /// submit windlight settings to the estate static void onSubmitWindlight(void* userData); diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp index c15678d48..34b8dde3b 100644 --- a/linden/indra/newview/llfloatermap.cpp +++ b/linden/indra/newview/llfloatermap.cpp @@ -44,6 +44,7 @@ #include "lluictrlfactory.h" #include "llfirstuse.h" #include "panelradar.h" +#include "hippoLimits.h" // [RLVa:KB] @@ -149,7 +150,7 @@ void LLFloaterMap::draw() drawChild(mPanelRadar); } } - else + else if (gHippoLimits->mAllowMinimap) //Check for if minimap is blocked { setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); @@ -215,7 +216,6 @@ void LLFloaterMap::setRadarButtonState( bool showing_radar ) } } - void LLFloaterMap::adjustLayout( bool expand ) { S32 radar_height = mPanelRadar->getRect().getHeight(); diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index deee0f68b..c7f1c38fa 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -1,3298 +1,3436 @@ -/** - * @file llfloaterregioninfo.cpp - * @author Aaron Brashears - * @brief Implementation of the region info and controls floater and panels. - * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llfloaterregioninfo.h" - -#include <algorithm> -#include <functional> - -#include "llcachename.h" -#include "lldir.h" -#include "lldispatcher.h" -#include "llglheaders.h" -#include "llregionflags.h" -#include "llstl.h" -#include "indra_constants.h" -#include "message.h" - -#include "llagent.h" -#include "llalertdialog.h" -#include "llappviewer.h" -#include "llfloateravatarpicker.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llfilepicker.h" -#include "llfloaterdaycycle.h" -#include "llfloatergodtools.h" // for send_sim_wide_deletes() -#include "llfloatertopobjects.h" // added to fix SL-32336 -#include "llfloatergroups.h" -#include "llfloatertelehub.h" -#include "llfloaterwindlight.h" -#include "llinventorymodel.h" -#include "lllineeditor.h" -#include "llalertdialog.h" -#include "llnamelistctrl.h" -#include "llsliderctrl.h" -#include "llspinctrl.h" -#include "lltabcontainer.h" -#include "lltextbox.h" -#include "llinventory.h" -#include "lltexturectrl.h" -#include "lltrans.h" -#include "llviewercontrol.h" -#include "lluictrlfactory.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" -#include "llviewerregion.h" -#include "llviewerstats.h" -#include "llviewertexteditor.h" -#include "llviewerwindow.h" -#include "llvlcomposition.h" - -// [RLVa:KB] -#include "rlvhandler.h" -// [/RLVa:KB] - -#define ELAR_ENABLED 0 // Enable when server support is implemented - -const S32 TERRAIN_TEXTURE_COUNT = 4; -const S32 CORNER_COUNT = 4; - -///---------------------------------------------------------------------------- -/// Local class declaration -///---------------------------------------------------------------------------- - -class LLDispatchEstateUpdateInfo : public LLDispatchHandler -{ -public: - LLDispatchEstateUpdateInfo() {} - virtual ~LLDispatchEstateUpdateInfo() {} - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings); -}; - -class LLDispatchSetEstateAccess : public LLDispatchHandler -{ -public: - LLDispatchSetEstateAccess() {} - virtual ~LLDispatchSetEstateAccess() {} - virtual bool operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings); -}; - - -/* -void unpack_request_params( - LLMessageSystem* msg, - LLDispatcher::sparam_t& strings, - LLDispatcher::iparam_t& integers) -{ - char str_buf[MAX_STRING]; - S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData); - S32 i; - for (i = 0; i < str_count; ++i) - { - // we treat the SParam as binary data (since it might be an - // LLUUID in compressed form which may have embedded \0's,) - str_buf[0] = '\0'; - S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam); - if (data_size >= 0) - { - msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam, - str_buf, data_size, i, MAX_STRING - 1); - strings.push_back(std::string(str_buf, data_size)); - } - } - - U32 int_buf; - S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData); - for (i = 0; i < int_count; ++i) - { - msg->getU32("IntegerData", "IParam", int_buf, i); - integers.push_back(int_buf); - } -} -*/ - - - -bool estate_dispatch_initialized = false; - - -///---------------------------------------------------------------------------- -/// LLFloaterRegionInfo -///---------------------------------------------------------------------------- - -//S32 LLFloaterRegionInfo::sRequestSerial = 0; -LLUUID LLFloaterRegionInfo::sRequestInvoice; - -LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", NULL, FALSE); -} - -BOOL LLFloaterRegionInfo::postBuild() -{ - mTab = getChild<LLTabContainer>("region_panels"); - - // contruct the panels - LLPanelRegionInfo* panel; - panel = new LLPanelRegionGeneralInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_general.xml"); - mTab->addTabPanel(panel, panel->getLabel(), TRUE); - - panel = new LLPanelRegionDebugInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_debug.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelRegionTextureInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_texture.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelRegionTerrainInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_terrain.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelEstateInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_estate.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - panel = new LLPanelEstateCovenant; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_covenant.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); - - gMessageSystem->setHandlerFunc( - "EstateOwnerMessage", - &processEstateOwnerRequest); - - return TRUE; -} - -LLFloaterRegionInfo::~LLFloaterRegionInfo() -{ -} - -void LLFloaterRegionInfo::onOpen() -{ - LLRect rect = gSavedSettings.getRect("FloaterRegionInfo"); - S32 left, top; - gFloaterView->getNewFloaterPosition(&left, &top); - rect.translate(left,top); - - refreshFromRegion(gAgent.getRegion()); - requestRegionInfo(); - LLFloater::onOpen(); -} - -// static -void LLFloaterRegionInfo::requestRegionInfo() -{ - LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); - - tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE); - tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE); - tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE); - tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE); - - // Must allow anyone to request the RegionInfo data - // so non-owners/non-gods can see the values. - // Therefore can't use an EstateOwnerMessage JC - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("RequestRegionInfo"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - gAgent.sendReliableMessage(); -} - -// static -void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) -{ - static LLDispatcher dispatch; - if(!findInstance()) - { - return; - } - - if (!estate_dispatch_initialized) - { - LLPanelEstateInfo::initDispatch(dispatch); - } - - LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); - - // unpack the message - std::string request; - LLUUID invoice; - LLDispatcher::sparam_t strings; - LLDispatcher::unpackMessage(msg, request, invoice, strings); - if(invoice != getLastInvoice()) - { - llwarns << "Mismatched Estate message: " << request << llendl; - return; - } - - //dispatch the message - dispatch.dispatch(request, invoice, strings); - - LLViewerRegion* region = gAgent.getRegion(); - panel->updateControls(region); -} - - -// static -void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) -{ - LLPanel* panel; - - llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; - if(!findInstance()) - { - return; - } - - LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); - - LLViewerRegion* region = gAgent.getRegion(); - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - - // extract message - std::string sim_name; - std::string sim_type = LLTrans::getString("land_type_unknown"); - U32 region_flags; - U8 agent_limit; - F32 object_bonus_factor; - U8 sim_access; - F32 water_height; - F32 terrain_raise_limit; - F32 terrain_lower_limit; - BOOL use_estate_sun; - F32 sun_hour; - msg->getString("RegionInfo", "SimName", sim_name); - msg->getU32("RegionInfo", "RegionFlags", region_flags); - msg->getU8("RegionInfo", "MaxAgents", agent_limit); - msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor); - msg->getU8("RegionInfo", "SimAccess", sim_access); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); - msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); - msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun); - // actually the "last set" sun hour, not the current sun hour. JC - msg->getF32("RegionInfo", "SunHour", sun_hour); - // the only reasonable way to decide if we actually have any data is to - // check to see if any of these fields have nonzero sizes - if (msg->getSize("RegionInfo2", "ProductSKU") > 0 || - msg->getSize("RegionInfo2", "ProductName") > 0) - { - msg->getString("RegionInfo2", "ProductName", sim_type); - } - - // GENERAL PANEL - panel = tab->getChild<LLPanel>("General"); - panel->childSetValue("region_text", LLSD(sim_name)); - panel->childSetValue("region_type", LLSD(sim_type)); - panel->childSetValue("version_channel_text", gLastVersionChannel); - - panel->childSetValue("block_terraform_check", (region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); - panel->childSetValue("block_fly_check", (region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); - panel->childSetValue("allow_damage_check", (region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); - panel->childSetValue("restrict_pushobject", (region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); - panel->childSetValue("allow_land_resell_check", (region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); - panel->childSetValue("allow_parcel_changes_check", (region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE ); - panel->childSetValue("block_parcel_search_check", (region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE ); - panel->childSetValue("agent_limit_spin", LLSD((F32)agent_limit) ); - panel->childSetValue("object_bonus_spin", LLSD(object_bonus_factor) ); - panel->childSetValue("access_combo", LLSD(sim_access) ); - - - // detect teen grid for maturity - - U32 parent_estate_id; - msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id); - BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that - panel->childSetEnabled("access_combo", gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid)); - panel->setCtrlsEnabled(allow_modify); - - - // DEBUG PANEL - panel = tab->getChild<LLPanel>("Debug"); - - panel->childSetValue("region_text", LLSD(sim_name) ); - panel->childSetValue("disable_scripts_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) ); - panel->childSetValue("disable_collisions_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) ); - panel->childSetValue("disable_physics_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) ); - panel->setCtrlsEnabled(allow_modify); - - // TERRAIN PANEL - panel = tab->getChild<LLPanel>("Terrain"); - - panel->childSetValue("region_text", LLSD(sim_name)); - panel->childSetValue("water_height_spin", LLSD(water_height)); - panel->childSetValue("terrain_raise_spin", LLSD(terrain_raise_limit)); - panel->childSetValue("terrain_lower_spin", LLSD(terrain_lower_limit)); - panel->childSetValue("use_estate_sun_check", LLSD(use_estate_sun)); - - panel->childSetValue("fixed_sun_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SUN_FIXED))); - panel->childSetEnabled("fixed_sun_check", allow_modify && !use_estate_sun); - panel->childSetValue("sun_hour_slider", LLSD(sun_hour)); - panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); - panel->setCtrlsEnabled(allow_modify); - - getInstance()->refreshFromRegion( gAgent.getRegion() ); -} - -// static -LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() -{ - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); - return panel; -} - -// static -LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() -{ - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); - LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild<LLPanel>("Covenant"); - return panel; -} - -void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) -{ - // call refresh from region on all panels - std::for_each( - mInfoPanels.begin(), - mInfoPanels.end(), - llbind2nd( -#if LL_WINDOWS - std::mem_fun1(&LLPanelRegionInfo::refreshFromRegion), -#else - std::mem_fun(&LLPanelRegionInfo::refreshFromRegion), -#endif - region)); -} - -// public -void LLFloaterRegionInfo::refresh() -{ - for(info_panels_t::iterator iter = mInfoPanels.begin(); - iter != mInfoPanels.end(); ++iter) - { - (*iter)->refresh(); - } -} - - -///---------------------------------------------------------------------------- -/// Local class implementation -///---------------------------------------------------------------------------- - -// -// LLPanelRegionInfo -// - -// static -void LLPanelRegionInfo::onBtnSet(void* user_data) -{ - LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; - if(!panel) return; - if (panel->sendUpdate()) - { - panel->disableButton("apply_btn"); - } -} - -//static -void LLPanelRegionInfo::onChangeChildCtrl(LLUICtrl* ctrl, void* user_data) -{ - if (ctrl) - { - LLPanelRegionInfo* panel = (LLPanelRegionInfo*) ctrl->getParent(); - panel->updateChild(ctrl); - } -} - -// static -// Enables the "set" button if it is not already enabled -void LLPanelRegionInfo::onChangeAnything(LLUICtrl* ctrl, void* user_data) -{ - LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; - if(panel) - { - panel->enableButton("apply_btn"); - panel->refresh(); - } -} - -// static -// Enables set button on change to line editor -void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data) -{ - // reuse the previous method - onChangeAnything(0, user_data); -} - - -// virtual -BOOL LLPanelRegionInfo::postBuild() -{ - childSetAction("apply_btn", onBtnSet, this); - childDisable("apply_btn"); - refresh(); - return TRUE; -} - -// virtual -void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr) -{ -} - -// virtual -bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region) -{ - if (region) mHost = region->getHost(); - return true; -} - -void LLPanelRegionInfo::sendEstateOwnerMessage( - LLMessageSystem* msg, - const std::string& request, - const LLUUID& invoice, - const strings_t& strings) -{ - llinfos << "Sending estate request '" << request << "'" << llendl; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - msg->nextBlock("MethodData"); - msg->addString("Method", request); - msg->addUUID("Invoice", invoice); - if(strings.empty()) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", NULL); - } - else - { - strings_t::const_iterator it = strings.begin(); - strings_t::const_iterator end = strings.end(); - for(; it != end; ++it) - { - msg->nextBlock("ParamList"); - msg->addString("Parameter", *it); - } - } - msg->sendReliable(mHost); -} - -void LLPanelRegionInfo::enableButton(const std::string& btn_name, BOOL enable) -{ - childSetEnabled(btn_name, enable); -} - -void LLPanelRegionInfo::disableButton(const std::string& btn_name) -{ - childDisable(btn_name); -} - -void LLPanelRegionInfo::initCtrl(const std::string& name) -{ - childSetCommitCallback(name, onChangeAnything, this); -} - -void LLPanelRegionInfo::initHelpBtn(const std::string& name, const std::string& xml_alert) -{ - childSetAction(name, onClickHelp, new std::string(xml_alert)); -} - -// static -void LLPanelRegionInfo::onClickHelp(void* data) -{ - std::string* xml_alert = (std::string*)data; - LLNotifications::instance().add(*xml_alert); -} - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionGeneralInfo -// -bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region) -{ - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - childDisable("apply_btn"); - childSetEnabled("access_text", allow_modify); - // childSetEnabled("access_combo", allow_modify); - // now set in processRegionInfo for teen grid detection - childSetEnabled("kick_btn", allow_modify); - childSetEnabled("kick_all_btn", allow_modify); - childSetEnabled("im_btn", allow_modify); - childSetEnabled("manage_telehub_btn", allow_modify); - - // Data gets filled in by processRegionInfo - - return LLPanelRegionInfo::refreshFromRegion(region); -} - -BOOL LLPanelRegionGeneralInfo::postBuild() -{ - // Enable the "Apply" button if something is changed. JC - initCtrl("block_terraform_check"); - initCtrl("block_fly_check"); - initCtrl("allow_damage_check"); - initCtrl("allow_land_resell_check"); - initCtrl("allow_parcel_changes_check"); - initCtrl("agent_limit_spin"); - initCtrl("object_bonus_spin"); - initCtrl("access_combo"); - initCtrl("restrict_pushobject"); - initCtrl("block_parcel_search_check"); - - initHelpBtn("terraform_help", "HelpRegionBlockTerraform"); - initHelpBtn("fly_help", "HelpRegionBlockFly"); - initHelpBtn("damage_help", "HelpRegionAllowDamage"); - initHelpBtn("agent_limit_help", "HelpRegionAgentLimit"); - initHelpBtn("object_bonus_help", "HelpRegionObjectBonus"); - initHelpBtn("access_help", "HelpRegionMaturity"); - initHelpBtn("restrict_pushobject_help", "HelpRegionRestrictPushObject"); - initHelpBtn("land_resell_help", "HelpRegionLandResell"); - initHelpBtn("parcel_changes_help", "HelpParcelChanges"); - initHelpBtn("parcel_search_help", "HelpRegionSearch"); - - childSetAction("kick_btn", onClickKick, this); - childSetAction("kick_all_btn", onClickKickAll, this); - childSetAction("im_btn", onClickMessage, this); - childSetAction("manage_telehub_btn", onClickManageTelehub, this); - - return LLPanelRegionInfo::postBuild(); -} - -// static -void LLPanelRegionGeneralInfo::onClickKick(void* userdata) -{ - llinfos << "LLPanelRegionGeneralInfo::onClickKick" << llendl; - LLPanelRegionGeneralInfo* panelp = (LLPanelRegionGeneralInfo*)userdata; - - // this depends on the grandparent view being a floater - // in order to set up floater dependency - LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); - LLFloater* child_floater = LLFloaterAvatarPicker::show(onKickCommit, userdata, FALSE, TRUE); - parent_floater->addDependentFloater(child_floater); -} - -// static -void LLPanelRegionGeneralInfo::onKickCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata) -{ - if (names.empty() || ids.empty()) return; - if(ids[0].notNull()) - { - LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata; - if(!self) return; - strings_t strings; - // [0] = our agent id - // [1] = target agent id - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); - - ids[0].toString(buffer); - strings.push_back(strings_t::value_type(buffer)); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); - } -} - -// static -void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata) -{ - llinfos << "LLPanelRegionGeneralInfo::onClickKickAll" << llendl; - LLNotifications::instance().add("KickUsersFromRegion", - LLSD(), - LLSD(), - boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); -} - -bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option == 0) - { - strings_t strings; - // [0] = our agent id - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - // historical message name - sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings); - } - return false; -} - -// static -void LLPanelRegionGeneralInfo::onClickMessage(void* userdata) -{ - llinfos << "LLPanelRegionGeneralInfo::onClickMessage" << llendl; - LLNotifications::instance().add("MessageRegion", - LLSD(), - LLSD(), - boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); -} - -// static -bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response) -{ - if(LLNotification::getSelectedOption(notification, response) != 0) return false; - - std::string text = response["message"].asString(); - if (text.empty()) return false; - - llinfos << "Message to everyone: " << text << llendl; - strings_t strings; - // [0] grid_x, unused here - // [1] grid_y, unused here - // [2] agent_id of sender - // [3] sender name - // [4] message - strings.push_back("-1"); - strings.push_back("-1"); - std::string buffer; - gAgent.getID().toString(buffer); - strings.push_back(buffer); - std::string name; - gAgent.buildFullname(name); - strings.push_back(strings_t::value_type(name)); - strings.push_back(strings_t::value_type(text)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings); - return false; -} - -// static -void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data) -{ - LLFloaterRegionInfo::getInstance()->close(); - - LLFloaterTelehub::show(); -} - -// setregioninfo -// strings[0] = 'Y' - block terraform, 'N' - not -// strings[1] = 'Y' - block fly, 'N' - not -// strings[2] = 'Y' - allow damage, 'N' - not -// strings[3] = 'Y' - allow land sale, 'N' - not -// strings[4] = agent limit -// strings[5] = object bonus -// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult) -// strings[7] = restrict pushobject -// strings[8] = 'Y' - allow parcel subdivide, 'N' - not -// strings[9] = 'Y' - block parcel search, 'N' - allow -BOOL LLPanelRegionGeneralInfo::sendUpdate() -{ - llinfos << "LLPanelRegionGeneralInfo::sendUpdate()" << llendl; - - // First try using a Cap. If that fails use the old method. - LLSD body; - std::string url = gAgent.getRegion()->getCapability("DispatchRegionInfo"); - if (!url.empty()) - { - body["block_terraform"] = childGetValue("block_terraform_check"); - body["block_fly"] = childGetValue("block_fly_check"); - body["allow_damage"] = childGetValue("allow_damage_check"); - body["allow_land_resell"] = childGetValue("allow_land_resell_check"); - body["agent_limit"] = childGetValue("agent_limit_spin"); - body["prim_bonus"] = childGetValue("object_bonus_spin"); - body["sim_access"] = childGetValue("access_combo"); - body["restrict_pushobject"] = childGetValue("restrict_pushobject"); - body["allow_parcel_changes"] = childGetValue("allow_parcel_changes_check"); - body["block_parcel_search"] = childGetValue("block_parcel_search_check"); - - LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); - } - else - { - strings_t strings; - std::string buffer; - - buffer = llformat("%s", (childGetValue("block_terraform_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("block_fly_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("allow_damage_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("allow_land_resell_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - F32 value = (F32)childGetValue("agent_limit_spin").asReal(); - buffer = llformat("%f", value); - strings.push_back(strings_t::value_type(buffer)); - - value = (F32)childGetValue("object_bonus_spin").asReal(); - buffer = llformat("%f", value); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%d", childGetValue("access_combo").asInteger()); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("restrict_pushobject").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - buffer = llformat("%s", (childGetValue("allow_parcel_changes_check").asBoolean() ? "Y" : "N")); - strings.push_back(strings_t::value_type(buffer)); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); - } - - // if we changed access levels, tell user about it - LLViewerRegion* region = gAgent.getRegion(); - if (region && (childGetValue("access_combo").asInteger() != region->getSimAccess()) ) - { - LLNotifications::instance().add("RegionMaturityChange"); - } - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionDebugInfo -///////////////////////////////////////////////////////////////////////////// -BOOL LLPanelRegionDebugInfo::postBuild() -{ - LLPanelRegionInfo::postBuild(); - initCtrl("disable_scripts_check"); - initCtrl("disable_collisions_check"); - initCtrl("disable_physics_check"); - - initHelpBtn("disable_scripts_help", "HelpRegionDisableScripts"); - initHelpBtn("disable_collisions_help", "HelpRegionDisableCollisions"); - initHelpBtn("disable_physics_help", "HelpRegionDisablePhysics"); - initHelpBtn("top_colliders_help", "HelpRegionTopColliders"); - initHelpBtn("top_scripts_help", "HelpRegionTopScripts"); - initHelpBtn("restart_help", "HelpRegionRestart"); - - childSetAction("choose_avatar_btn", onClickChooseAvatar, this); - childSetAction("return_btn", onClickReturn, this); - childSetAction("top_colliders_btn", onClickTopColliders, this); - childSetAction("top_scripts_btn", onClickTopScripts, this); - childSetAction("restart_btn", onClickRestart, this); - childSetAction("cancel_restart_btn", onClickCancelRestart, this); - - return TRUE; -} - -// virtual -bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region) -{ - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - childDisable("apply_btn"); - childDisable("target_avatar_name"); - - childSetEnabled("choose_avatar_btn", allow_modify); - childSetEnabled("return_scripts", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("return_other_land", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("return_estate_wide", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("return_btn", allow_modify && !mTargetAvatar.isNull()); - childSetEnabled("top_colliders_btn", allow_modify); - childSetEnabled("top_scripts_btn", allow_modify); - childSetEnabled("restart_btn", allow_modify); - childSetEnabled("cancel_restart_btn", allow_modify); - - return LLPanelRegionInfo::refreshFromRegion(region); -} - -// virtual -BOOL LLPanelRegionDebugInfo::sendUpdate() -{ - llinfos << "LLPanelRegionDebugInfo::sendUpdate" << llendl; - strings_t strings; - std::string buffer; - - buffer = llformat("%s", (childGetValue("disable_scripts_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - - buffer = llformat("%s", (childGetValue("disable_collisions_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - - buffer = llformat("%s", (childGetValue("disable_physics_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings); - return TRUE; -} - -void LLPanelRegionDebugInfo::onClickChooseAvatar(void* data) -{ - LLFloaterAvatarPicker::show(callbackAvatarID, data, FALSE, TRUE); -} - -// static -void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) data; - if (ids.empty() || names.empty()) return; - self->mTargetAvatar = ids[0]; - self->childSetValue("target_avatar_name", LLSD(names[0])); - self->refreshFromRegion( gAgent.getRegion() ); -} - -// static -void LLPanelRegionDebugInfo::onClickReturn(void* data) -{ - LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data; - if (panelp->mTargetAvatar.isNull()) return; - - LLSD args; - args["USER_NAME"] = panelp->childGetValue("target_avatar_name").asString(); - LLSD payload; - payload["avatar_id"] = panelp->mTargetAvatar; - - U32 flags = SWD_ALWAYS_RETURN_OBJECTS; - - if (panelp->childGetValue("return_scripts").asBoolean()) - { - flags |= SWD_SCRIPTED_ONLY; - } - - if (panelp->childGetValue("return_other_land").asBoolean()) - { - flags |= SWD_OTHERS_LAND_ONLY; - } - payload["flags"] = int(flags); - payload["return_estate_wide"] = panelp->childGetValue("return_estate_wide").asBoolean(); - LLNotifications::instance().add("EstateObjectReturn", args, payload, - boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2)); -} - -bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID(); - if (!target_avatar.isNull()) - { - U32 flags = notification["payload"]["flags"].asInteger(); - bool return_estate_wide = notification["payload"]["return_estate_wide"]; - if (return_estate_wide) - { - // send as estate message - routed by spaceserver to all regions in estate - strings_t strings; - strings.push_back(llformat("%d", flags)); - strings.push_back(target_avatar.asString()); - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - - sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); - } - else - { - // send to this simulator only - send_sim_wide_deletes(target_avatar, flags); - } - } - return false; -} - - -// static -void LLPanelRegionDebugInfo::onClickTopColliders(void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("1"); // one physics step - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); - self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); -} - -// static -void LLPanelRegionDebugInfo::onClickTopScripts(void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("6"); // top 5 scripts - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - LLFloaterTopObjects::show(); - LLFloaterTopObjects::clearList(); - self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); -} - -// static -void LLPanelRegionDebugInfo::onClickRestart(void* data) -{ - LLNotifications::instance().add("ConfirmRestart", LLSD(), LLSD(), - boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2)); -} - -bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - strings_t strings; - strings.push_back("120"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); - return false; -} - -// static -void LLPanelRegionDebugInfo::onClickCancelRestart(void* data) -{ - LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; - strings_t strings; - strings.push_back("-1"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); -} - - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionTextureInfo -// -LLPanelRegionTextureInfo::LLPanelRegionTextureInfo() : LLPanelRegionInfo() -{ - // nothing. -} - -bool LLPanelRegionTextureInfo::refreshFromRegion(LLViewerRegion* region) -{ - BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); - setCtrlsEnabled(allow_modify); - childDisable("apply_btn"); - - if (region) - { - childSetValue("region_text", LLSD(region->getName())); - } - else - { - childSetValue("region_text", LLSD("")); - } - - if (!region) return LLPanelRegionInfo::refreshFromRegion(region); - - LLVLComposition* compp = region->getComposition(); - LLTextureCtrl* texture_ctrl; - std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild<LLTextureCtrl>(buffer); - if(texture_ctrl) - { - lldebugs << "Detail Texture " << i << ": " - << compp->getDetailTextureID(i) << llendl; - LLUUID tmp_id(compp->getDetailTextureID(i)); - texture_ctrl->setImageAssetID(tmp_id); - } - } - - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - childSetValue(buffer, LLSD(compp->getStartHeight(i))); - buffer = llformat("height_range_spin_%d", i); - childSetValue(buffer, LLSD(compp->getHeightRange(i))); - } - - // Call the parent for common book-keeping - return LLPanelRegionInfo::refreshFromRegion(region); -} - - -BOOL LLPanelRegionTextureInfo::postBuild() -{ - LLPanelRegionInfo::postBuild(); - std::string buffer; - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - initCtrl(buffer); - } - - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - initCtrl(buffer); - buffer = llformat("height_range_spin_%d", i); - initCtrl(buffer); - } - -// LLButton* btn = new LLButton("dump", LLRect(0, 20, 100, 0), "", onClickDump, this); -// btn->setFollows(FOLLOWS_TOP|FOLLOWS_LEFT); -// addChild(btn); - - return LLPanelRegionInfo::postBuild(); -} - -BOOL LLPanelRegionTextureInfo::sendUpdate() -{ - llinfos << "LLPanelRegionTextureInfo::sendUpdate()" << llendl; - - // Make sure user hasn't chosen wacky textures. - if (!validateTextureSizes()) - { - return FALSE; - } - - LLTextureCtrl* texture_ctrl; - std::string buffer; - std::string id_str; - LLMessageSystem* msg = gMessageSystem; - strings_t strings; - - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - buffer = llformat("texture_detail_%d", i); - texture_ctrl = getChild<LLTextureCtrl>(buffer); - if(texture_ctrl) - { - LLUUID tmp_id(texture_ctrl->getImageAssetID()); - tmp_id.toString(id_str); - buffer = llformat("%d %s", i, id_str.c_str()); - strings.push_back(buffer); - } - } - sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); - strings.clear(); - for(S32 i = 0; i < CORNER_COUNT; ++i) - { - buffer = llformat("height_start_spin_%d", i); - std::string buffer2 = llformat("height_range_spin_%d", i); - std::string buffer3 = llformat("%d %f %f", i, (F32)childGetValue(buffer).asReal(), (F32)childGetValue(buffer2).asReal()); - strings.push_back(buffer3); - } - sendEstateOwnerMessage(msg, "textureheights", invoice, strings); - strings.clear(); - sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); - return TRUE; -} - -BOOL LLPanelRegionTextureInfo::validateTextureSizes() -{ - for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) - { - std::string buffer; - buffer = llformat("texture_detail_%d", i); - LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(buffer); - if (!texture_ctrl) continue; - - LLUUID image_asset_id = texture_ctrl->getImageAssetID(); - LLViewerImage* img = gImageList.getImage(image_asset_id); - S32 components = img->getComponents(); - // Must ask for highest resolution version's width. JC - S32 width = img->getWidth(0); - S32 height = img->getHeight(0); - - //llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl; - - if (components != 3) - { - LLSD args; - args["TEXTURE_NUM"] = i+1; - args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); - LLNotifications::instance().add("InvalidTerrainBitDepth", args); - return FALSE; - } - - if (width > 512 || height > 512) - { - - LLSD args; - args["TEXTURE_NUM"] = i+1; - args["TEXTURE_SIZE_X"] = width; - args["TEXTURE_SIZE_Y"] = height; - LLNotifications::instance().add("InvalidTerrainSize", args); - return FALSE; - - } - } - - return TRUE; -} - - -// static -void LLPanelRegionTextureInfo::onClickDump(void* data) -{ - llinfos << "LLPanelRegionTextureInfo::onClickDump()" << llendl; -} - - -///////////////////////////////////////////////////////////////////////////// -// LLPanelRegionTerrainInfo -///////////////////////////////////////////////////////////////////////////// -BOOL LLPanelRegionTerrainInfo::postBuild() -{ - LLPanelRegionInfo::postBuild(); - - initHelpBtn("water_height_help", "HelpRegionWaterHeight"); - initHelpBtn("terrain_raise_help", "HelpRegionTerrainRaise"); - initHelpBtn("terrain_lower_help", "HelpRegionTerrainLower"); - initHelpBtn("upload_raw_help", "HelpRegionUploadRaw"); - initHelpBtn("download_raw_help", "HelpRegionDownloadRaw"); - initHelpBtn("use_estate_sun_help", "HelpRegionUseEstateSun"); - initHelpBtn("fixed_sun_help", "HelpRegionFixedSun"); - initHelpBtn("bake_terrain_help", "HelpRegionBakeTerrain"); - - initCtrl("water_height_spin"); - initCtrl("terrain_raise_spin"); - initCtrl("terrain_lower_spin"); - - initCtrl("fixed_sun_check"); - childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); - childSetCommitCallback("use_estate_sun_check", onChangeUseEstateTime, this); - childSetCommitCallback("sun_hour_slider", onChangeSunHour, this); - - childSetAction("download_raw_btn", onClickDownloadRaw, this); - childSetAction("upload_raw_btn", onClickUploadRaw, this); - childSetAction("bake_terrain_btn", onClickBakeTerrain, this); - - return TRUE; -} - -// virtual -bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) -{ - llinfos << "LLPanelRegionTerrainInfo::refreshFromRegion" << llendl; - - BOOL owner_or_god = gAgent.isGodlike() - || (region && (region->getOwner() == gAgent.getID())); - BOOL owner_or_god_or_manager = owner_or_god - || (region && region->isEstateManager()); - setCtrlsEnabled(owner_or_god_or_manager); - childDisable("apply_btn"); - - childSetEnabled("download_raw_btn", owner_or_god); - childSetEnabled("upload_raw_btn", owner_or_god); - childSetEnabled("bake_terrain_btn", owner_or_god); - - return LLPanelRegionInfo::refreshFromRegion(region); -} - -// virtual -BOOL LLPanelRegionTerrainInfo::sendUpdate() -{ - llinfos << "LLPanelRegionTerrainInfo::sendUpdate" << llendl; - std::string buffer; - strings_t strings; - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - - buffer = llformat("%f", (F32)childGetValue("water_height_spin").asReal()); - strings.push_back(buffer); - buffer = llformat("%f", (F32)childGetValue("terrain_raise_spin").asReal()); - strings.push_back(buffer); - buffer = llformat("%f", (F32)childGetValue("terrain_lower_spin").asReal()); - strings.push_back(buffer); - buffer = llformat("%s", (childGetValue("use_estate_sun_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - buffer = llformat("%s", (childGetValue("fixed_sun_check").asBoolean() ? "Y" : "N")); - strings.push_back(buffer); - buffer = llformat("%f", (F32)childGetValue("sun_hour_slider").asReal() ); - strings.push_back(buffer); - - // Grab estate information in case the user decided to set the - // region back to estate time. JC - LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); - if (!floater) return true; - - LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); - if (!tab) return true; - - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); - if (!panel) return true; - - BOOL estate_global_time = panel->getGlobalTime(); - BOOL estate_fixed_sun = panel->getFixedSun(); - F32 estate_sun_hour; - if (estate_global_time) - { - estate_sun_hour = 0.f; - } - else - { - estate_sun_hour = panel->getSunHour(); - } - - buffer = llformat("%s", (estate_global_time ? "Y" : "N") ); - strings.push_back(buffer); - buffer = llformat("%s", (estate_fixed_sun ? "Y" : "N") ); - strings.push_back(buffer); - buffer = llformat("%f", estate_sun_hour); - strings.push_back(buffer); - - sendEstateOwnerMessage(gMessageSystem, "setregionterrain", invoice, strings); - return TRUE; -} - -// static -void LLPanelRegionTerrainInfo::onChangeUseEstateTime(LLUICtrl* ctrl, void* user_data) -{ - LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; - if (!panel) return; - BOOL use_estate_sun = panel->childGetValue("use_estate_sun_check").asBoolean(); - panel->childSetEnabled("fixed_sun_check", !use_estate_sun); - panel->childSetEnabled("sun_hour_slider", !use_estate_sun); - if (use_estate_sun) - { - panel->childSetValue("fixed_sun_check", LLSD(FALSE)); - panel->childSetValue("sun_hour_slider", LLSD(0.f)); - } - panel->childEnable("apply_btn"); -} - -// static -void LLPanelRegionTerrainInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) -{ - LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; - if (!panel) return; - // Just enable the apply button. We let the sun-hour slider be enabled - // for both fixed-sun and non-fixed-sun. JC - panel->childEnable("apply_btn"); -} - -// static -void LLPanelRegionTerrainInfo::onChangeSunHour(LLUICtrl* ctrl, void*) -{ - // can't use userdata to get panel, slider uses it internally - LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) ctrl->getParent(); - if (!panel) return; - panel->childEnable("apply_btn"); -} - -// static -void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data) -{ - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw")) - { - llwarns << "No file" << llendl; - return; - } - std::string filepath = picker.getFirstFile(); - gXferManager->expectFileForRequest(filepath); - - LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; - strings_t strings; - strings.push_back("download filename"); - strings.push_back(filepath); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); -} - -// static -void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data) -{ - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW)) - { - llwarns << "No file" << llendl; - return; - } - std::string filepath = picker.getFirstFile(); - gXferManager->expectFileForTransfer(filepath); - - LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; - strings_t strings; - strings.push_back("upload filename"); - strings.push_back(filepath); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); - - LLNotifications::instance().add("RawUploadStarted"); -} - -// static -void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data) -{ - LLNotifications::instance().add( - LLNotification::Params("ConfirmBakeTerrain") - .functor(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2))); -} - -bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - strings_t strings; - strings.push_back("bake"); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); - return false; -} - -///////////////////////////////////////////////////////////////////////////// -// LLPanelEstateInfo -// - -LLPanelEstateInfo::LLPanelEstateInfo() -: LLPanelRegionInfo(), - mEstateID(0) // invalid -{ -} - -// static -void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) -{ - std::string name; - -// name.assign("setowner"); -// static LLDispatchSetEstateOwner set_owner; -// dispatch.addHandler(name, &set_owner); - - name.assign("estateupdateinfo"); - static LLDispatchEstateUpdateInfo estate_update_info; - dispatch.addHandler(name, &estate_update_info); - - name.assign("setaccess"); - static LLDispatchSetEstateAccess set_access; - dispatch.addHandler(name, &set_access); - - estate_dispatch_initialized = true; -} - -// static -// Disables the sun-hour slider and the use fixed time check if the use global time is check -void LLPanelEstateInfo::onChangeUseGlobalTime(LLUICtrl* ctrl, void* user_data) -{ - LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; - if (panel) - { - bool enabled = !panel->childGetValue("use_global_time_check").asBoolean(); - panel->childSetEnabled("sun_hour_slider", enabled); - panel->childSetEnabled("fixed_sun_check", enabled); - panel->childSetValue("fixed_sun_check", LLSD(FALSE)); - panel->enableButton("apply_btn"); - } -} - -// Enables the sun-hour slider if the fixed-sun checkbox is set -void LLPanelEstateInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) -{ - LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; - if (panel) - { - bool enabled = !panel->childGetValue("fixed_sun_check").asBoolean(); - panel->childSetEnabled("use_global_time_check", enabled); - panel->childSetValue("use_global_time_check", LLSD(FALSE)); - panel->enableButton("apply_btn"); - } -} - - - - -//--------------------------------------------------------------------------- -// Add/Remove estate access button callbacks -//--------------------------------------------------------------------------- -void LLPanelEstateInfo::onClickEditSky(void* user_data) -{ - LLFloaterWindLight::show(); -} - -void LLPanelEstateInfo::onClickEditDayCycle(void* user_data) -{ - LLFloaterDayCycle::show(); -} - -// static -void LLPanelEstateInfo::onClickAddAllowedAgent(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("allowed_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - //args - - LLSD args; - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAllowedAgentOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); -} - -// static -void LLPanelEstateInfo::onClickRemoveAllowedAgent(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); -} - -// static -void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("allowed_group_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAllowedGroupsOnRegion", args); - return; - } - - LLNotification::Params params("ChangeLindenAccess"); - params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, self, _1, _2)); - if (isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } -} - -bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) return false; - - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - - LLFloaterGroupPicker* widget; - widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); - if (widget) - { - widget->setSelectCallback(addAllowedGroup2, NULL); - if (parent_floater) - { - LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); - widget->setOrigin(new_rect.mLeft, new_rect.mBottom); - parent_floater->addDependentFloater(widget); - } - } - - return false; -} - -// static -void LLPanelEstateInfo::onClickRemoveAllowedGroup(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); -} - -// static -void LLPanelEstateInfo::onClickAddBannedAgent(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("banned_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxBannedAgentsOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); -} - -// static -void LLPanelEstateInfo::onClickRemoveBannedAgent(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); -} - -// static -void LLPanelEstateInfo::onClickAddEstateManager(void* user_data) -{ - LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; - LLCtrlListInterface *list = self->childGetListInterface("estate_manager_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_MANAGERS) - { // Tell user they can't add more managers - LLSD args; - args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS); - LLNotifications::instance().add("MaxManagersOnRegion", args); - } - else - { // Go pick managers to add - accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); - } -} - -// static -void LLPanelEstateInfo::onClickRemoveEstateManager(void* user_data) -{ - accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); -} - -//--------------------------------------------------------------------------- -// Kick from estate methods -//--------------------------------------------------------------------------- -struct LLKickFromEstateInfo -{ - LLPanelEstateInfo *mEstatePanelp; - LLUUID mAgentID; -}; - -void LLPanelEstateInfo::onClickKickUser(void *user_data) -{ - LLPanelEstateInfo* panelp = (LLPanelEstateInfo*)user_data; - - // this depends on the grandparent view being a floater - // in order to set up floater dependency - LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); - LLFloater* child_floater = LLFloaterAvatarPicker::show(LLPanelEstateInfo::onKickUserCommit, user_data, FALSE, TRUE); - parent_floater->addDependentFloater(child_floater); -} - -void LLPanelEstateInfo::onKickUserCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata) -{ - if (names.empty() || ids.empty()) return; - - //check to make sure there is one valid user and id - if( (ids[0].isNull()) || - (names[0].length() == 0) ) - { - return; - } - - LLPanelEstateInfo* self = (LLPanelEstateInfo*)userdata; - if(!self) return; - - //keep track of what user they want to kick and other misc info - LLKickFromEstateInfo *kick_info = new LLKickFromEstateInfo(); - kick_info->mEstatePanelp = self; - kick_info->mAgentID = ids[0]; - - //Bring up a confirmation dialog - LLSD args; - args["EVIL_USER"] = names[0]; - LLSD payload; - payload["agent_id"] = ids[0]; - LLNotifications::instance().add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, self, _1, _2)); - -} - -bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - switch(option) - { - case 0: - { - //Kick User - strings_t strings; - strings.push_back(notification["payload"]["agent_id"].asString()); - - sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings); - break; - } - default: - break; - } - return false; -} - -//--------------------------------------------------------------------------- -// Core Add/Remove estate access methods -// TODO: INTERNATIONAL: don't build message text here; -// instead, create multiple translatable messages and choose -// one based on the status. -//--------------------------------------------------------------------------- -std::string all_estates_text() -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return "(error)"; - - std::string owner = panel->getOwnerName(); - - LLViewerRegion* region = gAgent.getRegion(); - if (gAgent.isGodlike()) - { - return llformat("all estates\nowned by %s", owner.c_str()); - } - else if (region && region->getOwner() == gAgent.getID()) - { - return "all estates you own"; - } - else if (region && region->isEstateManager()) - { - return llformat("all estates that\nyou manage for %s", owner.c_str()); - } - else - { - return "(error)"; - } -} - -// static -bool LLPanelEstateInfo::isLindenEstate() -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return false; - - U32 estate_id = panel->getEstateID(); - return (estate_id <= ESTATE_LAST_LINDEN); -} - -typedef std::vector<LLUUID> AgentOrGroupIDsVector; -struct LLEstateAccessChangeInfo -{ - LLEstateAccessChangeInfo(const LLSD& sd) - { - mDialogName = sd["dialog_name"].asString(); - mOperationFlag = (U32)sd["operation"].asInteger(); - LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray(); - for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray(); - id_it != end_it; - ++id_it) - { - mAgentOrGroupIDs.push_back(id_it->asUUID()); - } - } - - const LLSD asLLSD() const - { - LLSD sd; - sd["name"] = mDialogName; - sd["operation"] = (S32)mOperationFlag; - for (AgentOrGroupIDsVector::const_iterator it = mAgentOrGroupIDs.begin(); - it != mAgentOrGroupIDs.end(); - ++it) - { - sd["allowed_ids"].append(*it); - } - return sd; - } - - U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. - std::string mDialogName; - AgentOrGroupIDsVector mAgentOrGroupIDs; // List of agent IDs to apply to this change -}; - -// Special case callback for groups, since it has different callback format than names -// static -void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data) -{ - LLSD payload; - payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; - payload["dialog_name"] = "EstateAllowedGroupAdd"; - payload["allowed_ids"].append(id); - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - - LLNotification::Params params("EstateAllowedGroupAdd"); - params.payload(payload) - .substitutions(args) - .functor(accessCoreConfirm); - if (isLindenEstate()) - { - LLNotifications::instance().forceResponse(params, 0); - } - else - { - LLNotifications::instance().add(params); - } -} - -// static -void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dialog_name) -{ - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - // agent id filled in after avatar picker - - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor(accessAddCore2); - - if (isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - // same as clicking "OK" - LLNotifications::instance().forceResponse(params, 0); - } -} - -// static -bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) - { - // abort change - return false; - } - - LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); - // avatar picker yes multi-select, yes close-on-select - LLFloaterAvatarPicker::show(accessAddCore3, (void*)change_info, TRUE, TRUE); - return false; -} - -// static -void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data) -{ - LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; - if (!change_info) return; - if (ids.empty()) - { - // User didn't select a name. - delete change_info; - change_info = NULL; - return; - } - // User did select a name. - change_info->mAgentOrGroupIDs = ids; - // Can't put estate owner on ban list - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return; - LLViewerRegion* region = gAgent.getRegion(); - if (!region) return; - - if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) - { - LLCtrlListInterface *list = panel->childGetListInterface("allowed_avatar_name_list"); - int currentCount = (list ? list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d",ids.size()); - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - args["LIST_TYPE"] = "Allowed Residents"; - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - } - if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) - { - LLCtrlListInterface *list = panel->childGetListInterface("banned_avatar_name_list"); - int currentCount = (list ? list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d",ids.size()); - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - args["LIST_TYPE"] = "Banned Residents"; - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotifications::instance().add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - } - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - - LLNotification::Params params(change_info->mDialogName); - params.substitutions(args) - .payload(change_info->asLLSD()) - .functor(accessCoreConfirm); - - if (isLindenEstate()) - { - // just apply to this estate - LLNotifications::instance().forceResponse(params, 0); - } - else - { - // ask if this estate or all estates with this owner - LLNotifications::instance().add(params); - } -} - -// static -void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return; - LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>(list_ctrl_name); - if (!name_list) return; - - std::vector<LLScrollListItem*> list_vector = name_list->getAllSelected(); - if (list_vector.size() == 0) - return; - - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - - for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin(); - iter != list_vector.end(); - iter++) - { - LLScrollListItem *item = (*iter); - payload["allowed_ids"].append(item->getUUID()); - } - - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor(accessRemoveCore2); - - if (isLindenEstate()) - { - // warn on change linden estate - LLNotifications::instance().add(params); - } - else - { - // just proceed, as if clicking OK - LLNotifications::instance().forceResponse(params, 0); - } -} - -// static -bool LLPanelEstateInfo::accessRemoveCore2(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option != 0) - { - // abort - return false; - } - - // If Linden estate, can only apply to "this" estate, not all estates - // owned by NULL. - if (isLindenEstate()) - { - accessCoreConfirm(notification, response); - } - else - { - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - LLNotifications::instance().add(notification["payload"]["dialog_name"], - args, - notification["payload"], - accessCoreConfirm); - } - return false; -} - -// Used for both access add and remove operations, depending on the mOperationFlag -// passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.) -// static -bool LLPanelEstateInfo::accessCoreConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); - - LLViewerRegion* region = gAgent.getRegion(); - - LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); - - for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); - iter != end_it; - iter++) - { - U32 flags = originalFlags; - if (iter + 1 != end_it) - flags |= ESTATE_ACCESS_NO_REPLY; - - const LLUUID id = iter->asUUID(); - if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) - && region && (region->getOwner() == id)) - { - LLNotifications::instance().add("OwnerCanNotBeDenied"); - break; - } - switch(option) - { - case 0: - // This estate - sendEstateAccessDelta(flags, id); - break; - case 1: - { - // All estates, either than I own or manage for this owner. - // This will be verified on simulator. JC - if (!region) break; - if (region->getOwner() == gAgent.getID() - || gAgent.isGodlike()) - { - flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; - sendEstateAccessDelta(flags, id); - } - else if (region->isEstateManager()) - { - flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; - sendEstateAccessDelta(flags, id); - } - break; - } - case 2: - default: - break; - } - } - return false; -} - -// key = "estateaccessdelta" -// str(estate_id) will be added to front of list by forward_EstateOwnerRequest_to_dataserver -// str[0] = str(agent_id) requesting the change -// str[1] = str(flags) (ESTATE_ACCESS_DELTA_*) -// str[2] = str(agent_id) to add or remove -// static -void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id) -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - - msg->nextBlock("MethodData"); - msg->addString("Method", "estateaccessdelta"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - - std::string buf; - gAgent.getID().toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - buf = llformat("%u", flags); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - agent_or_group_id.toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - - if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | - ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) - { - - panel->clearAccessLists(); - } - - gAgent.sendReliableMessage(); -} - -void LLPanelEstateInfo::updateControls(LLViewerRegion* region) -{ - BOOL god = gAgent.isGodlike(); - BOOL owner = (region && (region->getOwner() == gAgent.getID())); - BOOL manager = (region && region->isEstateManager()); - setCtrlsEnabled(god || owner || manager); - - childDisable("apply_btn"); - childSetEnabled("add_allowed_avatar_btn", god || owner || manager); - childSetEnabled("remove_allowed_avatar_btn", god || owner || manager); - childSetEnabled("add_allowed_group_btn", god || owner || manager); - childSetEnabled("remove_allowed_group_btn", god || owner || manager); - childSetEnabled("add_banned_avatar_btn", god || owner || manager); - childSetEnabled("remove_banned_avatar_btn", god || owner || manager); - childSetEnabled("message_estate_btn", god || owner || manager); - childSetEnabled("kick_user_from_estate_btn", god || owner || manager); -#if ELAR_ENABLED - childSetEnabled("abuse_email_address", god || owner || manager); -#else - childSetEnabled("abuse_email_address", false); -#endif - - // estate managers can't add estate managers - childSetEnabled("add_estate_manager_btn", god || owner); - childSetEnabled("remove_estate_manager_btn", god || owner); - childSetEnabled("estate_manager_name_list", god || owner); -} - -bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) -{ - updateControls(region); - - // let the parent class handle the general data collection. - bool rv = LLPanelRegionInfo::refreshFromRegion(region); - - // We want estate info. To make sure it works across region - // boundaries and multiple packets, we add a serial number to the - // integers and track against that on update. - strings_t strings; - //integers_t integers; - //LLFloaterRegionInfo::incrementSerial(); - LLFloaterRegionInfo::nextInvoice(); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate(); - - - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - panel->clearAccessLists(); - - - sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); - - refresh(); - - return rv; -} - -void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) -{ - if (checkRemovalButton(child_ctrl->getName())) - { - // do nothing - } - else if (checkSunHourSlider(child_ctrl)) - { - // do nothing - } -} - -bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) -{ - llinfos << "LLPanelEstateInfo::estateUpdate()" << llendl; - return false; -} - - -BOOL LLPanelEstateInfo::postBuild() -{ - // set up the callbacks for the generic controls - initCtrl("externally_visible_check"); - initCtrl("use_global_time_check"); - initCtrl("fixed_sun_check"); - initCtrl("allow_direct_teleport"); - initCtrl("limit_payment"); - initCtrl("limit_age_verified"); - initCtrl("voice_chat_check"); - childSetCommitCallback("abuse_email_address", onChangeAnything, this); - childSetKeystrokeCallback("abuse_email_address", onChangeText, this); - - initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); - initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); - initHelpBtn("fixed_sun_help", "HelpEstateFixedSun"); - initHelpBtn("WLEditSkyHelp", "HelpEditSky"); - initHelpBtn("WLEditDayCycleHelp", "HelpEditDayCycle"); - - initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible"); - initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport"); - initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); - initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); - initHelpBtn("ban_resident_help", "HelpEstateBanResident"); - initHelpBtn("abuse_email_address_help", "HelpEstateAbuseEmailAddress"); - initHelpBtn("voice_chat_help", "HelpEstateVoiceChat"); - - // set up the use global time checkbox - childSetCommitCallback("use_global_time_check", onChangeUseGlobalTime, this); - childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); - childSetCommitCallback("sun_hour_slider", onChangeChildCtrl, this); - - childSetCommitCallback("allowed_avatar_name_list", onChangeChildCtrl, this); - LLNameListCtrl *avatar_name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list"); - if (avatar_name_list) - { - avatar_name_list->setCommitOnSelectionChange(TRUE); - avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_allowed_avatar_btn", onClickAddAllowedAgent, this); - childSetAction("remove_allowed_avatar_btn", onClickRemoveAllowedAgent, this); - - childSetCommitCallback("allowed_group_name_list", onChangeChildCtrl, this); - LLNameListCtrl* group_name_list = getChild<LLNameListCtrl>("allowed_group_name_list"); - if (group_name_list) - { - group_name_list->setCommitOnSelectionChange(TRUE); - group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_allowed_group_btn", onClickAddAllowedGroup, this); - childSetAction("remove_allowed_group_btn", onClickRemoveAllowedGroup, this); - - childSetCommitCallback("banned_avatar_name_list", onChangeChildCtrl, this); - LLNameListCtrl* banned_name_list = getChild<LLNameListCtrl>("banned_avatar_name_list"); - if (banned_name_list) - { - banned_name_list->setCommitOnSelectionChange(TRUE); - banned_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_banned_avatar_btn", onClickAddBannedAgent, this); - childSetAction("remove_banned_avatar_btn", onClickRemoveBannedAgent, this); - - childSetCommitCallback("estate_manager_name_list", onChangeChildCtrl, this); - LLNameListCtrl* manager_name_list = getChild<LLNameListCtrl>("estate_manager_name_list"); - if (manager_name_list) - { - manager_name_list->setCommitOnSelectionChange(TRUE); - manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue - } - - childSetAction("add_estate_manager_btn", onClickAddEstateManager, this); - childSetAction("remove_estate_manager_btn", onClickRemoveEstateManager, this); - childSetAction("message_estate_btn", onClickMessageEstate, this); - childSetAction("kick_user_from_estate_btn", onClickKickUser, this); - - childSetAction("WLEditSky", onClickEditSky, this); - childSetAction("WLEditDayCycle", onClickEditDayCycle, this); - - return LLPanelRegionInfo::postBuild(); -} - -void LLPanelEstateInfo::refresh() -{ - bool public_access = childGetValue("externally_visible_check").asBoolean(); - childSetEnabled("Only Allow", public_access); - childSetEnabled("limit_payment", public_access); - childSetEnabled("limit_age_verified", public_access); - // if this is set to false, then the limit fields are meaningless and should be turned off - if (public_access == false) - { - childSetValue("limit_payment", false); - childSetValue("limit_age_verified", false); - } -} - -BOOL LLPanelEstateInfo::sendUpdate() -{ - llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl; - - LLNotification::Params params("ChangeLindenEstate"); - params.functor(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2)); - - if (getEstateID() <= ESTATE_LAST_LINDEN) - { - // trying to change reserved estate, warn - LLNotifications::instance().add(params); - } - else - { - // for normal estates, just make the change - LLNotifications::instance().forceResponse(params, 0); - } - return TRUE; -} - -bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - switch(option) - { - case 0: - // send the update - if (!commitEstateInfoCaps()) - { - // the caps method failed, try the old way - LLFloaterRegionInfo::nextInvoice(); - commitEstateInfoDataserver(); - } - // we don't want to do this because we'll get it automatically from the sim - // after the spaceserver processes it -// else -// { -// // caps method does not automatically send this info -// LLFloaterRegionInfo::requestRegionInfo(); -// } - break; - case 1: - default: - // do nothing - break; - } - return false; -} - - -/* -// Request = "getowner" -// SParam[0] = "" (empty string) -// IParam[0] = serial -void LLPanelEstateInfo::getEstateOwner() -{ - // TODO -- disable the panel - // and call this function whenever we cross a region boundary - // re-enable when owner matches, and get new estate info - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_EstateOwnerRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - - msg->nextBlockFast(_PREHASH_RequestData); - msg->addStringFast(_PREHASH_Request, "getowner"); - - // we send an empty string so that the variable block is not empty - msg->nextBlockFast(_PREHASH_StringData); - msg->addStringFast(_PREHASH_SParam, ""); - - msg->nextBlockFast(_PREHASH_IntegerData); - msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial()); - - gAgent.sendMessage(); -} -*/ - -class LLEstateChangeInfoResponder : public LLHTTPClient::Responder -{ -public: - LLEstateChangeInfoResponder(void* userdata) : mpPanel((LLPanelEstateInfo*)userdata) {}; - - // if we get a normal response, handle it here - virtual void result(const LLSD& content) - { - // refresh the panel from the database - mpPanel->refresh(); - } - - // if we get an error response - virtual void error(U32 status, const std::string& reason) - { - llinfos << "LLEstateChangeInfoResponder::error " - << status << ": " << reason << llendl; - } -private: - LLPanelEstateInfo* mpPanel; -}; - -// tries to send estate info using a cap; returns true if it succeeded -bool LLPanelEstateInfo::commitEstateInfoCaps() -{ - std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo"); - - if (url.empty()) - { - // whoops, couldn't find the cap, so bail out - return false; - } - - LLSD body; - body["estate_name"] = getEstateName(); - - body["is_externally_visible"] = childGetValue("externally_visible_check").asBoolean(); - body["allow_direct_teleport"] = childGetValue("allow_direct_teleport").asBoolean(); - body["is_sun_fixed" ] = childGetValue("fixed_sun_check").asBoolean(); - body["deny_anonymous" ] = childGetValue("limit_payment").asBoolean(); - body["deny_age_unverified" ] = childGetValue("limit_age_verified").asBoolean(); - body["allow_voice_chat" ] = childGetValue("voice_chat_check").asBoolean(); - body["invoice" ] = LLFloaterRegionInfo::getLastInvoice(); - - // block fly is in estate database but not in estate UI, so we're not supporting it - //body["block_fly" ] = childGetValue("").asBoolean(); - - F32 sun_hour = getSunHour(); - if (childGetValue("use_global_time_check").asBoolean()) - { - sun_hour = 0.f; // 0 = global time - } - body["sun_hour"] = sun_hour; - - body["owner_abuse_email"] = childGetValue("abuse_email_address").asString(); - - // we use a responder so that we can re-get the data after committing to the database - LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder((void*)this)); - return true; -} - -/* This is the old way of doing things, is deprecated, and should be - deleted when the dataserver model can be removed */ -// key = "estatechangeinfo" -// strings[0] = str(estate_id) (added by simulator before relay - not here) -// strings[1] = estate_name -// strings[2] = str(estate_flags) -// strings[3] = str((S32)(sun_hour * 1024.f)) -void LLPanelEstateInfo::commitEstateInfoDataserver() -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - - msg->nextBlock("MethodData"); - msg->addString("Method", "estatechangeinfo"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - - msg->nextBlock("ParamList"); - msg->addString("Parameter", getEstateName()); - - std::string buffer; - buffer = llformat("%u", computeEstateFlags()); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - - F32 sun_hour = getSunHour(); - if (childGetValue("use_global_time_check").asBoolean()) - { - sun_hour = 0.f; // 0 = global time - } - - buffer = llformat("%d", (S32)(sun_hour*1024.0f)); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buffer); - - gAgent.sendMessage(); -} - -void LLPanelEstateInfo::setEstateFlags(U32 flags) -{ - childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) ); - childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) ); - childSetValue( - "voice_chat_check", - LLSD(flags & REGION_FLAGS_ALLOW_VOICE ? TRUE : FALSE)); - childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) ); - childSetValue("limit_payment", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) ); - childSetValue("limit_age_verified", LLSD(flags & REGION_FLAGS_DENY_AGEUNVERIFIED ? TRUE : FALSE) ); - - refresh(); -} - -U32 LLPanelEstateInfo::computeEstateFlags() -{ - U32 flags = 0; - - if (childGetValue("externally_visible_check").asBoolean()) - { - flags |= REGION_FLAGS_EXTERNALLY_VISIBLE; - } - - if ( childGetValue("voice_chat_check").asBoolean() ) - { - flags |= REGION_FLAGS_ALLOW_VOICE; - } - - if (childGetValue("allow_direct_teleport").asBoolean()) - { - flags |= REGION_FLAGS_ALLOW_DIRECT_TELEPORT; - } - - if (childGetValue("fixed_sun_check").asBoolean()) - { - flags |= REGION_FLAGS_SUN_FIXED; - } - - if (childGetValue("limit_payment").asBoolean()) - { - flags |= REGION_FLAGS_DENY_ANONYMOUS; - } - - if (childGetValue("limit_age_verified").asBoolean()) - { - flags |= REGION_FLAGS_DENY_AGEUNVERIFIED; - } - - - return flags; -} - -BOOL LLPanelEstateInfo::getGlobalTime() -{ - return childGetValue("use_global_time_check").asBoolean(); -} - -void LLPanelEstateInfo::setGlobalTime(bool b) -{ - childSetValue("use_global_time_check", LLSD(b)); - childSetEnabled("fixed_sun_check", LLSD(!b)); - childSetEnabled("sun_hour_slider", LLSD(!b)); - if (b) - { - childSetValue("sun_hour_slider", LLSD(0.f)); - } -} - - -BOOL LLPanelEstateInfo::getFixedSun() -{ - return childGetValue("fixed_sun_check").asBoolean(); -} - -void LLPanelEstateInfo::setSunHour(F32 sun_hour) -{ - if(sun_hour < 6.0f) - { - sun_hour = 24.0f + sun_hour; - } - childSetValue("sun_hour_slider", LLSD(sun_hour)); -} - -F32 LLPanelEstateInfo::getSunHour() -{ - if (childIsEnabled("sun_hour_slider")) - { - return (F32)childGetValue("sun_hour_slider").asReal(); - } - return 0.f; -} - -const std::string LLPanelEstateInfo::getEstateName() const -{ - return childGetValue("estate_name").asString(); -} - -void LLPanelEstateInfo::setEstateName(const std::string& name) -{ - childSetValue("estate_name", LLSD(name)); -} - -const std::string LLPanelEstateInfo::getOwnerName() const -{ - return childGetValue("estate_owner").asString(); -} - -void LLPanelEstateInfo::setOwnerName(const std::string& name) -{ - childSetValue("estate_owner", LLSD(name)); -} - -const std::string LLPanelEstateInfo::getAbuseEmailAddress() const -{ - return childGetValue("abuse_email_address").asString(); -} - -void LLPanelEstateInfo::setAbuseEmailAddress(const std::string& address) -{ - childSetValue("abuse_email_address", LLSD(address)); -} - -void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, - bool enable_group, - bool enable_ban) -{ - childSetEnabled("allow_resident_label", enable_agent); - childSetEnabled("allowed_avatar_name_list", enable_agent); - childSetVisible("allowed_avatar_name_list", enable_agent); - childSetEnabled("add_allowed_avatar_btn", enable_agent); - childSetEnabled("remove_allowed_avatar_btn", enable_agent); - - // Groups - childSetEnabled("allow_group_label", enable_group); - childSetEnabled("allowed_group_name_list", enable_group); - childSetVisible("allowed_group_name_list", enable_group); - childSetEnabled("add_allowed_group_btn", enable_group); - childSetEnabled("remove_allowed_group_btn", enable_group); - - // Ban - childSetEnabled("ban_resident_label", enable_ban); - childSetEnabled("banned_avatar_name_list", enable_ban); - childSetVisible("banned_avatar_name_list", enable_ban); - childSetEnabled("add_banned_avatar_btn", enable_ban); - childSetEnabled("remove_banned_avatar_btn", enable_ban); - - // Update removal buttons if needed - if (enable_agent) - { - checkRemovalButton("allowed_avatar_name_list"); - } - - if (enable_group) - { - checkRemovalButton("allowed_group_name_list"); - } - - if (enable_ban) - { - checkRemovalButton("banned_avatar_name_list"); - } -} - -// static -void LLPanelEstateInfo::callbackCacheName( - const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group, - void*) -{ - LLPanelEstateInfo* self = LLFloaterRegionInfo::getPanelEstate(); - if (!self) return; - - std::string name; - - if (id.isNull()) - { - name = "(none)"; - } - else - { - name = first + " " + last; - } - - self->setOwnerName(name); -} - -void LLPanelEstateInfo::clearAccessLists() -{ - LLNameListCtrl* name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list"); - if (name_list) - { - name_list->deleteAllItems(); - } - - name_list = getChild<LLNameListCtrl>("banned_avatar_name_list"); - if (name_list) - { - name_list->deleteAllItems(); - } -} - -// enables/disables the "remove" button for the various allow/ban lists -BOOL LLPanelEstateInfo::checkRemovalButton(std::string name) -{ - std::string btn_name = ""; - if (name == "allowed_avatar_name_list") - { - btn_name = "remove_allowed_avatar_btn"; - } - else if (name == "allowed_group_name_list") - { - btn_name = "remove_allowed_group_btn"; - } - else if (name == "banned_avatar_name_list") - { - btn_name = "remove_banned_avatar_btn"; - } - else if (name == "estate_manager_name_list") - { - //ONLY OWNER CAN ADD /DELET ESTATE MANAGER - LLViewerRegion* region = gAgent.getRegion(); - if (region && (region->getOwner() == gAgent.getID())) - { - btn_name = "remove_estate_manager_btn"; - } - } - - // enable the remove button if something is selected - LLNameListCtrl* name_list = getChild<LLNameListCtrl>(name); - childSetEnabled(btn_name, name_list && name_list->getFirstSelected() ? TRUE : FALSE); - - return (btn_name != ""); -} - -BOOL LLPanelEstateInfo::checkSunHourSlider(LLUICtrl* child_ctrl) -{ - BOOL found_child_ctrl = FALSE; - if (child_ctrl->getName() == "sun_hour_slider") - { - enableButton("apply_btn"); - found_child_ctrl = TRUE; - } - return found_child_ctrl; -} - -// static -void LLPanelEstateInfo::onClickMessageEstate(void* userdata) -{ - llinfos << "LLPanelEstateInfo::onClickMessageEstate" << llendl; - LLNotifications::instance().add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2)); -} - -bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - std::string text = response["message"].asString(); - if(option != 0) return false; - if(text.empty()) return false; - llinfos << "Message to everyone: " << text << llendl; - strings_t strings; - //integers_t integers; - std::string name; - gAgent.buildFullname(name); - strings.push_back(strings_t::value_type(name)); - strings.push_back(strings_t::value_type(text)); - LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); - sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings); - return false; -} - -LLPanelEstateCovenant::LLPanelEstateCovenant() -: mCovenantID(LLUUID::null) -{ -} - -// virtual -bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) -{ - LLTextBox* region_name = getChild<LLTextBox>("region_name_text"); - if (region_name) - { - region_name->setText(region->getName()); - } - - LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause"); - if (resellable_clause) - { - if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) - { - resellable_clause->setText(getString("can_not_resell")); - } - else - { - resellable_clause->setText(getString("can_resell")); - } - } - - LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause"); - if (changeable_clause) - { - if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) - { - changeable_clause->setText(getString("can_change")); - } - else - { - changeable_clause->setText(getString("can_not_change")); - } - } - - LLTextBox* region_maturity = getChild<LLTextBox>("region_maturity_text"); - if (region_maturity) - { - region_maturity->setText(region->getSimAccessString()); - } - - LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text"); - if (region_landtype) - { - region_landtype->setText(region->getSimProductName()); - } - - - // let the parent class handle the general data collection. - bool rv = LLPanelRegionInfo::refreshFromRegion(region); - LLMessageSystem *msg = gMessageSystem; - msg->newMessage("EstateCovenantRequest"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); - msg->sendReliable(region->getHost()); - return rv; -} - -// virtual -bool LLPanelEstateCovenant::estateUpdate(LLMessageSystem* msg) -{ - llinfos << "LLPanelEstateCovenant::estateUpdate()" << llendl; - return true; -} - -// virtual -BOOL LLPanelEstateCovenant::postBuild() -{ - initHelpBtn("covenant_help", "HelpEstateCovenant"); - mEstateNameText = getChild<LLTextBox>("estate_name_text"); - mEstateOwnerText = getChild<LLTextBox>("estate_owner_text"); - mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text"); - mEditor = getChild<LLViewerTextEditor>("covenant_editor"); - if (mEditor) mEditor->setHandleEditKeysDirectly(TRUE); - LLButton* reset_button = getChild<LLButton>("reset_covenant"); - reset_button->setEnabled(gAgent.canManageEstate()); - reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); - - return LLPanelRegionInfo::postBuild(); -} - -// virtual -void LLPanelEstateCovenant::updateChild(LLUICtrl* child_ctrl) -{ -} - -// virtual -BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - LLInventoryItem* item = (LLInventoryItem*)cargo_data; - - if (!gAgent.canManageEstate()) - { - *accept = ACCEPT_NO; - return TRUE; - } - - switch(cargo_type) - { - case DAD_NOTECARD: - *accept = ACCEPT_YES_COPY_SINGLE; - if (item && drop) - { - LLSD payload; - payload["item_id"] = item->getUUID(); - LLNotifications::instance().add("EstateChangeCovenant", LLSD(), payload, - LLPanelEstateCovenant::confirmChangeCovenantCallback); - } - break; - default: - *accept = ACCEPT_NO; - break; - } - - return TRUE; -} - -// static -bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); - - if (!item || !self) return false; - - switch(option) - { - case 0: - self->loadInvItem(item); - break; - default: - break; - } - return false; -} - -// static -void LLPanelEstateCovenant::resetCovenantID(void* userdata) -{ - LLNotifications::instance().add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback); -} - -// static -bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response) -{ - LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); - if (!self) return false; - - S32 option = LLNotification::getSelectedOption(notification, response); - switch(option) - { - case 0: - self->loadInvItem(NULL); - break; - default: - break; - } - return false; -} - -void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp) -{ - const BOOL high_priority = TRUE; - if (itemp) - { - gAssetStorage->getInvItemAsset(gAgent.getRegionHost(), - gAgent.getID(), - gAgent.getSessionID(), - itemp->getPermissions().getOwner(), - LLUUID::null, - itemp->getUUID(), - itemp->getAssetUUID(), - itemp->getType(), - onLoadComplete, - (void*)this, - high_priority); - mAssetStatus = ASSET_LOADING; - } - else - { - mAssetStatus = ASSET_LOADED; - setCovenantTextEditor("There is no Covenant provided for this Estate."); - sendChangeCovenantID(LLUUID::null); - } -} - -// static -void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs, - const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status) -{ - llinfos << "LLPanelEstateCovenant::onLoadComplete()" << llendl; - LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data; - if( panelp ) - { - if(0 == status) - { - LLVFile file(vfs, asset_uuid, type, LLVFile::READ); - - S32 file_length = file.getSize(); - - char* buffer = new char[file_length+1]; - if (buffer == NULL) - { - llerrs << "Memory Allocation Failed" << llendl; - return; - } - - file.read((U8*)buffer, file_length); /* Flawfinder: ignore */ - // put a EOS at the end - buffer[file_length] = 0; - - if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) ) - { - if( !panelp->mEditor->importBuffer( buffer, file_length+1 ) ) - { - llwarns << "Problem importing estate covenant." << llendl; - LLNotifications::instance().add("ProblemImportingEstateCovenant"); - } - else - { - panelp->sendChangeCovenantID(asset_uuid); - } - } - else - { - // Version 0 (just text, doesn't include version number) - panelp->sendChangeCovenantID(asset_uuid); - } - delete[] buffer; - } - else - { - LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || - LL_ERR_FILE_EMPTY == status) - { - LLNotifications::instance().add("MissingNotecardAssetID"); - } - else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) - { - LLNotifications::instance().add("NotAllowedToViewNotecard"); - } - else - { - LLNotifications::instance().add("UnableToLoadNotecardAsset"); - } - - llwarns << "Problem loading notecard: " << status << llendl; - } - panelp->mAssetStatus = ASSET_LOADED; - panelp->setCovenantID(asset_uuid); - } -} - -// key = "estatechangecovenantid" -// strings[0] = str(estate_id) (added by simulator before relay - not here) -// strings[1] = str(covenant_id) -void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id) -{ - if (asset_id != getCovenantID()) - { - setCovenantID(asset_id); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - - msg->nextBlock("MethodData"); - msg->addString("Method", "estatechangecovenantid"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - - msg->nextBlock("ParamList"); - msg->addString("Parameter", getCovenantID().asString()); - gAgent.sendReliableMessage(); - } -} - -// virtual -BOOL LLPanelEstateCovenant::sendUpdate() -{ - return TRUE; -} - -const std::string& LLPanelEstateCovenant::getEstateName() const -{ - return mEstateNameText->getText(); -} - -void LLPanelEstateCovenant::setEstateName(const std::string& name) -{ - mEstateNameText->setText(name); -} - -// static -void LLPanelEstateCovenant::updateCovenantText(const std::string& string, const LLUUID& asset_id) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEditor->setText(string); - panelp->setCovenantID(asset_id); - } -} - -// static -void LLPanelEstateCovenant::updateEstateName(const std::string& name) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEstateNameText->setText(name); - } -} - -// static -void LLPanelEstateCovenant::updateLastModified(const std::string& text) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mLastModifiedText->setText(text); - } -} - -// static -void LLPanelEstateCovenant::updateEstateOwnerName(const std::string& name) -{ - LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); - if( panelp ) - { - panelp->mEstateOwnerText->setText(name); - } -} - -const std::string& LLPanelEstateCovenant::getOwnerName() const -{ - return mEstateOwnerText->getText(); -} - -void LLPanelEstateCovenant::setOwnerName(const std::string& name) -{ - mEstateOwnerText->setText(name); -} - -void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text) -{ - mEditor->setText(text); -} - -// key = "estateupdateinfo" -// strings[0] = estate name -// strings[1] = str(owner_id) -// strings[2] = str(estate_id) -// strings[3] = str(estate_flags) -// strings[4] = str((S32)(sun_hour * 1024)) -// strings[5] = str(parent_estate_id) -// strings[6] = str(covenant_id) -// strings[7] = str(covenant_timestamp) -// strings[8] = str(send_to_agent_only) -// strings[9] = str(abuse_email_addr) -bool LLDispatchEstateUpdateInfo::operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return true; - - // NOTE: LLDispatcher extracts strings with an extra \0 at the - // end. If we pass the std::string direct to the UI/renderer - // it draws with a weird character at the end of the string. - std::string estate_name = strings[0].c_str(); // preserve c_str() call! - panel->setEstateName(estate_name); - -#if ELAR_ENABLED - if (strings.size() > 9) - { - std::string abuse_email = strings[9].c_str(); // preserve c_str() call! - panel->setAbuseEmailAddress(abuse_email); - } - else -#endif - { - panel->setAbuseEmailAddress(panel->getString("email_unsupported")); - } - - LLViewerRegion* regionp = gAgent.getRegion(); - - LLUUID owner_id(strings[1]); - regionp->setOwner(owner_id); - // Update estate owner name in UI - const BOOL is_group = FALSE; - gCacheName->get(owner_id, is_group, LLPanelEstateInfo::callbackCacheName); - - U32 estate_id = strtoul(strings[2].c_str(), NULL, 10); - panel->setEstateID(estate_id); - - U32 flags = strtoul(strings[3].c_str(), NULL, 10); - panel->setEstateFlags(flags); - - F32 sun_hour = ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f; - if(sun_hour == 0 && (flags & REGION_FLAGS_SUN_FIXED ? FALSE : TRUE)) - { - panel->setGlobalTime(TRUE); - } - else - { - panel->setGlobalTime(FALSE); - panel->setSunHour(sun_hour); - } - - bool visible_from_mainland = (bool)(flags & REGION_FLAGS_EXTERNALLY_VISIBLE); - bool god = gAgent.isGodlike(); - bool linden_estate = (estate_id <= ESTATE_LAST_LINDEN); - - // If visible from mainland, disable the access allowed - // UI, as anyone can teleport there. - // However, gods need to be able to edit the access list for - // linden estates, regardless of visibility, to allow object - // and L$ transfers. - bool enable_agent = (!visible_from_mainland || (god && linden_estate)); - bool enable_group = enable_agent; - bool enable_ban = !linden_estate; - panel->setAccessAllowedEnabled(enable_agent, enable_group, enable_ban); - - return true; -} - - -// key = "setaccess" -// strings[0] = str(estate_id) -// strings[1] = str(packed_access_lists) -// strings[2] = str(num allowed agent ids) -// strings[3] = str(num allowed group ids) -// strings[4] = str(num banned agent ids) -// strings[5] = str(num estate manager agent ids) -// strings[6] = bin(uuid) -// strings[7] = bin(uuid) -// strings[8] = bin(uuid) -// ... -bool LLDispatchSetEstateAccess::operator()( - const LLDispatcher* dispatcher, - const std::string& key, - const LLUUID& invoice, - const sparam_t& strings) -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return true; - - S32 index = 1; // skip estate_id - U32 access_flags = strtoul(strings[index++].c_str(), NULL,10); - S32 num_allowed_agents = strtol(strings[index++].c_str(), NULL, 10); - S32 num_allowed_groups = strtol(strings[index++].c_str(), NULL, 10); - S32 num_banned_agents = strtol(strings[index++].c_str(), NULL, 10); - S32 num_estate_managers = strtol(strings[index++].c_str(), NULL, 10); - - // sanity ckecks - if (num_allowed_agents > 0 - && !(access_flags & ESTATE_ACCESS_ALLOWED_AGENTS)) - { - llwarns << "non-zero count for allowed agents, but no corresponding flag" << llendl; - } - if (num_allowed_groups > 0 - && !(access_flags & ESTATE_ACCESS_ALLOWED_GROUPS)) - { - llwarns << "non-zero count for allowed groups, but no corresponding flag" << llendl; - } - if (num_banned_agents > 0 - && !(access_flags & ESTATE_ACCESS_BANNED_AGENTS)) - { - llwarns << "non-zero count for banned agents, but no corresponding flag" << llendl; - } - if (num_estate_managers > 0 - && !(access_flags & ESTATE_ACCESS_MANAGERS)) - { - llwarns << "non-zero count for managers, but no corresponding flag" << llendl; - } - - // grab the UUID's out of the string fields - if (access_flags & ESTATE_ACCESS_ALLOWED_AGENTS) - { - LLNameListCtrl* allowed_agent_name_list; - allowed_agent_name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list"); - - int totalAllowedAgents = num_allowed_agents; - - if (allowed_agent_name_list) - { - totalAllowedAgents += allowed_agent_name_list->getItemCount(); - } - - std::string msg = llformat("Allowed residents: (%d, max %d)", - totalAllowedAgents, - ESTATE_MAX_ACCESS_IDS); - panel->childSetValue("allow_resident_label", LLSD(msg)); - - if (allowed_agent_name_list) - { - //allowed_agent_name_list->deleteAllItems(); - for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - allowed_agent_name_list->addNameItem(id); - } - panel->childSetEnabled("remove_allowed_avatar_btn", allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_agent_name_list->sortByColumnIndex(0, TRUE); - } - } - - if (access_flags & ESTATE_ACCESS_ALLOWED_GROUPS) - { - LLNameListCtrl* allowed_group_name_list; - allowed_group_name_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list"); - - std::string msg = llformat("Allowed groups: (%d, max %d)", - num_allowed_groups, - (S32) ESTATE_MAX_GROUP_IDS); - panel->childSetValue("allow_group_label", LLSD(msg)); - - if (allowed_group_name_list) - { - allowed_group_name_list->deleteAllItems(); - for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - allowed_group_name_list->addGroupNameItem(id); - } - panel->childSetEnabled("remove_allowed_group_btn", allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_group_name_list->sortByColumnIndex(0, TRUE); - } - } - - if (access_flags & ESTATE_ACCESS_BANNED_AGENTS) - { - LLNameListCtrl* banned_agent_name_list; - banned_agent_name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list"); - - int totalBannedAgents = num_banned_agents; - - if (banned_agent_name_list) - { - totalBannedAgents += banned_agent_name_list->getItemCount(); - } - - - std::string msg = llformat("Banned residents: (%d, max %d)", - totalBannedAgents, - ESTATE_MAX_ACCESS_IDS); - panel->childSetValue("ban_resident_label", LLSD(msg)); - - if (banned_agent_name_list) - { - //banned_agent_name_list->deleteAllItems(); - for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - banned_agent_name_list->addNameItem(id); - } - panel->childSetEnabled("remove_banned_avatar_btn", banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); - banned_agent_name_list->sortByColumnIndex(0, TRUE); - } - } - - if (access_flags & ESTATE_ACCESS_MANAGERS) - { - std::string msg = llformat("Estate Managers: (%d, max %d)", - num_estate_managers, - ESTATE_MAX_MANAGERS); - panel->childSetValue("estate_manager_label", LLSD(msg)); - - LLNameListCtrl* estate_manager_name_list = - panel->getChild<LLNameListCtrl>("estate_manager_name_list"); - if (estate_manager_name_list) - { - estate_manager_name_list->deleteAllItems(); // Clear existing entries - - // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't - // truncate the list unless it's really big. Go ahead and show the extras so the user doesn't get confused, - // and they can still remove them. - for (S32 i = 0; i < num_estate_managers && i < (ESTATE_MAX_MANAGERS * 4); i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - estate_manager_name_list->addNameItem(id); - } - panel->childSetEnabled("remove_estate_manager_btn", estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); - estate_manager_name_list->sortByColumnIndex(0, TRUE); - } - } - - return true; -} - -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) -void LLFloaterRegionInfo::open() -{ - // We'll allow access to the estate tools for estate managers (and for the sim owner) - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) - { - LLViewerRegion* pRegion = gAgent.getRegion(); - if (!pRegion) - return; - - // Should be able to call LLRegion::canManageEstate() but then we can fake god like - if ( (!pRegion->isEstateManager()) && (pRegion->getOwner() != gAgent.getID()) ) - return; - } - - LLFloater::open(); -} -// [/RLVa:KB] +/** + * @file llfloaterregioninfo.cpp + * @author Aaron Brashears + * @brief Implementation of the region info and controls floater and panels. + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloaterregioninfo.h" + +#include <algorithm> +#include <functional> + +#include "llcachename.h" +#include "lldir.h" +#include "lldispatcher.h" +#include "llglheaders.h" +#include "llregionflags.h" +#include "llstl.h" +#include "indra_constants.h" +#include "message.h" + +#include "llagent.h" +#include "llalertdialog.h" +#include "llappviewer.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfilepicker.h" +#include "llfloaterdaycycle.h" +#include "llfloatergodtools.h" // for send_sim_wide_deletes() +#include "llfloatertopobjects.h" // added to fix SL-32336 +#include "llfloatergroups.h" +#include "llfloatertelehub.h" +#include "llfloaterwindlight.h" +#include "llinventorymodel.h" +#include "lllineeditor.h" +#include "llalertdialog.h" +#include "llnamelistctrl.h" +#include "llsliderctrl.h" +#include "llspinctrl.h" +#include "lltabcontainer.h" +#include "lltextbox.h" +#include "llinventory.h" +#include "lltexturectrl.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "lluictrlfactory.h" +#include "llviewerimage.h" +#include "llviewerimagelist.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llviewertexteditor.h" +#include "llviewerwindow.h" +#include "llvlcomposition.h" +#include "hippoLimits.h" + +// [RLVa:KB] +#include "rlvhandler.h" +// [/RLVa:KB] + +#define ELAR_ENABLED 0 // Enable when server support is implemented + +const S32 TERRAIN_TEXTURE_COUNT = 4; +const S32 CORNER_COUNT = 4; + +///---------------------------------------------------------------------------- +/// Local class declaration +///---------------------------------------------------------------------------- + +class LLDispatchEstateUpdateInfo : public LLDispatchHandler +{ +public: + LLDispatchEstateUpdateInfo() {} + virtual ~LLDispatchEstateUpdateInfo() {} + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); +}; + +class LLDispatchSetEstateAccess : public LLDispatchHandler +{ +public: + LLDispatchSetEstateAccess() {} + virtual ~LLDispatchSetEstateAccess() {} + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings); +}; + + +/* +void unpack_request_params( + LLMessageSystem* msg, + LLDispatcher::sparam_t& strings, + LLDispatcher::iparam_t& integers) +{ + char str_buf[MAX_STRING]; + S32 str_count = msg->getNumberOfBlocksFast(_PREHASH_StringData); + S32 i; + for (i = 0; i < str_count; ++i) + { + // we treat the SParam as binary data (since it might be an + // LLUUID in compressed form which may have embedded \0's,) + str_buf[0] = '\0'; + S32 data_size = msg->getSizeFast(_PREHASH_StringData, i, _PREHASH_SParam); + if (data_size >= 0) + { + msg->getBinaryDataFast(_PREHASH_StringData, _PREHASH_SParam, + str_buf, data_size, i, MAX_STRING - 1); + strings.push_back(std::string(str_buf, data_size)); + } + } + + U32 int_buf; + S32 int_count = msg->getNumberOfBlocksFast(_PREHASH_IntegerData); + for (i = 0; i < int_count; ++i) + { + msg->getU32("IntegerData", "IParam", int_buf, i); + integers.push_back(int_buf); + } +} +*/ + + + +bool estate_dispatch_initialized = false; + + +///---------------------------------------------------------------------------- +/// LLFloaterRegionInfo +///---------------------------------------------------------------------------- + +//S32 LLFloaterRegionInfo::sRequestSerial = 0; +LLUUID LLFloaterRegionInfo::sRequestInvoice; + +LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", NULL, FALSE); +} + +BOOL LLFloaterRegionInfo::postBuild() +{ + mTab = getChild<LLTabContainer>("region_panels"); + + // contruct the panels + LLPanelRegionInfo* panel; + + panel = new LLPanelRegionGeneralInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_general.xml"); + mTab->addTabPanel(panel, panel->getLabel(), TRUE); + + panel = new LLPanelRegionOpenSettingsInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_open_region_settings.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelRegionDebugInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_debug.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelRegionTextureInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_texture.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelRegionTerrainInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_terrain.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelEstateInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_estate.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + panel = new LLPanelEstateCovenant; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_covenant.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + + gMessageSystem->setHandlerFunc( + "EstateOwnerMessage", + &processEstateOwnerRequest); + + return TRUE; +} + +LLFloaterRegionInfo::~LLFloaterRegionInfo() +{ +} + +void LLFloaterRegionInfo::onOpen() +{ + LLRect rect = gSavedSettings.getRect("FloaterRegionInfo"); + S32 left, top; + gFloaterView->getNewFloaterPosition(&left, &top); + rect.translate(left,top); + + refreshFromRegion(gAgent.getRegion()); + requestRegionInfo(); + LLFloater::onOpen(); +} + +// static +void LLFloaterRegionInfo::requestRegionInfo() +{ + LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); + + tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE); + tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE); + tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE); + tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE); + tab->getChild<LLPanel>("RegionSettings")->setCtrlsEnabled(FALSE); + + // Must allow anyone to request the RegionInfo data + // so non-owners/non-gods can see the values. + // Therefore can't use an EstateOwnerMessage JC + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("RequestRegionInfo"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + gAgent.sendReliableMessage(); +} + +// static +void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) +{ + static LLDispatcher dispatch; + if(!findInstance()) + { + return; + } + + if (!estate_dispatch_initialized) + { + LLPanelEstateInfo::initDispatch(dispatch); + } + + LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); + LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); + + // unpack the message + std::string request; + LLUUID invoice; + LLDispatcher::sparam_t strings; + LLDispatcher::unpackMessage(msg, request, invoice, strings); + if(invoice != getLastInvoice()) + { + llwarns << "Mismatched Estate message: " << request << llendl; + return; + } + + //dispatch the message + dispatch.dispatch(request, invoice, strings); + + LLViewerRegion* region = gAgent.getRegion(); + panel->updateControls(region); +} + + +// static +void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) +{ + LLPanel* panel; + + llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; + if(!findInstance()) + { + return; + } + + LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels"); + + LLViewerRegion* region = gAgent.getRegion(); + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + + // extract message + std::string sim_name; + std::string sim_type = LLTrans::getString("land_type_unknown"); + U32 region_flags; + U8 agent_limit; + F32 object_bonus_factor; + U8 sim_access; + F32 water_height; + F32 terrain_raise_limit; + F32 terrain_lower_limit; + BOOL use_estate_sun; + F32 sun_hour; + msg->getString("RegionInfo", "SimName", sim_name); + msg->getU32("RegionInfo", "RegionFlags", region_flags); + msg->getU8("RegionInfo", "MaxAgents", agent_limit); + msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor); + msg->getU8("RegionInfo", "SimAccess", sim_access); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); + msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); + msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun); + // actually the "last set" sun hour, not the current sun hour. JC + msg->getF32("RegionInfo", "SunHour", sun_hour); + // the only reasonable way to decide if we actually have any data is to + // check to see if any of these fields have nonzero sizes + if (msg->getSize("RegionInfo2", "ProductSKU") > 0 || + msg->getSize("RegionInfo2", "ProductName") > 0) + { + msg->getString("RegionInfo2", "ProductName", sim_type); + } + + // GENERAL PANEL + panel = tab->getChild<LLPanel>("General"); + panel->childSetValue("region_text", LLSD(sim_name)); + panel->childSetValue("region_type", LLSD(sim_type)); + panel->childSetValue("version_channel_text", gLastVersionChannel); + + panel->childSetValue("block_terraform_check", (region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); + panel->childSetValue("block_fly_check", (region_flags & REGION_FLAGS_BLOCK_FLY) ? TRUE : FALSE ); + panel->childSetValue("allow_damage_check", (region_flags & REGION_FLAGS_ALLOW_DAMAGE) ? TRUE : FALSE ); + panel->childSetValue("restrict_pushobject", (region_flags & REGION_FLAGS_RESTRICT_PUSHOBJECT) ? TRUE : FALSE ); + panel->childSetValue("allow_land_resell_check", (region_flags & REGION_FLAGS_BLOCK_LAND_RESELL) ? FALSE : TRUE ); + panel->childSetValue("allow_parcel_changes_check", (region_flags & REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? TRUE : FALSE ); + panel->childSetValue("block_parcel_search_check", (region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE ); + panel->childSetValue("agent_limit_spin", LLSD((F32)agent_limit) ); + panel->childSetValue("object_bonus_spin", LLSD(object_bonus_factor) ); + panel->childSetValue("access_combo", LLSD(sim_access) ); + + + // detect teen grid for maturity + + U32 parent_estate_id; + msg->getU32("RegionInfo", "ParentEstateID", parent_estate_id); + BOOL teen_grid = (parent_estate_id == 5); // *TODO add field to estate table and test that + panel->childSetEnabled("access_combo", gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid)); + panel->setCtrlsEnabled(allow_modify); + + // RegionSettings PANEL + panel = tab->getChild<LLPanel>("RegionSettings"); + panel->setCtrlsEnabled(allow_modify); + + // DEBUG PANEL + panel = tab->getChild<LLPanel>("Debug"); + + panel->childSetValue("region_text", LLSD(sim_name) ); + panel->childSetValue("disable_scripts_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) ); + panel->childSetValue("disable_collisions_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) ); + panel->childSetValue("disable_physics_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) ); + panel->setCtrlsEnabled(allow_modify); + + // TERRAIN PANEL + panel = tab->getChild<LLPanel>("Terrain"); + + panel->childSetValue("region_text", LLSD(sim_name)); + panel->childSetValue("water_height_spin", LLSD(water_height)); + panel->childSetValue("terrain_raise_spin", LLSD(terrain_raise_limit)); + panel->childSetValue("terrain_lower_spin", LLSD(terrain_lower_limit)); + panel->childSetValue("use_estate_sun_check", LLSD(use_estate_sun)); + + panel->childSetValue("fixed_sun_check", LLSD((BOOL)(region_flags & REGION_FLAGS_SUN_FIXED))); + panel->childSetEnabled("fixed_sun_check", allow_modify && !use_estate_sun); + panel->childSetValue("sun_hour_slider", LLSD(sun_hour)); + panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); + panel->setCtrlsEnabled(allow_modify); + + getInstance()->refreshFromRegion( gAgent.getRegion() ); +} + +// static +LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() +{ + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); + LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); + return panel; +} + +// static +LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() +{ + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); + LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild<LLPanel>("Covenant"); + return panel; +} + +// static +LLPanelRegionOpenSettingsInfo* LLFloaterRegionInfo::getPanelOpenSettings() +{ + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); + LLPanelRegionOpenSettingsInfo* panel; + panel = (LLPanelRegionOpenSettingsInfo*)tab->getChild<LLPanel>("RegionSettings"); + return panel; +} + +void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) +{ + // call refresh from region on all panels + std::for_each( + mInfoPanels.begin(), + mInfoPanels.end(), + llbind2nd( +#if LL_WINDOWS + std::mem_fun1(&LLPanelRegionInfo::refreshFromRegion), +#else + std::mem_fun(&LLPanelRegionInfo::refreshFromRegion), +#endif + region)); +} + +// public +void LLFloaterRegionInfo::refresh() +{ + for(info_panels_t::iterator iter = mInfoPanels.begin(); + iter != mInfoPanels.end(); ++iter) + { + (*iter)->refresh(); + } +} + + +///---------------------------------------------------------------------------- +/// Local class implementation +///---------------------------------------------------------------------------- + +// +// LLPanelRegionInfo +// + +// static +void LLPanelRegionInfo::onBtnSet(void* user_data) +{ + LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; + if(!panel) return; + if (panel->sendUpdate()) + { + panel->disableButton("apply_btn"); + } +} + +//static +void LLPanelRegionInfo::onChangeChildCtrl(LLUICtrl* ctrl, void* user_data) +{ + if (ctrl) + { + LLPanelRegionInfo* panel = (LLPanelRegionInfo*) ctrl->getParent(); + panel->updateChild(ctrl); + } +} + +// static +// Enables the "set" button if it is not already enabled +void LLPanelRegionInfo::onChangeAnything(LLUICtrl* ctrl, void* user_data) +{ + LLPanelRegionInfo* panel = (LLPanelRegionInfo*)user_data; + if(panel) + { + panel->enableButton("apply_btn"); + panel->refresh(); + } +} + +// static +// Enables set button on change to line editor +void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data) +{ + // reuse the previous method + onChangeAnything(0, user_data); +} + + +// virtual +BOOL LLPanelRegionInfo::postBuild() +{ + childSetAction("apply_btn", onBtnSet, this); + childDisable("apply_btn"); + refresh(); + return TRUE; +} + +// virtual +void LLPanelRegionInfo::updateChild(LLUICtrl* child_ctr) +{ +} + +// virtual +bool LLPanelRegionInfo::refreshFromRegion(LLViewerRegion* region) +{ + if (region) mHost = region->getHost(); + return true; +} + +void LLPanelRegionInfo::sendEstateOwnerMessage( + LLMessageSystem* msg, + const std::string& request, + const LLUUID& invoice, + const strings_t& strings) +{ + llinfos << "Sending estate request '" << request << "'" << llendl; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", request); + msg->addUUID("Invoice", invoice); + if(strings.empty()) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", NULL); + } + else + { + strings_t::const_iterator it = strings.begin(); + strings_t::const_iterator end = strings.end(); + for(; it != end; ++it) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", *it); + } + } + msg->sendReliable(mHost); +} + +void LLPanelRegionInfo::enableButton(const std::string& btn_name, BOOL enable) +{ + childSetEnabled(btn_name, enable); +} + +void LLPanelRegionInfo::disableButton(const std::string& btn_name) +{ + childDisable(btn_name); +} + +void LLPanelRegionInfo::initCtrl(const std::string& name) +{ + childSetCommitCallback(name, onChangeAnything, this); +} + +void LLPanelRegionInfo::initHelpBtn(const std::string& name, const std::string& xml_alert) +{ + childSetAction(name, onClickHelp, new std::string(xml_alert)); +} + +// static +void LLPanelRegionInfo::onClickHelp(void* data) +{ + std::string* xml_alert = (std::string*)data; + LLNotifications::instance().add(*xml_alert); +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionGeneralInfo +// +bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region) +{ + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + childDisable("apply_btn"); + childSetEnabled("access_text", allow_modify); + // childSetEnabled("access_combo", allow_modify); + // now set in processRegionInfo for teen grid detection + childSetEnabled("kick_btn", allow_modify); + childSetEnabled("kick_all_btn", allow_modify); + childSetEnabled("im_btn", allow_modify); + childSetEnabled("manage_telehub_btn", allow_modify); + + // Data gets filled in by processRegionInfo + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +BOOL LLPanelRegionGeneralInfo::postBuild() +{ + // Enable the "Apply" button if something is changed. JC + initCtrl("block_terraform_check"); + initCtrl("block_fly_check"); + initCtrl("allow_damage_check"); + initCtrl("allow_land_resell_check"); + initCtrl("allow_parcel_changes_check"); + initCtrl("agent_limit_spin"); + initCtrl("object_bonus_spin"); + initCtrl("access_combo"); + initCtrl("restrict_pushobject"); + initCtrl("block_parcel_search_check"); + initCtrl("minimum_agent_age"); + + initHelpBtn("terraform_help", "HelpRegionBlockTerraform"); + initHelpBtn("fly_help", "HelpRegionBlockFly"); + initHelpBtn("damage_help", "HelpRegionAllowDamage"); + initHelpBtn("agent_limit_help", "HelpRegionAgentLimit"); + initHelpBtn("object_bonus_help", "HelpRegionObjectBonus"); + initHelpBtn("access_help", "HelpRegionMaturity"); + initHelpBtn("restrict_pushobject_help", "HelpRegionRestrictPushObject"); + initHelpBtn("land_resell_help", "HelpRegionLandResell"); + initHelpBtn("parcel_changes_help", "HelpParcelChanges"); + initHelpBtn("parcel_search_help", "HelpRegionSearch"); + + childSetAction("kick_btn", onClickKick, this); + childSetAction("kick_all_btn", onClickKickAll, this); + childSetAction("im_btn", onClickMessage, this); + childSetAction("manage_telehub_btn", onClickManageTelehub, this); + + return LLPanelRegionInfo::postBuild(); +} + +// static +void LLPanelRegionGeneralInfo::onClickKick(void* userdata) +{ + llinfos << "LLPanelRegionGeneralInfo::onClickKick" << llendl; + LLPanelRegionGeneralInfo* panelp = (LLPanelRegionGeneralInfo*)userdata; + + // this depends on the grandparent view being a floater + // in order to set up floater dependency + LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); + LLFloater* child_floater = LLFloaterAvatarPicker::show(onKickCommit, userdata, FALSE, TRUE); + parent_floater->addDependentFloater(child_floater); +} + +// static +void LLPanelRegionGeneralInfo::onKickCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata) +{ + if (names.empty() || ids.empty()) return; + if(ids[0].notNull()) + { + LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata; + if(!self) return; + strings_t strings; + // [0] = our agent id + // [1] = target agent id + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); + + ids[0].toString(buffer); + strings.push_back(strings_t::value_type(buffer)); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", invoice, strings); + } +} + +// static +void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata) +{ + llinfos << "LLPanelRegionGeneralInfo::onClickKickAll" << llendl; + LLNotifications::instance().add("KickUsersFromRegion", + LLSD(), + LLSD(), + boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); +} + +bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option == 0) + { + strings_t strings; + // [0] = our agent id + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + // historical message name + sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings); + } + return false; +} + +// static +void LLPanelRegionGeneralInfo::onClickMessage(void* userdata) +{ + llinfos << "LLPanelRegionGeneralInfo::onClickMessage" << llendl; + LLNotifications::instance().add("MessageRegion", + LLSD(), + LLSD(), + boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2)); +} + +// static +bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response) +{ + if(LLNotification::getSelectedOption(notification, response) != 0) return false; + + std::string text = response["message"].asString(); + if (text.empty()) return false; + + llinfos << "Message to everyone: " << text << llendl; + strings_t strings; + // [0] grid_x, unused here + // [1] grid_y, unused here + // [2] agent_id of sender + // [3] sender name + // [4] message + strings.push_back("-1"); + strings.push_back("-1"); + std::string buffer; + gAgent.getID().toString(buffer); + strings.push_back(buffer); + std::string name; + gAgent.buildFullname(name); + strings.push_back(strings_t::value_type(name)); + strings.push_back(strings_t::value_type(text)); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings); + return false; +} + +// static +void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data) +{ + LLFloaterRegionInfo::getInstance()->close(); + + LLFloaterTelehub::show(); +} + +// setregioninfo +// strings[0] = 'Y' - block terraform, 'N' - not +// strings[1] = 'Y' - block fly, 'N' - not +// strings[2] = 'Y' - allow damage, 'N' - not +// strings[3] = 'Y' - allow land sale, 'N' - not +// strings[4] = agent limit +// strings[5] = object bonus +// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult) +// strings[7] = restrict pushobject +// strings[8] = 'Y' - allow parcel subdivide, 'N' - not +// strings[9] = 'Y' - block parcel search, 'N' - allow +BOOL LLPanelRegionGeneralInfo::sendUpdate() +{ + llinfos << "LLPanelRegionGeneralInfo::sendUpdate()" << llendl; + + // First try using a Cap. If that fails use the old method. + LLSD body; + std::string url = gAgent.getRegion()->getCapability("DispatchRegionInfo"); + if (!url.empty()) + { + body["block_terraform"] = childGetValue("block_terraform_check"); + body["block_fly"] = childGetValue("block_fly_check"); + body["allow_damage"] = childGetValue("allow_damage_check"); + body["allow_land_resell"] = childGetValue("allow_land_resell_check"); + body["agent_limit"] = childGetValue("agent_limit_spin"); + body["prim_bonus"] = childGetValue("object_bonus_spin"); + body["sim_access"] = childGetValue("access_combo"); + body["restrict_pushobject"] = childGetValue("restrict_pushobject"); + body["allow_parcel_changes"] = childGetValue("allow_parcel_changes_check"); + body["block_parcel_search"] = childGetValue("block_parcel_search_check"); + body["minimum_agent_age"] = childGetValue("minimum_agent_age"); + + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } + else + { + strings_t strings; + std::string buffer; + + buffer = llformat("%s", (childGetValue("block_terraform_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("block_fly_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("allow_damage_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("allow_land_resell_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + F32 value = (F32)childGetValue("agent_limit_spin").asReal(); + buffer = llformat("%f", value); + strings.push_back(strings_t::value_type(buffer)); + + value = (F32)childGetValue("object_bonus_spin").asReal(); + buffer = llformat("%f", value); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%d", childGetValue("access_combo").asInteger()); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("restrict_pushobject").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + buffer = llformat("%s", (childGetValue("allow_parcel_changes_check").asBoolean() ? "Y" : "N")); + strings.push_back(strings_t::value_type(buffer)); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); + } + + // if we changed access levels, tell user about it + LLViewerRegion* region = gAgent.getRegion(); + if (region && (childGetValue("access_combo").asInteger() != region->getSimAccess()) ) + { + LLNotifications::instance().add("RegionMaturityChange"); + } + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionOpenSettingsInfo +// +bool LLPanelRegionOpenSettingsInfo::refreshFromRegion(LLViewerRegion* region) +{ + // Data gets filled in by hippo manager + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + + childSetValue("draw_distance", gAgent.mDrawDistance); + childSetValue("force_draw_distance", gAgent.mLockedDrawDistance); + childSetValue("allow_minimap", LLSD(gHippoLimits->mAllowMinimap)); + childSetValue("allow_physical_prims", (gHippoLimits->mAllowPhysicalPrims == 1 ? TRUE : FALSE)); + childSetValue("max_drag_distance", LLSD(gHippoLimits->mMaxDragDistance)); + childSetValue("min_hole_size", LLSD(gHippoLimits->mMinHoleSize)); + childSetValue("max_hollow_size", LLSD(gHippoLimits->mMaxHollow)); + childSetValue("max_inventory_items_transfer", LLSD(gHippoLimits->mMaxInventoryItemsTransfer)); + childSetValue("max_link_count", LLSD(gHippoLimits->mMaxLinkedPrims)); + childSetValue("max_link_count_phys", LLSD(gHippoLimits->mMaxPhysLinkedPrims)); + childSetValue("max_phys_prim_scale", LLSD(gHippoLimits->mMaxPrimScale));//Todo:Fix + childSetValue("max_prim_scale", LLSD(gHippoLimits->mMaxPrimScale)); + childSetValue("min_prim_scale", LLSD(gHippoLimits->mMinPrimScale)); + childSetValue("render_water", LLSD(gHippoLimits->mRenderWater)); + childSetValue("show_tags", LLSD(gHippoLimits->mRenderName)); + childSetValue("max_groups", LLSD(gHippoLimits->mMaxAgentGroups)); + childSetValue("allow_parcel_windlight", LLSD(gHippoLimits->mAllowParcelWindLight)); + childSetValue("enable_teen_mode", LLSD(gHippoLimits->mEnableTeenMode)); + childSetValue("enforce_max_build", LLSD(gHippoLimits->mEnforceMaxBuild)); + + setCtrlsEnabled(allow_modify); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +BOOL LLPanelRegionOpenSettingsInfo::postBuild() +{ + // Enable the "Apply" button if something is changed. JC + initCtrl("draw_distance"); + initCtrl("force_draw_distance"); + initCtrl("max_drag_distance"); + initCtrl("max_prim_scale"); + initCtrl("min_prim_scale"); + initCtrl("max_phys_prim_scale"); + initCtrl("max_hollow_size"); + initCtrl("min_hole_size"); + initCtrl("max_link_count"); + initCtrl("max_link_count_phys"); + initCtrl("max_inventory_items_transfer"); + initCtrl("max_groups"); + initCtrl("render_water"); + initCtrl("allow_minimap"); + initCtrl("allow_physical_prims"); + initCtrl("enable_teen_mode"); + initCtrl("show_tags"); + initCtrl("allow_parcel_windlight"); + + initHelpBtn("force_draw_distance_help", "HelpForceDrawDistance"); + initHelpBtn("max_inventory_items_transfer_help", "HelpMaxInventoryItemsTransfer"); + initHelpBtn("max_groups_help", "HelpMaxGroups"); + initHelpBtn("render_water_help", "HelpRenderWater"); + initHelpBtn("allow_minimap_help", "HelpAllowMinimap"); + initHelpBtn("allow_physical_prims_help", "HelpAllowPhysicalPrims"); + initHelpBtn("enable_teen_mode_help", "HelpEnableTeenMode"); + initHelpBtn("show_tags_help", "HelpShowTags"); + initHelpBtn("allow_parcel_windlight_help", "HelpAllowParcelWindLight"); + + childSetAction("apply_ors_btn", sendUpdate, this); + + refreshFromRegion(gAgent.getRegion()); + + return LLPanelRegionInfo::postBuild(); +} + +// setregioninfo +// strings[0] = 'Y' - block terraform, 'N' - not +// strings[1] = 'Y' - block fly, 'N' - not +// strings[2] = 'Y' - allow damage, 'N' - not +// strings[3] = 'Y' - allow land sale, 'N' - not +// strings[4] = agent limit +// strings[5] = object bonus +// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult) +// strings[7] = restrict pushobject +// strings[8] = 'Y' - allow parcel subdivide, 'N' - not +// strings[9] = 'Y' - block parcel search, 'N' - allow +void LLPanelRegionOpenSettingsInfo::sendUpdate(void* userdata) +{ + LLPanelRegionOpenSettingsInfo* self; + self = (LLPanelRegionOpenSettingsInfo*)userdata; + + llinfos << "LLPanelRegionOpenSettingsInfo::sendUpdate()" << llendl; + + LLSD body; + std::string url = gAgent.getRegion()->getCapability("DispatchOpenRegionSettings"); + if (!url.empty()) + { + body["draw_distance"] = self->childGetValue("draw_distance"); + body["force_draw_distance"] = self->childGetValue("force_draw_distance"); + body["allow_minimap"] = self->childGetValue("allow_minimap"); + body["allow_physical_prims"] = self->childGetValue("allow_physical_prims"); + body["max_drag_distance"] = self->childGetValue("max_drag_distance"); + body["min_hole_size"] = self->childGetValue("min_hole_size"); + body["max_hollow_size"] = self->childGetValue("max_hollow_size"); + body["max_inventory_items_transfer"] = self->childGetValue("max_inventory_items_transfer"); + body["max_link_count"] = self->childGetValue("max_link_count"); + body["max_link_count_phys"] = self->childGetValue("max_link_count_phys"); + body["max_phys_prim_scale"] = self->childGetValue("max_phys_prim_scale"); + body["max_prim_scale"] = self->childGetValue("max_prim_scale"); + body["min_prim_scale"] = self->childGetValue("min_prim_scale"); + body["render_water"] = self->childGetValue("render_water"); + body["show_tags"] = self->childGetValue("show_tags"); + body["max_groups"] = self->childGetValue("max_groups"); + body["allow_parcel_windlight"] = self->childGetValue("allow_parcel_windlight"); + body["enable_teen_mode"] = self->childGetValue("enable_teen_mode"); + body["enforce_max_build"] = self->childGetValue("enforce_max_build"); + + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionDebugInfo +///////////////////////////////////////////////////////////////////////////// +BOOL LLPanelRegionDebugInfo::postBuild() +{ + LLPanelRegionInfo::postBuild(); + initCtrl("disable_scripts_check"); + initCtrl("disable_collisions_check"); + initCtrl("disable_physics_check"); + + initHelpBtn("disable_scripts_help", "HelpRegionDisableScripts"); + initHelpBtn("disable_collisions_help", "HelpRegionDisableCollisions"); + initHelpBtn("disable_physics_help", "HelpRegionDisablePhysics"); + initHelpBtn("top_colliders_help", "HelpRegionTopColliders"); + initHelpBtn("top_scripts_help", "HelpRegionTopScripts"); + initHelpBtn("restart_help", "HelpRegionRestart"); + initHelpBtn("minimum_agent_age_help", "HelpRegionMinimumAge"); + + + childSetAction("choose_avatar_btn", onClickChooseAvatar, this); + childSetAction("return_btn", onClickReturn, this); + childSetAction("top_colliders_btn", onClickTopColliders, this); + childSetAction("top_scripts_btn", onClickTopScripts, this); + childSetAction("restart_btn", onClickRestart, this); + childSetAction("cancel_restart_btn", onClickCancelRestart, this); + + return TRUE; +} + +// virtual +bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region) +{ + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + childDisable("apply_btn"); + childDisable("target_avatar_name"); + + childSetEnabled("choose_avatar_btn", allow_modify); + childSetEnabled("return_scripts", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("return_other_land", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("return_estate_wide", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("return_btn", allow_modify && !mTargetAvatar.isNull()); + childSetEnabled("top_colliders_btn", allow_modify); + childSetEnabled("top_scripts_btn", allow_modify); + childSetEnabled("restart_btn", allow_modify); + childSetEnabled("cancel_restart_btn", allow_modify); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +// virtual +BOOL LLPanelRegionDebugInfo::sendUpdate() +{ + llinfos << "LLPanelRegionDebugInfo::sendUpdate" << llendl; + strings_t strings; + std::string buffer; + + buffer = llformat("%s", (childGetValue("disable_scripts_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + + buffer = llformat("%s", (childGetValue("disable_collisions_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + + buffer = llformat("%s", (childGetValue("disable_physics_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "setregiondebug", invoice, strings); + return TRUE; +} + +void LLPanelRegionDebugInfo::onClickChooseAvatar(void* data) +{ + LLFloaterAvatarPicker::show(callbackAvatarID, data, FALSE, TRUE); +} + +// static +void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) data; + if (ids.empty() || names.empty()) return; + self->mTargetAvatar = ids[0]; + self->childSetValue("target_avatar_name", LLSD(names[0])); + self->refreshFromRegion( gAgent.getRegion() ); +} + +// static +void LLPanelRegionDebugInfo::onClickReturn(void* data) +{ + LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data; + if (panelp->mTargetAvatar.isNull()) return; + + LLSD args; + args["USER_NAME"] = panelp->childGetValue("target_avatar_name").asString(); + LLSD payload; + payload["avatar_id"] = panelp->mTargetAvatar; + + U32 flags = SWD_ALWAYS_RETURN_OBJECTS; + + if (panelp->childGetValue("return_scripts").asBoolean()) + { + flags |= SWD_SCRIPTED_ONLY; + } + + if (panelp->childGetValue("return_other_land").asBoolean()) + { + flags |= SWD_OTHERS_LAND_ONLY; + } + payload["flags"] = int(flags); + payload["return_estate_wide"] = panelp->childGetValue("return_estate_wide").asBoolean(); + LLNotifications::instance().add("EstateObjectReturn", args, payload, + boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2)); +} + +bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID(); + if (!target_avatar.isNull()) + { + U32 flags = notification["payload"]["flags"].asInteger(); + bool return_estate_wide = notification["payload"]["return_estate_wide"]; + if (return_estate_wide) + { + // send as estate message - routed by spaceserver to all regions in estate + strings_t strings; + strings.push_back(llformat("%d", flags)); + strings.push_back(target_avatar.asString()); + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings); + } + else + { + // send to this simulator only + send_sim_wide_deletes(target_avatar, flags); + } + } + return false; +} + + +// static +void LLPanelRegionDebugInfo::onClickTopColliders(void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("1"); // one physics step + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + LLFloaterTopObjects::show(); + LLFloaterTopObjects::clearList(); + self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings); +} + +// static +void LLPanelRegionDebugInfo::onClickTopScripts(void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("6"); // top 5 scripts + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + LLFloaterTopObjects::show(); + LLFloaterTopObjects::clearList(); + self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings); +} + +// static +void LLPanelRegionDebugInfo::onClickRestart(void* data) +{ + LLNotifications::instance().add("ConfirmRestart", LLSD(), LLSD(), + boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2)); +} + +bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + strings_t strings; + strings.push_back("120"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); + return false; +} + +// static +void LLPanelRegionDebugInfo::onClickCancelRestart(void* data) +{ + LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data; + strings_t strings; + strings.push_back("-1"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings); +} + + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionTextureInfo +// +LLPanelRegionTextureInfo::LLPanelRegionTextureInfo() : LLPanelRegionInfo() +{ + // nothing. +} + +bool LLPanelRegionTextureInfo::refreshFromRegion(LLViewerRegion* region) +{ + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + setCtrlsEnabled(allow_modify); + childDisable("apply_btn"); + + if (region) + { + childSetValue("region_text", LLSD(region->getName())); + } + else + { + childSetValue("region_text", LLSD("")); + } + + if (!region) return LLPanelRegionInfo::refreshFromRegion(region); + + LLVLComposition* compp = region->getComposition(); + LLTextureCtrl* texture_ctrl; + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + texture_ctrl = getChild<LLTextureCtrl>(buffer); + if(texture_ctrl) + { + lldebugs << "Detail Texture " << i << ": " + << compp->getDetailTextureID(i) << llendl; + LLUUID tmp_id(compp->getDetailTextureID(i)); + texture_ctrl->setImageAssetID(tmp_id); + } + } + + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + childSetValue(buffer, LLSD(compp->getStartHeight(i))); + buffer = llformat("height_range_spin_%d", i); + childSetValue(buffer, LLSD(compp->getHeightRange(i))); + } + + // Call the parent for common book-keeping + return LLPanelRegionInfo::refreshFromRegion(region); +} + + +BOOL LLPanelRegionTextureInfo::postBuild() +{ + LLPanelRegionInfo::postBuild(); + std::string buffer; + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + initCtrl(buffer); + } + + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + initCtrl(buffer); + buffer = llformat("height_range_spin_%d", i); + initCtrl(buffer); + } + +// LLButton* btn = new LLButton("dump", LLRect(0, 20, 100, 0), "", onClickDump, this); +// btn->setFollows(FOLLOWS_TOP|FOLLOWS_LEFT); +// addChild(btn); + + return LLPanelRegionInfo::postBuild(); +} + +BOOL LLPanelRegionTextureInfo::sendUpdate() +{ + llinfos << "LLPanelRegionTextureInfo::sendUpdate()" << llendl; + + // Make sure user hasn't chosen wacky textures. + if (!validateTextureSizes()) + { + return FALSE; + } + + LLTextureCtrl* texture_ctrl; + std::string buffer; + std::string id_str; + LLMessageSystem* msg = gMessageSystem; + strings_t strings; + + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + buffer = llformat("texture_detail_%d", i); + texture_ctrl = getChild<LLTextureCtrl>(buffer); + if(texture_ctrl) + { + LLUUID tmp_id(texture_ctrl->getImageAssetID()); + tmp_id.toString(id_str); + buffer = llformat("%d %s", i, id_str.c_str()); + strings.push_back(buffer); + } + } + sendEstateOwnerMessage(msg, "texturedetail", invoice, strings); + strings.clear(); + for(S32 i = 0; i < CORNER_COUNT; ++i) + { + buffer = llformat("height_start_spin_%d", i); + std::string buffer2 = llformat("height_range_spin_%d", i); + std::string buffer3 = llformat("%d %f %f", i, (F32)childGetValue(buffer).asReal(), (F32)childGetValue(buffer2).asReal()); + strings.push_back(buffer3); + } + sendEstateOwnerMessage(msg, "textureheights", invoice, strings); + strings.clear(); + sendEstateOwnerMessage(msg, "texturecommit", invoice, strings); + return TRUE; +} + +BOOL LLPanelRegionTextureInfo::validateTextureSizes() +{ + for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) + { + std::string buffer; + buffer = llformat("texture_detail_%d", i); + LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(buffer); + if (!texture_ctrl) continue; + + LLUUID image_asset_id = texture_ctrl->getImageAssetID(); + LLViewerImage* img = gImageList.getImage(image_asset_id); + S32 components = img->getComponents(); + // Must ask for highest resolution version's width. JC + S32 width = img->getWidth(0); + S32 height = img->getHeight(0); + + //llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl; + + if (components != 3) + { + LLSD args; + args["TEXTURE_NUM"] = i+1; + args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); + LLNotifications::instance().add("InvalidTerrainBitDepth", args); + return FALSE; + } + + if (width > 512 || height > 512) + { + + LLSD args; + args["TEXTURE_NUM"] = i+1; + args["TEXTURE_SIZE_X"] = width; + args["TEXTURE_SIZE_Y"] = height; + LLNotifications::instance().add("InvalidTerrainSize", args); + return FALSE; + + } + } + + return TRUE; +} + + +// static +void LLPanelRegionTextureInfo::onClickDump(void* data) +{ + llinfos << "LLPanelRegionTextureInfo::onClickDump()" << llendl; +} + + +///////////////////////////////////////////////////////////////////////////// +// LLPanelRegionTerrainInfo +///////////////////////////////////////////////////////////////////////////// +BOOL LLPanelRegionTerrainInfo::postBuild() +{ + LLPanelRegionInfo::postBuild(); + + initHelpBtn("water_height_help", "HelpRegionWaterHeight"); + initHelpBtn("terrain_raise_help", "HelpRegionTerrainRaise"); + initHelpBtn("terrain_lower_help", "HelpRegionTerrainLower"); + initHelpBtn("upload_raw_help", "HelpRegionUploadRaw"); + initHelpBtn("download_raw_help", "HelpRegionDownloadRaw"); + initHelpBtn("use_estate_sun_help", "HelpRegionUseEstateSun"); + initHelpBtn("fixed_sun_help", "HelpRegionFixedSun"); + initHelpBtn("bake_terrain_help", "HelpRegionBakeTerrain"); + + initCtrl("water_height_spin"); + initCtrl("terrain_raise_spin"); + initCtrl("terrain_lower_spin"); + + initCtrl("fixed_sun_check"); + childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); + childSetCommitCallback("use_estate_sun_check", onChangeUseEstateTime, this); + childSetCommitCallback("sun_hour_slider", onChangeSunHour, this); + + childSetAction("download_raw_btn", onClickDownloadRaw, this); + childSetAction("upload_raw_btn", onClickUploadRaw, this); + childSetAction("bake_terrain_btn", onClickBakeTerrain, this); + + return TRUE; +} + +// virtual +bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region) +{ + llinfos << "LLPanelRegionTerrainInfo::refreshFromRegion" << llendl; + + BOOL owner_or_god = gAgent.isGodlike() + || (region && (region->getOwner() == gAgent.getID())); + BOOL owner_or_god_or_manager = owner_or_god + || (region && region->isEstateManager()); + setCtrlsEnabled(owner_or_god_or_manager); + childDisable("apply_btn"); + + childSetEnabled("download_raw_btn", owner_or_god); + childSetEnabled("upload_raw_btn", owner_or_god); + childSetEnabled("bake_terrain_btn", owner_or_god); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +// virtual +BOOL LLPanelRegionTerrainInfo::sendUpdate() +{ + llinfos << "LLPanelRegionTerrainInfo::sendUpdate" << llendl; + std::string buffer; + strings_t strings; + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + + buffer = llformat("%f", (F32)childGetValue("water_height_spin").asReal()); + strings.push_back(buffer); + buffer = llformat("%f", (F32)childGetValue("terrain_raise_spin").asReal()); + strings.push_back(buffer); + buffer = llformat("%f", (F32)childGetValue("terrain_lower_spin").asReal()); + strings.push_back(buffer); + buffer = llformat("%s", (childGetValue("use_estate_sun_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + buffer = llformat("%s", (childGetValue("fixed_sun_check").asBoolean() ? "Y" : "N")); + strings.push_back(buffer); + buffer = llformat("%f", (F32)childGetValue("sun_hour_slider").asReal() ); + strings.push_back(buffer); + + // Grab estate information in case the user decided to set the + // region back to estate time. JC + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return true; + + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); + if (!tab) return true; + + LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate"); + if (!panel) return true; + + BOOL estate_global_time = panel->getGlobalTime(); + BOOL estate_fixed_sun = panel->getFixedSun(); + F32 estate_sun_hour; + if (estate_global_time) + { + estate_sun_hour = 0.f; + } + else + { + estate_sun_hour = panel->getSunHour(); + } + + buffer = llformat("%s", (estate_global_time ? "Y" : "N") ); + strings.push_back(buffer); + buffer = llformat("%s", (estate_fixed_sun ? "Y" : "N") ); + strings.push_back(buffer); + buffer = llformat("%f", estate_sun_hour); + strings.push_back(buffer); + + sendEstateOwnerMessage(gMessageSystem, "setregionterrain", invoice, strings); + return TRUE; +} + +// static +void LLPanelRegionTerrainInfo::onChangeUseEstateTime(LLUICtrl* ctrl, void* user_data) +{ + LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; + if (!panel) return; + BOOL use_estate_sun = panel->childGetValue("use_estate_sun_check").asBoolean(); + panel->childSetEnabled("fixed_sun_check", !use_estate_sun); + panel->childSetEnabled("sun_hour_slider", !use_estate_sun); + if (use_estate_sun) + { + panel->childSetValue("fixed_sun_check", LLSD(FALSE)); + panel->childSetValue("sun_hour_slider", LLSD(0.f)); + } + panel->childEnable("apply_btn"); +} + +// static +void LLPanelRegionTerrainInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) +{ + LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) user_data; + if (!panel) return; + // Just enable the apply button. We let the sun-hour slider be enabled + // for both fixed-sun and non-fixed-sun. JC + panel->childEnable("apply_btn"); +} + +// static +void LLPanelRegionTerrainInfo::onChangeSunHour(LLUICtrl* ctrl, void*) +{ + // can't use userdata to get panel, slider uses it internally + LLPanelRegionTerrainInfo* panel = (LLPanelRegionTerrainInfo*) ctrl->getParent(); + if (!panel) return; + panel->childEnable("apply_btn"); +} + +// static +void LLPanelRegionTerrainInfo::onClickDownloadRaw(void* data) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getSaveFile(LLFilePicker::FFSAVE_RAW, "terrain.raw")) + { + llwarns << "No file" << llendl; + return; + } + std::string filepath = picker.getFirstFile(); + gXferManager->expectFileForRequest(filepath); + + LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; + strings_t strings; + strings.push_back("download filename"); + strings.push_back(filepath); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); +} + +// static +void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(LLFilePicker::FFLOAD_RAW)) + { + llwarns << "No file" << llendl; + return; + } + std::string filepath = picker.getFirstFile(); + gXferManager->expectFileForTransfer(filepath); + + LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data; + strings_t strings; + strings.push_back("upload filename"); + strings.push_back(filepath); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + + LLNotifications::instance().add("RawUploadStarted"); +} + +// static +void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data) +{ + LLNotifications::instance().add( + LLNotification::Params("ConfirmBakeTerrain") + .functor(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2))); +} + +bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + strings_t strings; + strings.push_back("bake"); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings); + return false; +} + +///////////////////////////////////////////////////////////////////////////// +// LLPanelEstateInfo +// + +LLPanelEstateInfo::LLPanelEstateInfo() +: LLPanelRegionInfo(), + mEstateID(0) // invalid +{ +} + +// static +void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) +{ + std::string name; + +// name.assign("setowner"); +// static LLDispatchSetEstateOwner set_owner; +// dispatch.addHandler(name, &set_owner); + + name.assign("estateupdateinfo"); + static LLDispatchEstateUpdateInfo estate_update_info; + dispatch.addHandler(name, &estate_update_info); + + name.assign("setaccess"); + static LLDispatchSetEstateAccess set_access; + dispatch.addHandler(name, &set_access); + + estate_dispatch_initialized = true; +} + +// static +// Disables the sun-hour slider and the use fixed time check if the use global time is check +void LLPanelEstateInfo::onChangeUseGlobalTime(LLUICtrl* ctrl, void* user_data) +{ + LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; + if (panel) + { + bool enabled = !panel->childGetValue("use_global_time_check").asBoolean(); + panel->childSetEnabled("sun_hour_slider", enabled); + panel->childSetEnabled("fixed_sun_check", enabled); + panel->childSetValue("fixed_sun_check", LLSD(FALSE)); + panel->enableButton("apply_btn"); + } +} + +// Enables the sun-hour slider if the fixed-sun checkbox is set +void LLPanelEstateInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) +{ + LLPanelEstateInfo* panel = (LLPanelEstateInfo*) user_data; + if (panel) + { + bool enabled = !panel->childGetValue("fixed_sun_check").asBoolean(); + panel->childSetEnabled("use_global_time_check", enabled); + panel->childSetValue("use_global_time_check", LLSD(FALSE)); + panel->enableButton("apply_btn"); + } +} + + + + +//--------------------------------------------------------------------------- +// Add/Remove estate access button callbacks +//--------------------------------------------------------------------------- +void LLPanelEstateInfo::onClickEditSky(void* user_data) +{ + LLFloaterWindLight::show(); +} + +void LLPanelEstateInfo::onClickEditDayCycle(void* user_data) +{ + LLFloaterDayCycle::show(); +} + +// static +void LLPanelEstateInfo::onClickAddAllowedAgent(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("allowed_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + //args + + LLSD args; + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAllowedAgentOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); +} + +// static +void LLPanelEstateInfo::onClickRemoveAllowedAgent(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); +} + +// static +void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("allowed_group_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAllowedGroupsOnRegion", args); + return; + } + + LLNotification::Params params("ChangeLindenAccess"); + params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, self, _1, _2)); + if (isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } +} + +bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) return false; + + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + + LLFloaterGroupPicker* widget; + widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); + if (widget) + { + widget->setSelectCallback(addAllowedGroup2, NULL); + if (parent_floater) + { + LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); + widget->setOrigin(new_rect.mLeft, new_rect.mBottom); + parent_floater->addDependentFloater(widget); + } + } + + return false; +} + +// static +void LLPanelEstateInfo::onClickRemoveAllowedGroup(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); +} + +// static +void LLPanelEstateInfo::onClickAddBannedAgent(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("banned_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxBannedAgentsOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); +} + +// static +void LLPanelEstateInfo::onClickRemoveBannedAgent(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); +} + +// static +void LLPanelEstateInfo::onClickAddEstateManager(void* user_data) +{ + LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data; + LLCtrlListInterface *list = self->childGetListInterface("estate_manager_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_MANAGERS) + { // Tell user they can't add more managers + LLSD args; + args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS); + LLNotifications::instance().add("MaxManagersOnRegion", args); + } + else + { // Go pick managers to add + accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); + } +} + +// static +void LLPanelEstateInfo::onClickRemoveEstateManager(void* user_data) +{ + accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); +} + +//--------------------------------------------------------------------------- +// Kick from estate methods +//--------------------------------------------------------------------------- +struct LLKickFromEstateInfo +{ + LLPanelEstateInfo *mEstatePanelp; + LLUUID mAgentID; +}; + +void LLPanelEstateInfo::onClickKickUser(void *user_data) +{ + LLPanelEstateInfo* panelp = (LLPanelEstateInfo*)user_data; + + // this depends on the grandparent view being a floater + // in order to set up floater dependency + LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); + LLFloater* child_floater = LLFloaterAvatarPicker::show(LLPanelEstateInfo::onKickUserCommit, user_data, FALSE, TRUE); + parent_floater->addDependentFloater(child_floater); +} + +void LLPanelEstateInfo::onKickUserCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata) +{ + if (names.empty() || ids.empty()) return; + + //check to make sure there is one valid user and id + if( (ids[0].isNull()) || + (names[0].length() == 0) ) + { + return; + } + + LLPanelEstateInfo* self = (LLPanelEstateInfo*)userdata; + if(!self) return; + + //keep track of what user they want to kick and other misc info + LLKickFromEstateInfo *kick_info = new LLKickFromEstateInfo(); + kick_info->mEstatePanelp = self; + kick_info->mAgentID = ids[0]; + + //Bring up a confirmation dialog + LLSD args; + args["EVIL_USER"] = names[0]; + LLSD payload; + payload["agent_id"] = ids[0]; + LLNotifications::instance().add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, self, _1, _2)); + +} + +bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + switch(option) + { + case 0: + { + //Kick User + strings_t strings; + strings.push_back(notification["payload"]["agent_id"].asString()); + + sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings); + break; + } + default: + break; + } + return false; +} + +//--------------------------------------------------------------------------- +// Core Add/Remove estate access methods +// TODO: INTERNATIONAL: don't build message text here; +// instead, create multiple translatable messages and choose +// one based on the status. +//--------------------------------------------------------------------------- +std::string all_estates_text() +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return "(error)"; + + std::string owner = panel->getOwnerName(); + + LLViewerRegion* region = gAgent.getRegion(); + if (gAgent.isGodlike()) + { + return llformat("all estates\nowned by %s", owner.c_str()); + } + else if (region && region->getOwner() == gAgent.getID()) + { + return "all estates you own"; + } + else if (region && region->isEstateManager()) + { + return llformat("all estates that\nyou manage for %s", owner.c_str()); + } + else + { + return "(error)"; + } +} + +// static +bool LLPanelEstateInfo::isLindenEstate() +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return false; + + U32 estate_id = panel->getEstateID(); + return (estate_id <= ESTATE_LAST_LINDEN); +} + +typedef std::vector<LLUUID> AgentOrGroupIDsVector; +struct LLEstateAccessChangeInfo +{ + LLEstateAccessChangeInfo(const LLSD& sd) + { + mDialogName = sd["dialog_name"].asString(); + mOperationFlag = (U32)sd["operation"].asInteger(); + LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray(); + for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray(); + id_it != end_it; + ++id_it) + { + mAgentOrGroupIDs.push_back(id_it->asUUID()); + } + } + + const LLSD asLLSD() const + { + LLSD sd; + sd["name"] = mDialogName; + sd["operation"] = (S32)mOperationFlag; + for (AgentOrGroupIDsVector::const_iterator it = mAgentOrGroupIDs.begin(); + it != mAgentOrGroupIDs.end(); + ++it) + { + sd["allowed_ids"].append(*it); + } + return sd; + } + + U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. + std::string mDialogName; + AgentOrGroupIDsVector mAgentOrGroupIDs; // List of agent IDs to apply to this change +}; + +// Special case callback for groups, since it has different callback format than names +// static +void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data) +{ + LLSD payload; + payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; + payload["dialog_name"] = "EstateAllowedGroupAdd"; + payload["allowed_ids"].append(id); + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + + LLNotification::Params params("EstateAllowedGroupAdd"); + params.payload(payload) + .substitutions(args) + .functor(accessCoreConfirm); + if (isLindenEstate()) + { + LLNotifications::instance().forceResponse(params, 0); + } + else + { + LLNotifications::instance().add(params); + } +} + +// static +void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dialog_name) +{ + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + // agent id filled in after avatar picker + + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor(accessAddCore2); + + if (isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + // same as clicking "OK" + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) + { + // abort change + return false; + } + + LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); + // avatar picker yes multi-select, yes close-on-select + LLFloaterAvatarPicker::show(accessAddCore3, (void*)change_info, TRUE, TRUE); + return false; +} + +// static +void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data) +{ + LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; + if (!change_info) return; + if (ids.empty()) + { + // User didn't select a name. + delete change_info; + change_info = NULL; + return; + } + // User did select a name. + change_info->mAgentOrGroupIDs = ids; + // Can't put estate owner on ban list + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return; + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) + { + LLCtrlListInterface *list = panel->childGetListInterface("allowed_avatar_name_list"); + int currentCount = (list ? list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d",ids.size()); + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + args["LIST_TYPE"] = "Allowed Residents"; + args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + } + if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) + { + LLCtrlListInterface *list = panel->childGetListInterface("banned_avatar_name_list"); + int currentCount = (list ? list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d",ids.size()); + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + args["LIST_TYPE"] = "Banned Residents"; + args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); + LLNotifications::instance().add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + } + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + + LLNotification::Params params(change_info->mDialogName); + params.substitutions(args) + .payload(change_info->asLLSD()) + .functor(accessCoreConfirm); + + if (isLindenEstate()) + { + // just apply to this estate + LLNotifications::instance().forceResponse(params, 0); + } + else + { + // ask if this estate or all estates with this owner + LLNotifications::instance().add(params); + } +} + +// static +void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return; + LLNameListCtrl* name_list = panel->getChild<LLNameListCtrl>(list_ctrl_name); + if (!name_list) return; + + std::vector<LLScrollListItem*> list_vector = name_list->getAllSelected(); + if (list_vector.size() == 0) + return; + + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + + for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin(); + iter != list_vector.end(); + iter++) + { + LLScrollListItem *item = (*iter); + payload["allowed_ids"].append(item->getUUID()); + } + + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor(accessRemoveCore2); + + if (isLindenEstate()) + { + // warn on change linden estate + LLNotifications::instance().add(params); + } + else + { + // just proceed, as if clicking OK + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateInfo::accessRemoveCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option != 0) + { + // abort + return false; + } + + // If Linden estate, can only apply to "this" estate, not all estates + // owned by NULL. + if (isLindenEstate()) + { + accessCoreConfirm(notification, response); + } + else + { + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotifications::instance().add(notification["payload"]["dialog_name"], + args, + notification["payload"], + accessCoreConfirm); + } + return false; +} + +// Used for both access add and remove operations, depending on the mOperationFlag +// passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.) +// static +bool LLPanelEstateInfo::accessCoreConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); + + LLViewerRegion* region = gAgent.getRegion(); + + LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); + + for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); + iter != end_it; + iter++) + { + U32 flags = originalFlags; + if (iter + 1 != end_it) + flags |= ESTATE_ACCESS_NO_REPLY; + + const LLUUID id = iter->asUUID(); + if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) + && region && (region->getOwner() == id)) + { + LLNotifications::instance().add("OwnerCanNotBeDenied"); + break; + } + switch(option) + { + case 0: + // This estate + sendEstateAccessDelta(flags, id); + break; + case 1: + { + // All estates, either than I own or manage for this owner. + // This will be verified on simulator. JC + if (!region) break; + if (region->getOwner() == gAgent.getID() + || gAgent.isGodlike()) + { + flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; + sendEstateAccessDelta(flags, id); + } + else if (region->isEstateManager()) + { + flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; + sendEstateAccessDelta(flags, id); + } + break; + } + case 2: + default: + break; + } + } + return false; +} + +// key = "estateaccessdelta" +// str(estate_id) will be added to front of list by forward_EstateOwnerRequest_to_dataserver +// str[0] = str(agent_id) requesting the change +// str[1] = str(flags) (ESTATE_ACCESS_DELTA_*) +// str[2] = str(agent_id) to add or remove +// static +void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id) +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + + msg->nextBlock("MethodData"); + msg->addString("Method", "estateaccessdelta"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + + std::string buf; + gAgent.getID().toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + buf = llformat("%u", flags); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + agent_or_group_id.toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | + ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + + panel->clearAccessLists(); + } + + gAgent.sendReliableMessage(); +} + +void LLPanelEstateInfo::updateControls(LLViewerRegion* region) +{ + BOOL god = gAgent.isGodlike(); + BOOL owner = (region && (region->getOwner() == gAgent.getID())); + BOOL manager = (region && region->isEstateManager()); + setCtrlsEnabled(god || owner || manager); + + childDisable("apply_btn"); + childSetEnabled("add_allowed_avatar_btn", god || owner || manager); + childSetEnabled("remove_allowed_avatar_btn", god || owner || manager); + childSetEnabled("add_allowed_group_btn", god || owner || manager); + childSetEnabled("remove_allowed_group_btn", god || owner || manager); + childSetEnabled("add_banned_avatar_btn", god || owner || manager); + childSetEnabled("remove_banned_avatar_btn", god || owner || manager); + childSetEnabled("message_estate_btn", god || owner || manager); + childSetEnabled("kick_user_from_estate_btn", god || owner || manager); + childSetEnabled("abuse_email_address", god || owner || manager); + + // estate managers can't add estate managers + childSetEnabled("add_estate_manager_btn", god || owner); + childSetEnabled("remove_estate_manager_btn", god || owner); + childSetEnabled("estate_manager_name_list", god || owner); +} + +bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) +{ + updateControls(region); + + // let the parent class handle the general data collection. + bool rv = LLPanelRegionInfo::refreshFromRegion(region); + + // We want estate info. To make sure it works across region + // boundaries and multiple packets, we add a serial number to the + // integers and track against that on update. + strings_t strings; + //integers_t integers; + //LLFloaterRegionInfo::incrementSerial(); + LLFloaterRegionInfo::nextInvoice(); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate(); + + + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + panel->clearAccessLists(); + + + sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); + + refresh(); + + return rv; +} + +void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) +{ + if (checkRemovalButton(child_ctrl->getName())) + { + // do nothing + } + else if (checkSunHourSlider(child_ctrl)) + { + // do nothing + } +} + +bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) +{ + llinfos << "LLPanelEstateInfo::estateUpdate()" << llendl; + return false; +} + + +BOOL LLPanelEstateInfo::postBuild() +{ + // set up the callbacks for the generic controls + initCtrl("externally_visible_check"); + initCtrl("use_global_time_check"); + initCtrl("fixed_sun_check"); + initCtrl("allow_direct_teleport"); + initCtrl("limit_payment"); + initCtrl("limit_age_verified"); + initCtrl("voice_chat_check"); + childSetCommitCallback("abuse_email_address", onChangeAnything, this); + childSetKeystrokeCallback("abuse_email_address", onChangeText, this); + + initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); + initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); + initHelpBtn("fixed_sun_help", "HelpEstateFixedSun"); + initHelpBtn("WLEditSkyHelp", "HelpEditSky"); + initHelpBtn("WLEditDayCycleHelp", "HelpEditDayCycle"); + + initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible"); + initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport"); + initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); + initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); + initHelpBtn("ban_resident_help", "HelpEstateBanResident"); + initHelpBtn("abuse_email_address_help", "HelpEstateAbuseEmailAddress"); + initHelpBtn("voice_chat_help", "HelpEstateVoiceChat"); + + // set up the use global time checkbox + childSetCommitCallback("use_global_time_check", onChangeUseGlobalTime, this); + childSetCommitCallback("fixed_sun_check", onChangeFixedSun, this); + childSetCommitCallback("sun_hour_slider", onChangeChildCtrl, this); + + childSetCommitCallback("allowed_avatar_name_list", onChangeChildCtrl, this); + LLNameListCtrl *avatar_name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list"); + if (avatar_name_list) + { + avatar_name_list->setCommitOnSelectionChange(TRUE); + avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + childSetAction("add_allowed_avatar_btn", onClickAddAllowedAgent, this); + childSetAction("remove_allowed_avatar_btn", onClickRemoveAllowedAgent, this); + + childSetCommitCallback("allowed_group_name_list", onChangeChildCtrl, this); + LLNameListCtrl* group_name_list = getChild<LLNameListCtrl>("allowed_group_name_list"); + if (group_name_list) + { + group_name_list->setCommitOnSelectionChange(TRUE); + group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + childSetAction("add_allowed_group_btn", onClickAddAllowedGroup, this); + childSetAction("remove_allowed_group_btn", onClickRemoveAllowedGroup, this); + + childSetCommitCallback("banned_avatar_name_list", onChangeChildCtrl, this); + LLNameListCtrl* banned_name_list = getChild<LLNameListCtrl>("banned_avatar_name_list"); + if (banned_name_list) + { + banned_name_list->setCommitOnSelectionChange(TRUE); + banned_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + childSetAction("add_banned_avatar_btn", onClickAddBannedAgent, this); + childSetAction("remove_banned_avatar_btn", onClickRemoveBannedAgent, this); + + childSetCommitCallback("estate_manager_name_list", onChangeChildCtrl, this); + LLNameListCtrl* manager_name_list = getChild<LLNameListCtrl>("estate_manager_name_list"); + if (manager_name_list) + { + manager_name_list->setCommitOnSelectionChange(TRUE); + manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue + } + + childSetAction("add_estate_manager_btn", onClickAddEstateManager, this); + childSetAction("remove_estate_manager_btn", onClickRemoveEstateManager, this); + childSetAction("message_estate_btn", onClickMessageEstate, this); + childSetAction("kick_user_from_estate_btn", onClickKickUser, this); + + childSetAction("WLEditSky", onClickEditSky, this); + childSetAction("WLEditDayCycle", onClickEditDayCycle, this); + + return LLPanelRegionInfo::postBuild(); +} + +void LLPanelEstateInfo::refresh() +{ + bool public_access = childGetValue("externally_visible_check").asBoolean(); + childSetEnabled("Only Allow", public_access); + childSetEnabled("limit_payment", public_access); + childSetEnabled("limit_age_verified", public_access); + // if this is set to false, then the limit fields are meaningless and should be turned off + if (public_access == false) + { + childSetValue("limit_payment", false); + childSetValue("limit_age_verified", false); + } +} + +BOOL LLPanelEstateInfo::sendUpdate() +{ + llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl; + + LLNotification::Params params("ChangeLindenEstate"); + params.functor(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2)); + + if (getEstateID() <= ESTATE_LAST_LINDEN) + { + // trying to change reserved estate, warn + LLNotifications::instance().add(params); + } + else + { + // for normal estates, just make the change + LLNotifications::instance().forceResponse(params, 0); + } + return TRUE; +} + +bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + switch(option) + { + case 0: + // send the update + if (!commitEstateInfoCaps()) + { + // the caps method failed, try the old way + LLFloaterRegionInfo::nextInvoice(); + commitEstateInfoDataserver(); + } + // we don't want to do this because we'll get it automatically from the sim + // after the spaceserver processes it +// else +// { +// // caps method does not automatically send this info +// LLFloaterRegionInfo::requestRegionInfo(); +// } + break; + case 1: + default: + // do nothing + break; + } + return false; +} + + +/* +// Request = "getowner" +// SParam[0] = "" (empty string) +// IParam[0] = serial +void LLPanelEstateInfo::getEstateOwner() +{ + // TODO -- disable the panel + // and call this function whenever we cross a region boundary + // re-enable when owner matches, and get new estate info + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_EstateOwnerRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + + msg->nextBlockFast(_PREHASH_RequestData); + msg->addStringFast(_PREHASH_Request, "getowner"); + + // we send an empty string so that the variable block is not empty + msg->nextBlockFast(_PREHASH_StringData); + msg->addStringFast(_PREHASH_SParam, ""); + + msg->nextBlockFast(_PREHASH_IntegerData); + msg->addS32Fast(_PREHASH_IParam, LLFloaterRegionInfo::getSerial()); + + gAgent.sendMessage(); +} +*/ + +class LLEstateChangeInfoResponder : public LLHTTPClient::Responder +{ +public: + LLEstateChangeInfoResponder(void* userdata) : mpPanel((LLPanelEstateInfo*)userdata) {}; + + // if we get a normal response, handle it here + virtual void result(const LLSD& content) + { + // refresh the panel from the database + mpPanel->refresh(); + } + + // if we get an error response + virtual void error(U32 status, const std::string& reason) + { + llinfos << "LLEstateChangeInfoResponder::error " + << status << ": " << reason << llendl; + } +private: + LLPanelEstateInfo* mpPanel; +}; + +// tries to send estate info using a cap; returns true if it succeeded +bool LLPanelEstateInfo::commitEstateInfoCaps() +{ + std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo"); + + if (url.empty()) + { + // whoops, couldn't find the cap, so bail out + return false; + } + + LLSD body; + body["estate_name"] = getEstateName(); + + body["is_externally_visible"] = childGetValue("externally_visible_check").asBoolean(); + body["allow_direct_teleport"] = childGetValue("allow_direct_teleport").asBoolean(); + body["is_sun_fixed" ] = childGetValue("fixed_sun_check").asBoolean(); + body["deny_anonymous" ] = childGetValue("limit_payment").asBoolean(); + body["deny_age_unverified" ] = childGetValue("limit_age_verified").asBoolean(); + body["allow_voice_chat" ] = childGetValue("voice_chat_check").asBoolean(); + body["invoice" ] = LLFloaterRegionInfo::getLastInvoice(); + + // block fly is in estate database but not in estate UI, so we're not supporting it + //body["block_fly" ] = childGetValue("").asBoolean(); + + F32 sun_hour = getSunHour(); + if (childGetValue("use_global_time_check").asBoolean()) + { + sun_hour = 0.f; // 0 = global time + } + body["sun_hour"] = sun_hour; + + body["owner_abuse_email"] = childGetValue("abuse_email_address").asString(); + + // we use a responder so that we can re-get the data after committing to the database + LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder((void*)this)); + return true; +} + +/* This is the old way of doing things, is deprecated, and should be + deleted when the dataserver model can be removed */ +// key = "estatechangeinfo" +// strings[0] = str(estate_id) (added by simulator before relay - not here) +// strings[1] = estate_name +// strings[2] = str(estate_flags) +// strings[3] = str((S32)(sun_hour * 1024.f)) +void LLPanelEstateInfo::commitEstateInfoDataserver() +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + + msg->nextBlock("MethodData"); + msg->addString("Method", "estatechangeinfo"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + + msg->nextBlock("ParamList"); + msg->addString("Parameter", getEstateName()); + + std::string buffer; + buffer = llformat("%u", computeEstateFlags()); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + + F32 sun_hour = getSunHour(); + if (childGetValue("use_global_time_check").asBoolean()) + { + sun_hour = 0.f; // 0 = global time + } + + buffer = llformat("%d", (S32)(sun_hour*1024.0f)); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + + gAgent.sendMessage(); +} + +void LLPanelEstateInfo::setEstateFlags(U32 flags) +{ + childSetValue("externally_visible_check", LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) ); + childSetValue("fixed_sun_check", LLSD(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE) ); + childSetValue( + "voice_chat_check", + LLSD(flags & REGION_FLAGS_ALLOW_VOICE ? TRUE : FALSE)); + childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) ); + childSetValue("limit_payment", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) ); + childSetValue("limit_age_verified", LLSD(flags & REGION_FLAGS_DENY_AGEUNVERIFIED ? TRUE : FALSE) ); + + refresh(); +} + +U32 LLPanelEstateInfo::computeEstateFlags() +{ + U32 flags = 0; + + if (childGetValue("externally_visible_check").asBoolean()) + { + flags |= REGION_FLAGS_EXTERNALLY_VISIBLE; + } + + if ( childGetValue("voice_chat_check").asBoolean() ) + { + flags |= REGION_FLAGS_ALLOW_VOICE; + } + + if (childGetValue("allow_direct_teleport").asBoolean()) + { + flags |= REGION_FLAGS_ALLOW_DIRECT_TELEPORT; + } + + if (childGetValue("fixed_sun_check").asBoolean()) + { + flags |= REGION_FLAGS_SUN_FIXED; + } + + if (childGetValue("limit_payment").asBoolean()) + { + flags |= REGION_FLAGS_DENY_ANONYMOUS; + } + + if (childGetValue("limit_age_verified").asBoolean()) + { + flags |= REGION_FLAGS_DENY_AGEUNVERIFIED; + } + + + return flags; +} + +BOOL LLPanelEstateInfo::getGlobalTime() +{ + return childGetValue("use_global_time_check").asBoolean(); +} + +void LLPanelEstateInfo::setGlobalTime(bool b) +{ + childSetValue("use_global_time_check", LLSD(b)); + childSetEnabled("fixed_sun_check", LLSD(!b)); + childSetEnabled("sun_hour_slider", LLSD(!b)); + if (b) + { + childSetValue("sun_hour_slider", LLSD(0.f)); + } +} + + +BOOL LLPanelEstateInfo::getFixedSun() +{ + return childGetValue("fixed_sun_check").asBoolean(); +} + +void LLPanelEstateInfo::setSunHour(F32 sun_hour) +{ + if(sun_hour < 6.0f) + { + sun_hour = 24.0f + sun_hour; + } + childSetValue("sun_hour_slider", LLSD(sun_hour)); +} + +F32 LLPanelEstateInfo::getSunHour() +{ + if (childIsEnabled("sun_hour_slider")) + { + return (F32)childGetValue("sun_hour_slider").asReal(); + } + return 0.f; +} + +const std::string LLPanelEstateInfo::getEstateName() const +{ + return childGetValue("estate_name").asString(); +} + +void LLPanelEstateInfo::setEstateName(const std::string& name) +{ + childSetValue("estate_name", LLSD(name)); +} + +const std::string LLPanelEstateInfo::getOwnerName() const +{ + return childGetValue("estate_owner").asString(); +} + +void LLPanelEstateInfo::setOwnerName(const std::string& name) +{ + childSetValue("estate_owner", LLSD(name)); +} + +const std::string LLPanelEstateInfo::getAbuseEmailAddress() const +{ + return childGetValue("abuse_email_address").asString(); +} + +void LLPanelEstateInfo::setAbuseEmailAddress(const std::string& address) +{ + childSetValue("abuse_email_address", LLSD(address)); +} + +void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, + bool enable_group, + bool enable_ban) +{ + childSetEnabled("allow_resident_label", enable_agent); + childSetEnabled("allowed_avatar_name_list", enable_agent); + childSetVisible("allowed_avatar_name_list", enable_agent); + childSetEnabled("add_allowed_avatar_btn", enable_agent); + childSetEnabled("remove_allowed_avatar_btn", enable_agent); + + // Groups + childSetEnabled("allow_group_label", enable_group); + childSetEnabled("allowed_group_name_list", enable_group); + childSetVisible("allowed_group_name_list", enable_group); + childSetEnabled("add_allowed_group_btn", enable_group); + childSetEnabled("remove_allowed_group_btn", enable_group); + + // Ban + childSetEnabled("ban_resident_label", enable_ban); + childSetEnabled("banned_avatar_name_list", enable_ban); + childSetVisible("banned_avatar_name_list", enable_ban); + childSetEnabled("add_banned_avatar_btn", enable_ban); + childSetEnabled("remove_banned_avatar_btn", enable_ban); + + // Update removal buttons if needed + if (enable_agent) + { + checkRemovalButton("allowed_avatar_name_list"); + } + + if (enable_group) + { + checkRemovalButton("allowed_group_name_list"); + } + + if (enable_ban) + { + checkRemovalButton("banned_avatar_name_list"); + } +} + +// static +void LLPanelEstateInfo::callbackCacheName( + const LLUUID& id, + const std::string& first, + const std::string& last, + BOOL is_group, + void*) +{ + LLPanelEstateInfo* self = LLFloaterRegionInfo::getPanelEstate(); + if (!self) return; + + std::string name; + + if (id.isNull()) + { + name = "(none)"; + } + else + { + name = first + " " + last; + } + + self->setOwnerName(name); +} + +void LLPanelEstateInfo::clearAccessLists() +{ + LLNameListCtrl* name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list"); + if (name_list) + { + name_list->deleteAllItems(); + } + + name_list = getChild<LLNameListCtrl>("banned_avatar_name_list"); + if (name_list) + { + name_list->deleteAllItems(); + } +} + +// enables/disables the "remove" button for the various allow/ban lists +BOOL LLPanelEstateInfo::checkRemovalButton(std::string name) +{ + std::string btn_name = ""; + if (name == "allowed_avatar_name_list") + { + btn_name = "remove_allowed_avatar_btn"; + } + else if (name == "allowed_group_name_list") + { + btn_name = "remove_allowed_group_btn"; + } + else if (name == "banned_avatar_name_list") + { + btn_name = "remove_banned_avatar_btn"; + } + else if (name == "estate_manager_name_list") + { + //ONLY OWNER CAN ADD /DELET ESTATE MANAGER + LLViewerRegion* region = gAgent.getRegion(); + if (region && (region->getOwner() == gAgent.getID())) + { + btn_name = "remove_estate_manager_btn"; + } + } + + // enable the remove button if something is selected + LLNameListCtrl* name_list = getChild<LLNameListCtrl>(name); + childSetEnabled(btn_name, name_list && name_list->getFirstSelected() ? TRUE : FALSE); + + return (btn_name != ""); +} + +BOOL LLPanelEstateInfo::checkSunHourSlider(LLUICtrl* child_ctrl) +{ + BOOL found_child_ctrl = FALSE; + if (child_ctrl->getName() == "sun_hour_slider") + { + enableButton("apply_btn"); + found_child_ctrl = TRUE; + } + return found_child_ctrl; +} + +// static +void LLPanelEstateInfo::onClickMessageEstate(void* userdata) +{ + llinfos << "LLPanelEstateInfo::onClickMessageEstate" << llendl; + LLNotifications::instance().add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2)); +} + +bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + std::string text = response["message"].asString(); + if(option != 0) return false; + if(text.empty()) return false; + llinfos << "Message to everyone: " << text << llendl; + strings_t strings; + //integers_t integers; + std::string name; + gAgent.buildFullname(name); + strings.push_back(strings_t::value_type(name)); + strings.push_back(strings_t::value_type(text)); + LLUUID invoice(LLFloaterRegionInfo::getLastInvoice()); + sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings); + return false; +} + +LLPanelEstateCovenant::LLPanelEstateCovenant() +: mCovenantID(LLUUID::null) +{ +} + +// virtual +bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) +{ + LLTextBox* region_name = getChild<LLTextBox>("region_name_text"); + if (region_name) + { + region_name->setText(region->getName()); + } + + LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause"); + if (resellable_clause) + { + if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + { + resellable_clause->setText(getString("can_not_resell")); + } + else + { + resellable_clause->setText(getString("can_resell")); + } + } + + LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause"); + if (changeable_clause) + { + if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) + { + changeable_clause->setText(getString("can_change")); + } + else + { + changeable_clause->setText(getString("can_not_change")); + } + } + + LLTextBox* region_maturity = getChild<LLTextBox>("region_maturity_text"); + if (region_maturity) + { + region_maturity->setText(region->getSimAccessString()); + } + + LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text"); + if (region_landtype) + { + region_landtype->setText(region->getSimProductName()); + } + + + // let the parent class handle the general data collection. + bool rv = LLPanelRegionInfo::refreshFromRegion(region); + LLMessageSystem *msg = gMessageSystem; + msg->newMessage("EstateCovenantRequest"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->sendReliable(region->getHost()); + return rv; +} + +// virtual +bool LLPanelEstateCovenant::estateUpdate(LLMessageSystem* msg) +{ + llinfos << "LLPanelEstateCovenant::estateUpdate()" << llendl; + return true; +} + +// virtual +BOOL LLPanelEstateCovenant::postBuild() +{ + initHelpBtn("covenant_help", "HelpEstateCovenant"); + mEstateNameText = getChild<LLTextBox>("estate_name_text"); + mEstateOwnerText = getChild<LLTextBox>("estate_owner_text"); + mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text"); + mEditor = getChild<LLViewerTextEditor>("covenant_editor"); + if (mEditor) mEditor->setHandleEditKeysDirectly(TRUE); + LLButton* reset_button = getChild<LLButton>("reset_covenant"); + reset_button->setEnabled(gAgent.canManageEstate()); + reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); + + return LLPanelRegionInfo::postBuild(); +} + +// virtual +void LLPanelEstateCovenant::updateChild(LLUICtrl* child_ctrl) +{ +} + +// virtual +BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + LLInventoryItem* item = (LLInventoryItem*)cargo_data; + + if (!gAgent.canManageEstate()) + { + *accept = ACCEPT_NO; + return TRUE; + } + + switch(cargo_type) + { + case DAD_NOTECARD: + *accept = ACCEPT_YES_COPY_SINGLE; + if (item && drop) + { + LLSD payload; + payload["item_id"] = item->getUUID(); + LLNotifications::instance().add("EstateChangeCovenant", LLSD(), payload, + LLPanelEstateCovenant::confirmChangeCovenantCallback); + } + break; + default: + *accept = ACCEPT_NO; + break; + } + + return TRUE; +} + +// static +bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); + LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); + + if (!item || !self) return false; + + switch(option) + { + case 0: + self->loadInvItem(item); + break; + default: + break; + } + return false; +} + +// static +void LLPanelEstateCovenant::resetCovenantID(void* userdata) +{ + LLNotifications::instance().add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback); +} + +// static +bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response) +{ + LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant(); + if (!self) return false; + + S32 option = LLNotification::getSelectedOption(notification, response); + switch(option) + { + case 0: + self->loadInvItem(NULL); + break; + default: + break; + } + return false; +} + +void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp) +{ + const BOOL high_priority = TRUE; + if (itemp) + { + gAssetStorage->getInvItemAsset(gAgent.getRegionHost(), + gAgent.getID(), + gAgent.getSessionID(), + itemp->getPermissions().getOwner(), + LLUUID::null, + itemp->getUUID(), + itemp->getAssetUUID(), + itemp->getType(), + onLoadComplete, + (void*)this, + high_priority); + mAssetStatus = ASSET_LOADING; + } + else + { + mAssetStatus = ASSET_LOADED; + setCovenantTextEditor("There is no Covenant provided for this Estate."); + sendChangeCovenantID(LLUUID::null); + } +} + +// static +void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs, + const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + llinfos << "LLPanelEstateCovenant::onLoadComplete()" << llendl; + LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data; + if( panelp ) + { + if(0 == status) + { + LLVFile file(vfs, asset_uuid, type, LLVFile::READ); + + S32 file_length = file.getSize(); + + char* buffer = new char[file_length+1]; + if (buffer == NULL) + { + llerrs << "Memory Allocation Failed" << llendl; + return; + } + + file.read((U8*)buffer, file_length); /* Flawfinder: ignore */ + // put a EOS at the end + buffer[file_length] = 0; + + if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) ) + { + if( !panelp->mEditor->importBuffer( buffer, file_length+1 ) ) + { + llwarns << "Problem importing estate covenant." << llendl; + LLNotifications::instance().add("ProblemImportingEstateCovenant"); + } + else + { + panelp->sendChangeCovenantID(asset_uuid); + } + } + else + { + // Version 0 (just text, doesn't include version number) + panelp->sendChangeCovenantID(asset_uuid); + } + delete[] buffer; + } + else + { + LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); + + if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || + LL_ERR_FILE_EMPTY == status) + { + LLNotifications::instance().add("MissingNotecardAssetID"); + } + else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) + { + LLNotifications::instance().add("NotAllowedToViewNotecard"); + } + else + { + LLNotifications::instance().add("UnableToLoadNotecardAsset"); + } + + llwarns << "Problem loading notecard: " << status << llendl; + } + panelp->mAssetStatus = ASSET_LOADED; + panelp->setCovenantID(asset_uuid); + } +} + +// key = "estatechangecovenantid" +// strings[0] = str(estate_id) (added by simulator before relay - not here) +// strings[1] = str(covenant_id) +void LLPanelEstateCovenant::sendChangeCovenantID(const LLUUID &asset_id) +{ + if (asset_id != getCovenantID()) + { + setCovenantID(asset_id); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + + msg->nextBlock("MethodData"); + msg->addString("Method", "estatechangecovenantid"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + + msg->nextBlock("ParamList"); + msg->addString("Parameter", getCovenantID().asString()); + gAgent.sendReliableMessage(); + } +} + +// virtual +BOOL LLPanelEstateCovenant::sendUpdate() +{ + return TRUE; +} + +const std::string& LLPanelEstateCovenant::getEstateName() const +{ + return mEstateNameText->getText(); +} + +void LLPanelEstateCovenant::setEstateName(const std::string& name) +{ + mEstateNameText->setText(name); +} + +// static +void LLPanelEstateCovenant::updateCovenantText(const std::string& string, const LLUUID& asset_id) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEditor->setText(string); + panelp->setCovenantID(asset_id); + } +} + +// static +void LLPanelEstateCovenant::updateEstateName(const std::string& name) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEstateNameText->setText(name); + } +} + +// static +void LLPanelEstateCovenant::updateLastModified(const std::string& text) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mLastModifiedText->setText(text); + } +} + +// static +void LLPanelEstateCovenant::updateEstateOwnerName(const std::string& name) +{ + LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant(); + if( panelp ) + { + panelp->mEstateOwnerText->setText(name); + } +} + +const std::string& LLPanelEstateCovenant::getOwnerName() const +{ + return mEstateOwnerText->getText(); +} + +void LLPanelEstateCovenant::setOwnerName(const std::string& name) +{ + mEstateOwnerText->setText(name); +} + +void LLPanelEstateCovenant::setCovenantTextEditor(const std::string& text) +{ + mEditor->setText(text); +} + +// key = "estateupdateinfo" +// strings[0] = estate name +// strings[1] = str(owner_id) +// strings[2] = str(estate_id) +// strings[3] = str(estate_flags) +// strings[4] = str((S32)(sun_hour * 1024)) +// strings[5] = str(parent_estate_id) +// strings[6] = str(covenant_id) +// strings[7] = str(covenant_timestamp) +// strings[8] = str(send_to_agent_only) +// strings[9] = str(abuse_email_addr) +bool LLDispatchEstateUpdateInfo::operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return true; + + // NOTE: LLDispatcher extracts strings with an extra \0 at the + // end. If we pass the std::string direct to the UI/renderer + // it draws with a weird character at the end of the string. + std::string estate_name = strings[0].c_str(); // preserve c_str() call! + panel->setEstateName(estate_name); + + if (strings.size() > 3) + { + std::string abuse_email = strings[9].c_str(); // preserve c_str() call! + panel->setAbuseEmailAddress(abuse_email); + } + else + { + panel->setAbuseEmailAddress(panel->getString("email_unsupported")); + } + + LLViewerRegion* regionp = gAgent.getRegion(); + + LLUUID owner_id(strings[1]); + regionp->setOwner(owner_id); + // Update estate owner name in UI + const BOOL is_group = FALSE; + gCacheName->get(owner_id, is_group, LLPanelEstateInfo::callbackCacheName); + + U32 estate_id = strtoul(strings[2].c_str(), NULL, 10); + panel->setEstateID(estate_id); + + U32 flags = strtoul(strings[3].c_str(), NULL, 10); + panel->setEstateFlags(flags); + + F32 sun_hour = ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f; + if(sun_hour == 0 && (flags & REGION_FLAGS_SUN_FIXED ? FALSE : TRUE)) + { + panel->setGlobalTime(TRUE); + } + else + { + panel->setGlobalTime(FALSE); + panel->setSunHour(sun_hour); + } + + bool visible_from_mainland = (bool)(flags & REGION_FLAGS_EXTERNALLY_VISIBLE); + bool god = gAgent.isGodlike(); + bool linden_estate = (estate_id <= ESTATE_LAST_LINDEN); + + // If visible from mainland, disable the access allowed + // UI, as anyone can teleport there. + // However, gods need to be able to edit the access list for + // linden estates, regardless of visibility, to allow object + // and L$ transfers. + bool enable_agent = (!visible_from_mainland || (god && linden_estate)); + bool enable_group = enable_agent; + bool enable_ban = !linden_estate; + panel->setAccessAllowedEnabled(enable_agent, enable_group, enable_ban); + + return true; +} + + +// key = "setaccess" +// strings[0] = str(estate_id) +// strings[1] = str(packed_access_lists) +// strings[2] = str(num allowed agent ids) +// strings[3] = str(num allowed group ids) +// strings[4] = str(num banned agent ids) +// strings[5] = str(num estate manager agent ids) +// strings[6] = bin(uuid) +// strings[7] = bin(uuid) +// strings[8] = bin(uuid) +// ... +bool LLDispatchSetEstateAccess::operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) +{ + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (!panel) return true; + + S32 index = 1; // skip estate_id + U32 access_flags = strtoul(strings[index++].c_str(), NULL,10); + S32 num_allowed_agents = strtol(strings[index++].c_str(), NULL, 10); + S32 num_allowed_groups = strtol(strings[index++].c_str(), NULL, 10); + S32 num_banned_agents = strtol(strings[index++].c_str(), NULL, 10); + S32 num_estate_managers = strtol(strings[index++].c_str(), NULL, 10); + + // sanity ckecks + if (num_allowed_agents > 0 + && !(access_flags & ESTATE_ACCESS_ALLOWED_AGENTS)) + { + llwarns << "non-zero count for allowed agents, but no corresponding flag" << llendl; + } + if (num_allowed_groups > 0 + && !(access_flags & ESTATE_ACCESS_ALLOWED_GROUPS)) + { + llwarns << "non-zero count for allowed groups, but no corresponding flag" << llendl; + } + if (num_banned_agents > 0 + && !(access_flags & ESTATE_ACCESS_BANNED_AGENTS)) + { + llwarns << "non-zero count for banned agents, but no corresponding flag" << llendl; + } + if (num_estate_managers > 0 + && !(access_flags & ESTATE_ACCESS_MANAGERS)) + { + llwarns << "non-zero count for managers, but no corresponding flag" << llendl; + } + + // grab the UUID's out of the string fields + if (access_flags & ESTATE_ACCESS_ALLOWED_AGENTS) + { + LLNameListCtrl* allowed_agent_name_list; + allowed_agent_name_list = panel->getChild<LLNameListCtrl>("allowed_avatar_name_list"); + + int totalAllowedAgents = num_allowed_agents; + + if (allowed_agent_name_list) + { + totalAllowedAgents += allowed_agent_name_list->getItemCount(); + } + + std::string msg = llformat("Allowed residents: (%d, max %d)", + totalAllowedAgents, + ESTATE_MAX_ACCESS_IDS); + panel->childSetValue("allow_resident_label", LLSD(msg)); + + if (allowed_agent_name_list) + { + //allowed_agent_name_list->deleteAllItems(); + for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + allowed_agent_name_list->addNameItem(id); + } + panel->childSetEnabled("remove_allowed_avatar_btn", allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); + allowed_agent_name_list->sortByColumnIndex(0, TRUE); + } + } + + if (access_flags & ESTATE_ACCESS_ALLOWED_GROUPS) + { + LLNameListCtrl* allowed_group_name_list; + allowed_group_name_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list"); + + std::string msg = llformat("Allowed groups: (%d, max %d)", + num_allowed_groups, + (S32) ESTATE_MAX_GROUP_IDS); + panel->childSetValue("allow_group_label", LLSD(msg)); + + if (allowed_group_name_list) + { + allowed_group_name_list->deleteAllItems(); + for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + allowed_group_name_list->addGroupNameItem(id); + } + panel->childSetEnabled("remove_allowed_group_btn", allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); + allowed_group_name_list->sortByColumnIndex(0, TRUE); + } + } + + if (access_flags & ESTATE_ACCESS_BANNED_AGENTS) + { + LLNameListCtrl* banned_agent_name_list; + banned_agent_name_list = panel->getChild<LLNameListCtrl>("banned_avatar_name_list"); + + int totalBannedAgents = num_banned_agents; + + if (banned_agent_name_list) + { + totalBannedAgents += banned_agent_name_list->getItemCount(); + } + + + std::string msg = llformat("Banned residents: (%d, max %d)", + totalBannedAgents, + ESTATE_MAX_ACCESS_IDS); + panel->childSetValue("ban_resident_label", LLSD(msg)); + + if (banned_agent_name_list) + { + //banned_agent_name_list->deleteAllItems(); + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + banned_agent_name_list->addNameItem(id); + } + panel->childSetEnabled("remove_banned_avatar_btn", banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); + banned_agent_name_list->sortByColumnIndex(0, TRUE); + } + } + + if (access_flags & ESTATE_ACCESS_MANAGERS) + { + std::string msg = llformat("Estate Managers: (%d, max %d)", + num_estate_managers, + ESTATE_MAX_MANAGERS); + panel->childSetValue("estate_manager_label", LLSD(msg)); + + LLNameListCtrl* estate_manager_name_list = + panel->getChild<LLNameListCtrl>("estate_manager_name_list"); + if (estate_manager_name_list) + { + estate_manager_name_list->deleteAllItems(); // Clear existing entries + + // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't + // truncate the list unless it's really big. Go ahead and show the extras so the user doesn't get confused, + // and they can still remove them. + for (S32 i = 0; i < num_estate_managers && i < (ESTATE_MAX_MANAGERS * 4); i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + estate_manager_name_list->addNameItem(id); + } + panel->childSetEnabled("remove_estate_manager_btn", estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); + estate_manager_name_list->sortByColumnIndex(0, TRUE); + } + } + + return true; +} + +// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) +void LLFloaterRegionInfo::open() +{ + // We'll allow access to the estate tools for estate managers (and for the sim owner) + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) + { + LLViewerRegion* pRegion = gAgent.getRegion(); + if (!pRegion) + return; + + // Should be able to call LLRegion::canManageEstate() but then we can fake god like + if ( (!pRegion->isEstateManager()) && (pRegion->getOwner() != gAgent.getID()) ) + return; + } + + LLFloater::open(); +} +// [/RLVa:KB] diff --git a/linden/indra/newview/llfloaterregioninfo.h b/linden/indra/newview/llfloaterregioninfo.h index fd0d9ce63..ee01c7c58 100644 --- a/linden/indra/newview/llfloaterregioninfo.h +++ b/linden/indra/newview/llfloaterregioninfo.h @@ -53,6 +53,7 @@ class LLSpinCtrl; class LLTextBox; class LLPanelRegionGeneralInfo; +class LLPanelRegionOpenSettingsInfo; class LLPanelRegionDebugInfo; class LLPanelRegionTextureInfo; class LLPanelRegionTerrainInfo; @@ -83,6 +84,7 @@ class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton<LLFloate static LLPanelEstateInfo* getPanelEstate(); static LLPanelEstateCovenant* getPanelCovenant(); + static LLPanelRegionOpenSettingsInfo* getPanelOpenSettings(); // from LLPanel virtual void refresh(); @@ -173,6 +175,24 @@ class LLPanelRegionGeneralInfo : public LLPanelRegionInfo ///////////////////////////////////////////////////////////////////////////// +class LLPanelRegionOpenSettingsInfo : public LLPanelRegionInfo +{ +public: + LLPanelRegionOpenSettingsInfo() + : LLPanelRegionInfo() {} + ~LLPanelRegionOpenSettingsInfo() {} + + virtual bool refreshFromRegion(LLViewerRegion* region); + + // LLPanel + virtual BOOL postBuild(); + +protected: + static void sendUpdate(void* userdata); +}; + +///////////////////////////////////////////////////////////////////////////// + class LLPanelRegionDebugInfo : public LLPanelRegionInfo { public: diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 6744faf5a..c092f5a63 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -181,26 +181,23 @@ void* LLFloaterTools::createPanelLandInfo(void* data) void LLFloaterTools::updateToolsSizeLimits() { - if (gSavedSettings.getBOOL("DisableMaxBuildConstraints")) - { - getChild<LLSpinCtrl>("Scale X")->setMaxValue(F32_MAX); - getChild<LLSpinCtrl>("Scale Y")->setMaxValue(F32_MAX); - getChild<LLSpinCtrl>("Scale Z")->setMaxValue(F32_MAX); + getChild<LLSpinCtrl>("Scale X")->setMinValue(gHippoLimits->getMinPrimScale()); + getChild<LLSpinCtrl>("Scale Y")->setMinValue(gHippoLimits->getMinPrimScale()); + getChild<LLSpinCtrl>("Scale Z")->setMinValue(gHippoLimits->getMinPrimScale()); - getChild<LLSpinCtrl>("Pos X")->setMaxValue(F32_MAX); - getChild<LLSpinCtrl>("Pos Y")->setMaxValue(F32_MAX); - getChild<LLSpinCtrl>("Pos Z")->setMaxValue(F32_MAX); - } - else - { - getChild<LLSpinCtrl>("Scale X")->setMaxValue(gHippoLimits->getMaxPrimScale()); - getChild<LLSpinCtrl>("Scale Y")->setMaxValue(gHippoLimits->getMaxPrimScale()); - getChild<LLSpinCtrl>("Scale Z")->setMaxValue(gHippoLimits->getMaxPrimScale()); + getChild<LLSpinCtrl>("Scale X")->setMaxValue(gHippoLimits->getMaxPrimScale()); + getChild<LLSpinCtrl>("Scale Y")->setMaxValue(gHippoLimits->getMaxPrimScale()); + getChild<LLSpinCtrl>("Scale Z")->setMaxValue(gHippoLimits->getMaxPrimScale()); - getChild<LLSpinCtrl>("Scale X")->setMinValue(gHippoLimits->getMinPrimScale()); - getChild<LLSpinCtrl>("Scale Y")->setMinValue(gHippoLimits->getMinPrimScale()); - getChild<LLSpinCtrl>("Scale Z")->setMinValue(gHippoLimits->getMinPrimScale()); - } + getChild<LLSpinCtrl>("Pos X")->setMinValue(gHippoLimits->getMinPrimXPos()); + getChild<LLSpinCtrl>("Pos Y")->setMinValue(gHippoLimits->getMinPrimYPos()); + getChild<LLSpinCtrl>("Pos Z")->setMinValue(gHippoLimits->getMinPrimZPos()); + + getChild<LLSpinCtrl>("Pos X")->setMaxValue(gHippoLimits->getMaxPrimXPos()); + getChild<LLSpinCtrl>("Pos Y")->setMaxValue(gHippoLimits->getMaxPrimYPos()); + getChild<LLSpinCtrl>("Pos Z")->setMaxValue(gHippoLimits->getMinPrimZPos()); + + getChild<LLCheckBoxCtrl>("Physical Checkbox Ctrl")->setEnabled(gHippoLimits->mAllowPhysicalPrims); } void LLFloaterTools::updateToolsPrecision() @@ -1258,8 +1255,18 @@ void LLFloaterTools::onClickLink(void* data) return; } - S32 max_linked_prims = gHippoLimits->getMaxLinkedPrims(); - if (max_linked_prims > -1) + S32 max_linked_prims = 0; + if(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->usePhysics()) + { + //Physical - use phys prim limit + max_linked_prims = gHippoLimits->getMaxPhysLinkedPrims(); + } + else + { + //Non phys limit + max_linked_prims = gHippoLimits->getMaxLinkedPrims(); + } + if (max_linked_prims > -1) //-1 : no limits { S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); if (object_count > max_linked_prims + 1) @@ -1271,7 +1278,7 @@ void LLFloaterTools::onClickLink(void* data) return; } } - + if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2) { LLNotifications::instance().add("CannotLinkIncompleteSet"); diff --git a/linden/indra/newview/llfloatertos.cpp b/linden/indra/newview/llfloatertos.cpp index 52d7b1f3c..2684e10e0 100644 --- a/linden/indra/newview/llfloatertos.cpp +++ b/linden/indra/newview/llfloatertos.cpp @@ -1,284 +1,310 @@ -/** - * @file llfloatertos.cpp - * @brief Terms of Service Agreement dialog - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloatertos.h" - -// viewer includes -#include "llagent.h" -#include "llappviewer.h" -#include "llstartup.h" -#include "llviewerstats.h" -#include "llviewertexteditor.h" -#include "llviewerwindow.h" - -// linden library includes -#include "llbutton.h" -#include "llhttpclient.h" -#include "llhttpstatuscodes.h" // for HTTP_FOUND -#include "llradiogroup.h" -#include "lltextbox.h" -#include "llui.h" -#include "lluictrlfactory.h" -#include "llvfile.h" -#include "message.h" - - -// static -LLFloaterTOS* LLFloaterTOS::sInstance = NULL; - -// static -LLFloaterTOS* LLFloaterTOS::show(ETOSType type, const std::string & message) -{ - if( !LLFloaterTOS::sInstance ) - { - LLFloaterTOS::sInstance = new LLFloaterTOS(type, message); - } - - if (type == TOS_TOS) - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_tos.xml"); - } - else - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_critical.xml"); - } - - return LLFloaterTOS::sInstance; -} - - -LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string & message) -: LLModalDialog( std::string(" "), 100, 100 ), - mType(type), - mMessage(message), - mWebBrowserWindowId( 0 ), - mLoadCompleteCount( 0 ) -{ -} - -// helper class that trys to download a URL from a web site and calls a method -// on parent class indicating if the web server is working or not -class LLIamHereTOS : public LLHTTPClient::Responder -{ - private: - LLIamHereTOS( LLFloaterTOS* parent ) : - mParent( parent ) - {} - - LLFloaterTOS* mParent; - - public: - - static boost::intrusive_ptr< LLIamHereTOS > build( LLFloaterTOS* parent ) - { - return boost::intrusive_ptr< LLIamHereTOS >( new LLIamHereTOS( parent ) ); - }; - - virtual void setParent( LLFloaterTOS* parentIn ) - { - mParent = parentIn; - }; - - virtual void result( const LLSD& content ) - { - if ( mParent ) - mParent->setSiteIsAlive( true ); - }; - - virtual void error( U32 status, const std::string& reason ) - { - if ( mParent ) - { - // *HACK: For purposes of this alive check, 302 Found - // (aka Moved Temporarily) is considered alive. The web site - // redirects this link to a "cache busting" temporary URL. JC - bool alive = (status == HTTP_FOUND); - mParent->setSiteIsAlive( alive ); - } - }; -}; - -// this is global and not a class member to keep crud out of the header file -namespace { - boost::intrusive_ptr< LLIamHereTOS > gResponsePtr = 0; -}; - -BOOL LLFloaterTOS::postBuild() -{ - childSetAction("Continue", onContinue, this); - childSetAction("Cancel", onCancel, this); - childSetCommitCallback("agree_chk", updateAgree, this); - - if ( mType != TOS_TOS ) - { - llinfos << "tos_type != TOS_TOS" << llendl; - // this displays the critical message - LLTextEditor *editor = getChild<LLTextEditor>("tos_text"); - editor->setHandleEditKeysDirectly( TRUE ); - editor->setEnabled( FALSE ); - editor->setWordWrap(TRUE); - editor->setFocus(TRUE); - // editor->setValue(LLSD(mMessage)); - editor->setValue(mMessage); - - return TRUE; - } - - // disable Agree to TOS radio button until the page has fully loaded - LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); - tos_agreement->setEnabled( false ); - - // hide the SL text widget if we're displaying TOS with using a browser widget. - LLTextEditor *editor = getChild<LLTextEditor>("tos_text"); - editor->setVisible(FALSE); - - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); - if ( web_browser ) - { - // start to observe it so we see navigate complete events - web_browser->addObserver( this ); - - gResponsePtr = LLIamHereTOS::build( this ); - LLHTTPClient::head( getString( "real_url" ), gResponsePtr ); - } - - return TRUE; -} - -void LLFloaterTOS::setSiteIsAlive( bool alive ) -{ - // only do this for TOS pages - if ( mType == TOS_TOS ) - { - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); - // if the contents of the site was retrieved - if ( alive ) - { - if ( web_browser ) - { - // navigate to the "real" page - web_browser->navigateTo( getString( "real_url" ) ); - }; - } - else - { - // normally this is set when navigation to TOS page navigation completes (so you can't accept before TOS loads) - // but if the page is unavailable, we need to do this now - LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); - tos_agreement->setEnabled( true ); - }; - }; -} - -LLFloaterTOS::~LLFloaterTOS() -{ - // stop obsaerving events - LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); - if ( web_browser ) - { - web_browser->remObserver( this ); - }; - - // tell the responder we're not here anymore - if ( gResponsePtr ) - gResponsePtr->setParent( 0 ); - - LLFloaterTOS::sInstance = NULL; -} - -// virtual -void LLFloaterTOS::draw() -{ - // draw children - LLModalDialog::draw(); -} - -// static -void LLFloaterTOS::updateAgree(LLUICtrl*, void* userdata ) -{ - LLFloaterTOS* self = (LLFloaterTOS*) userdata; - bool agree = self->childGetValue("agree_chk").asBoolean(); - self->childSetEnabled("Continue", agree); -} - -// static -void LLFloaterTOS::onContinue( void* userdata ) -{ - LLFloaterTOS* self = (LLFloaterTOS*) userdata; - llinfos << "User agrees with TOS." << llendl; - if (self->mType == TOS_TOS) - { - gAcceptTOS = TRUE; - } - else - { - gAcceptCriticalMessage = TRUE; - } - - // Testing TOS dialog - #if ! LL_RELEASE_FOR_DOWNLOAD - if ( LLStartUp::getStartupState() == STATE_LOGIN_WAIT ) - { - LLStartUp::setStartupState( STATE_LOGIN_SHOW ); - } - else - #endif - - LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication - self->close(); // destroys this object -} - -// static -void LLFloaterTOS::onCancel( void* userdata ) -{ - LLFloaterTOS* self = (LLFloaterTOS*) userdata; - llinfos << "User disagrees with TOS." << llendl; - LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done); - LLStartUp::setStartupState( STATE_LOGIN_SHOW ); - self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS - self->close(); // destroys this object -} - -//virtual -void LLFloaterTOS::onNavigateComplete( const EventType& eventIn ) -{ - // skip past the loading screen navigate complete - if ( ++mLoadCompleteCount == 2 ) - { - llinfos << "NAVIGATE COMPLETE" << llendl; - // enable Agree to TOS radio button now that page has loaded - LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); - tos_agreement->setEnabled( true ); - }; -} +/** + * @file llfloatertos.cpp + * @brief Terms of Service Agreement dialog + * + * $LicenseInfo:firstyear=2003&license=viewergpl$ + * + * Copyright (c) 2003-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatertos.h" + +// viewer includes +#include "llagent.h" +#include "llappviewer.h" +#include "llstartup.h" +#include "llviewerstats.h" +#include "llviewertexteditor.h" +#include "llviewerwindow.h" + +// linden library includes +#include "llbutton.h" +#include "llhttpclient.h" +#include "llhttpstatuscodes.h" // for HTTP_FOUND +#include "llradiogroup.h" +#include "lltextbox.h" +#include "llui.h" +#include "lluictrlfactory.h" +#include "llvfile.h" +#include "message.h" +#include "hippoGridManager.h" + + +// static +LLFloaterTOS* LLFloaterTOS::sInstance = NULL; + +// static +LLFloaterTOS* LLFloaterTOS::show(ETOSType type, const std::string & message) +{ + if( !LLFloaterTOS::sInstance ) + { + LLFloaterTOS::sInstance = new LLFloaterTOS(type, message); + } + + if (type == TOS_TOS) + { + LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_tos.xml"); + } + else + { + LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_critical.xml"); + } + + return LLFloaterTOS::sInstance; +} + + +LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string & message) +: LLModalDialog( std::string(" "), 100, 100 ), + mType(type), + mMessage(message), + mWebBrowserWindowId( 0 ), + mLoadCompleteCount( 0 ) +{ +} + +// helper class that trys to download a URL from a web site and calls a method +// on parent class indicating if the web server is working or not +class LLIamHereTOS : public LLHTTPClient::Responder +{ + private: + LLIamHereTOS( LLFloaterTOS* parent ) : + mParent( parent ) + {} + + LLFloaterTOS* mParent; + + public: + + static boost::intrusive_ptr< LLIamHereTOS > build( LLFloaterTOS* parent ) + { + return boost::intrusive_ptr< LLIamHereTOS >( new LLIamHereTOS( parent ) ); + }; + + virtual void setParent( LLFloaterTOS* parentIn ) + { + mParent = parentIn; + }; + + virtual void result( const LLSD& content ) + { + if ( mParent ) + mParent->setSiteIsAlive( true ); + }; + + virtual void error( U32 status, const std::string& reason ) + { + if ( mParent ) + { + // *HACK: For purposes of this alive check, 302 Found + // (aka Moved Temporarily) is considered alive. The web site + // redirects this link to a "cache busting" temporary URL. JC + bool alive = (status == HTTP_FOUND); + mParent->setSiteIsAlive( alive ); + } + }; +}; + +// this is global and not a class member to keep crud out of the header file +namespace { + boost::intrusive_ptr< LLIamHereTOS > gResponsePtr = 0; +}; + +BOOL LLFloaterTOS::postBuild() +{ + childSetAction("Continue", onContinue, this); + childSetAction("Cancel", onCancel, this); + childSetCommitCallback("agree_chk", updateAgree, this); + + LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); + tos_agreement->setEnabled( true ); + + //Always set this so that the TOS is displayed whether the web browser pops up or not. + LLTextEditor *editor = getChild<LLTextEditor>("tos_text"); + editor->setHandleEditKeysDirectly( TRUE ); + editor->setEnabled( FALSE ); + editor->setWordWrap(TRUE); + editor->setFocus(TRUE); + editor->setValue(LLSD(mMessage)); + LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); + if (web_browser) + { + //Disable for critical messages and text messages, it is reenabled later + web_browser->setVisible( FALSE ); + } + + if ( mType != TOS_TOS ) + { + // this displays the critical message only + return TRUE; + } + bool use_web_browser = false; + + //Check to see if the message is a link to display + std::string token = "http://"; + std::string::size_type iIndex = mMessage.rfind(token); + //IF it has http:// in it, we use the web browser + if(iIndex != std::string::npos && mMessage.length() >= 2) + { + // it exists + use_web_browser = true; + } + else if (gHippoGridManager->getConnectedGrid()->isSecondLife()) + { + //Its SL, use the browser for it as thats what it should do + use_web_browser = true; + } + + if ( web_browser && use_web_browser) + { + // hide the SL text widget if we're displaying TOS with using a browser widget. + LLTextEditor *editor = getChild<LLTextEditor>("tos_text"); + editor->setVisible( FALSE ); + + // disable Agree to TOS radio button until the page has fully loaded + tos_agreement->setEnabled( false ); + + // Reenable the web browser + web_browser->setVisible( TRUE ); + + // start to observe it so we see navigate complete events + web_browser->addObserver( this ); + + gResponsePtr = LLIamHereTOS::build( this ); + LLHTTPClient::head( getString( "real_url" ), gResponsePtr ); + } + + return TRUE; +} + +void LLFloaterTOS::setSiteIsAlive( bool alive ) +{ + // only do this for TOS pages + if ( mType == TOS_TOS ) + { + LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); + // if the contents of the site was retrieved + if ( alive ) + { + if ( web_browser ) + { + // navigate to the "real" page + web_browser->navigateTo( getString( "real_url" ) ); + }; + } + else + { + // normally this is set when navigation to TOS page navigation completes (so you can't accept before TOS loads) + // but if the page is unavailable, we need to do this now + LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); + tos_agreement->setEnabled( true ); + }; + }; +} + +LLFloaterTOS::~LLFloaterTOS() +{ + // stop obsaerving events + LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html"); + if ( web_browser ) + { + web_browser->remObserver( this ); + }; + + // tell the responder we're not here anymore + if ( gResponsePtr ) + gResponsePtr->setParent( 0 ); + + LLFloaterTOS::sInstance = NULL; +} + +// virtual +void LLFloaterTOS::draw() +{ + // draw children + LLModalDialog::draw(); +} + +// static +void LLFloaterTOS::updateAgree(LLUICtrl*, void* userdata ) +{ + LLFloaterTOS* self = (LLFloaterTOS*) userdata; + bool agree = self->childGetValue("agree_chk").asBoolean(); + self->childSetEnabled("Continue", agree); +} + +// static +void LLFloaterTOS::onContinue( void* userdata ) +{ + LLFloaterTOS* self = (LLFloaterTOS*) userdata; + llinfos << "User agrees with TOS." << llendl; + if (self->mType == TOS_TOS) + { + gAcceptTOS = TRUE; + } + else + { + gAcceptCriticalMessage = TRUE; + } + + // Testing TOS dialog + #if ! LL_RELEASE_FOR_DOWNLOAD + if ( LLStartUp::getStartupState() == STATE_LOGIN_WAIT ) + { + LLStartUp::setStartupState( STATE_LOGIN_SHOW ); + } + else + #endif + + LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication + self->close(); // destroys this object +} + +// static +void LLFloaterTOS::onCancel( void* userdata ) +{ + LLFloaterTOS* self = (LLFloaterTOS*) userdata; + llinfos << "User disagrees with TOS." << llendl; + LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done); + LLStartUp::setStartupState( STATE_LOGIN_SHOW ); + self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS + self->close(); // destroys this object +} + +//virtual +void LLFloaterTOS::onNavigateComplete( const EventType& eventIn ) +{ + // skip past the loading screen navigate complete + if ( ++mLoadCompleteCount == 2 ) + { + llinfos << "NAVIGATE COMPLETE" << llendl; + // enable Agree to TOS radio button now that page has loaded + LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); + tos_agreement->setEnabled( true ); + }; +} diff --git a/linden/indra/newview/llfloaterwater.cpp b/linden/indra/newview/llfloaterwater.cpp index c4b6d0d98..782c56e72 100644 --- a/linden/indra/newview/llfloaterwater.cpp +++ b/linden/indra/newview/llfloaterwater.cpp @@ -64,6 +64,8 @@ #include "llwaterparammanager.h" #include "llpostprocess.h" +#include "wlfloaterwindlightsend.h" + #undef max LLFloaterWater* LLFloaterWater::sWaterMenu = NULL; @@ -680,6 +682,12 @@ void LLFloaterWater::onSavePreset(LLUICtrl* ctrl, void* userData) } } + else if (ctrl->getValue().asString() == "send_to_server_item") + { + //Open the other box + WLFloaterWindLightSend::instance(); + WLFloaterWindLightSend::instance()->open(); + } else { LLWaterParamManager::instance()->mCurParams.mName = diff --git a/linden/indra/newview/llfloaterwindlight.cpp b/linden/indra/newview/llfloaterwindlight.cpp index be3c1fd0a..493723276 100644 --- a/linden/indra/newview/llfloaterwindlight.cpp +++ b/linden/indra/newview/llfloaterwindlight.cpp @@ -63,6 +63,9 @@ #include "llwlparamset.h" #include "llwlparammanager.h" #include "llpostprocess.h" +#include "wlfloaterwindlightsend.h" +#include "llworld.h" +#include "hippolimits.h" #undef max @@ -216,7 +219,9 @@ void LLFloaterWindLight::initCallbacks(void) { childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL); childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL); childSetCommitCallback("WLDistanceMult", onFloatControlMoved, ¶m_mgr->mDistanceMult); - childSetCommitCallback("DrawClassicClouds", LLSavedSettingsGlue::setBOOL, (void*)"SkyUseClassicClouds"); + childSetCommitCallback("DrawClassicClouds", onCloudDrawToggled, NULL); + childSetCommitCallback("WLCloudHeight", onCloudHeightMoved, NULL); + childSetCommitCallback("WLCloudRange", onCloudRangeMoved, NULL); // WL Top childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL); @@ -425,7 +430,21 @@ void LLFloaterWindLight::syncMenu() bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); childSetValue("WLCloudLockX", lockX); childSetValue("WLCloudLockY", lockY); - childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds")); + childSetValue("DrawClassicClouds", gHippoLimits->skyUseClassicClouds); + + childSetValue("WLCloudHeight", gSavedSettings.getF32("ClassicCloudHeight")); + childSetValue("WLCloudRange", gSavedSettings.getF32("ClassicCloudRange")); + + if(!gHippoLimits->skyUseClassicClouds) + { + childDisable("WLCloudHeight"); + childDisable("WLCloudRange"); + } + else + { + childEnable("WLCloudHeight"); + childEnable("WLCloudRange"); + } // disable if locked, enable if not if(lockX) @@ -874,6 +893,12 @@ void LLFloaterWindLight::onSavePreset(LLUICtrl* ctrl, void* userData) } } + else if (ctrl->getValue().asString() == "send_to_server_item") + { + //Open the other box + WLFloaterWindLightSend::instance(); + WLFloaterWindLightSend::instance()->open(); + } else { // check to see if it's a default and shouldn't be overwritten @@ -1046,6 +1071,35 @@ void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData) // *HACK all cloud scrolling is off by an additive of 10. LLWLParamManager::instance()->mCurParams.setCloudScrollY(sldrCtrl->getValueF32() + 10.0f); } +void LLFloaterWindLight::onCloudDrawToggled(LLUICtrl* ctrl, void* userData) +{ + LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl); + + bool lock = cbCtrl->get(); + gHippoLimits->skyUseClassicClouds = lock; + + LLWorld::getInstance()->rebuildClouds(gAgent.getRegion()); +} + +void LLFloaterWindLight::onCloudHeightMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + + gSavedSettings.setF32("ClassicCloudHeight", sldrCtrl->getValueF32()); + + LLWorld::getInstance()->rebuildClouds(gAgent.getRegion()); +} + +void LLFloaterWindLight::onCloudRangeMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); + + gSavedSettings.setF32("ClassicCloudRange", sldrCtrl->getValueF32()); +} void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData) { diff --git a/linden/indra/newview/llfloaterwindlight.h b/linden/indra/newview/llfloaterwindlight.h index b9e53114a..24b0e8798 100644 --- a/linden/indra/newview/llfloaterwindlight.h +++ b/linden/indra/newview/llfloaterwindlight.h @@ -118,6 +118,10 @@ class LLFloaterWindLight : public LLFloater static void onCloudScrollXToggled(LLUICtrl* ctrl, void* userData); static void onCloudScrollYToggled(LLUICtrl* ctrl, void* userData); + static void onCloudDrawToggled(LLUICtrl* ctrl, void* userData); + static void onCloudHeightMoved(LLUICtrl* ctrl, void* userData); + static void onCloudRangeMoved(LLUICtrl* ctrl, void* userData); + //// menu management /// show off our menu diff --git a/linden/indra/newview/llhomelocationresponder.cpp b/linden/indra/newview/llhomelocationresponder.cpp index 3ef58e756..e60923700 100644 --- a/linden/indra/newview/llhomelocationresponder.cpp +++ b/linden/indra/newview/llhomelocationresponder.cpp @@ -100,6 +100,8 @@ void LLHomeLocationResponder::result( const LLSD& content ) LLViewerRegion *viewer_region = gAgent.getRegion(); gAgent.setHomePosRegion( viewer_region->getHandle(), agent_pos ); + gAgent.takeHomeScreenshot(); + } } diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp index 01fe6f8e1..aada65889 100644 --- a/linden/indra/newview/llmaniptranslate.cpp +++ b/linden/indra/newview/llmaniptranslate.cpp @@ -533,7 +533,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) { F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance"); - if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) + if(max_drag_distance < gHippoLimits->getMaxDragDistance()) max_drag_distance = gHippoLimits->getMaxDragDistance(); //Take the more restrictive if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) { lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (too far)" << llendl; gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); diff --git a/linden/indra/newview/llprefschat.cpp b/linden/indra/newview/llprefschat.cpp index 6ebc8809c..8d704d5a3 100644 --- a/linden/indra/newview/llprefschat.cpp +++ b/linden/indra/newview/llprefschat.cpp @@ -72,6 +72,7 @@ class LLPrefsChatImpl : public LLPanel BOOL mShowTimestamps; BOOL mPlayTypingAnim; BOOL mChatBubbles; + BOOL mLocalChatBubbles; BOOL mScriptErrorAsChat; BOOL mChatChannel; F32 mConsoleOpacity; @@ -106,6 +107,7 @@ LLPrefsChatImpl::LLPrefsChatImpl() childSetValue("script_errors_as_chat", gSavedSettings.getBOOL("ScriptErrorsAsChat")); childSetValue("bubble_text_chat", gSavedSettings.getBOOL("UseChatBubbles")); + childSetValue("local_bubble_text_chat", gSavedSettings.getBOOL("UseLocalChatWithBubbles")); childSetValue("chat_full_width_check", gSavedSettings.getBOOL("ChatFullWidth")); childSetValue("close_chat_on_return_check", gSavedSettings.getBOOL("CloseChatOnReturn")); childSetValue("play_typing_animation", gSavedSettings.getBOOL("PlayTypingAnim")); @@ -135,6 +137,7 @@ void LLPrefsChatImpl::refreshValues() mShowTimestamps = gSavedSettings.getBOOL("ChatShowTimestamps"); mScriptErrorAsChat = gSavedSettings.getBOOL("ScriptErrorsAsChat"); mChatBubbles = gSavedSettings.getBOOL("UseChatBubbles"); + mLocalChatBubbles = gSavedSettings.getBOOL("UseLocalChatWithBubbles"); mChatFullWidth = gSavedSettings.getBOOL("ChatFullWidth"); mCloseChatOnReturn = gSavedSettings.getBOOL("CloseChatOnReturn"); mPlayTypingAnim = gSavedSettings.getBOOL("PlayTypingAnim"); @@ -164,6 +167,7 @@ void LLPrefsChatImpl::cancel() gSavedSettings.setBOOL("ChatShowTimestamps", mShowTimestamps); gSavedSettings.setBOOL("ScriptErrorsAsChat", mScriptErrorAsChat); gSavedSettings.setBOOL("UseChatBubbles", mChatBubbles); + gSavedSettings.setBOOL("UseLocalChatWithBubbles", mLocalChatBubbles); gSavedSettings.setBOOL("ChatFullWidth", mChatFullWidth); gSavedSettings.setBOOL("CloseChatOnReturn", mCloseChatOnReturn); gSavedSettings.setBOOL("PlayTypingAnim", mPlayTypingAnim); @@ -196,6 +200,7 @@ void LLPrefsChatImpl::apply() gSavedSettings.setBOOL("ChatShowTimestamps", childGetValue("show_timestamps_check")); gSavedSettings.setBOOL("ScriptErrorsAsChat", childGetValue("script_errors_as_chat")); gSavedSettings.setBOOL("UseChatBubbles", childGetValue("bubble_text_chat")); + gSavedSettings.setBOOL("UseLocalChatWithBubbles", childGetValue("local_bubble_text_chat")); gSavedSettings.setBOOL("ChatFullWidth", childGetValue("chat_full_width_check")); gSavedSettings.setBOOL("CloseChatOnReturn", childGetValue("close_chat_on_return_check")); gSavedSettings.setBOOL("PlayTypingAnim", childGetValue("play_typing_animation")); diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index caaba056d..d736fb0f9 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp @@ -59,6 +59,7 @@ #include "llglheaders.h" #include "lldrawpoolterrain.h" #include "lldrawable.h" +#include "hippolimits.h" extern LLPipeline gPipeline; @@ -295,7 +296,7 @@ void LLSurface::initTextures() // // Water texture // - if (gSavedSettings.getBOOL("RenderWater") ) + if (gSavedSettings.getBOOL("RenderWater") && gHippoLimits->mRenderWater) { createWaterTexture(); mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); @@ -306,6 +307,29 @@ void LLSurface::initTextures() } } +//static +void LLSurface::rebuildWater() +{ + //lldebugs << "Rebuilding Water..."; + if(!mWaterObjp.isNull()) + { + //lldebugs << "Removing Water"; + //Remove the old + gObjectList.killObject(mWaterObjp); + } + + if (gSavedSettings.getBOOL("RenderWater") && gHippoLimits->mRenderWater) + { + //lldebugs << "Building Water"; + createWaterTexture(); + mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp); + gPipeline.createObject(mWaterObjp); + LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle()); + water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); + mWaterObjp->setPositionGlobal(water_pos_global); + } + //lldebugs << "Rebuilding Water Complete"; +} void LLSurface::setOriginGlobal(const LLVector3d &origin_global) { diff --git a/linden/indra/newview/llsurface.h b/linden/indra/newview/llsurface.h index 003b2f250..c217b19a5 100644 --- a/linden/indra/newview/llsurface.h +++ b/linden/indra/newview/llsurface.h @@ -91,6 +91,8 @@ class LLSurface void disconnectNeighbor(LLSurface *neighborp); void disconnectAllNeighbors(); + void rebuildWater(); //Destroys (if nesessary) and then rebuilds (if needed) + virtual void decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch); virtual void updatePatchVisibilities(LLAgent &agent); diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index 2bc6e3ef2..4e133de47 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp @@ -75,6 +75,7 @@ // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] +#include "hippoLimits.h" // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a @@ -1679,8 +1680,10 @@ void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent, LLNotifications::instance().add("IncompleteInventory"); return; } + count = items.count() + cats.count(); - if(count > MAX_ITEMS) + if(count > gHippoLimits->getMaxInventoryItemsTransfer() && + gHippoLimits->getMaxInventoryItemsTransfer() != -1) //MAX_ITEMS) { LLNotifications::instance().add("TooManyItems"); return; @@ -1776,8 +1779,9 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent, // MTUBYTES or 18 * count < 1200 => count < 1200/18 => // 66. I've cut it down a bit from there to give some pad. S32 count = items.count() + cats.count(); - if(count > MAX_ITEMS) - { + if(count > gHippoLimits->getMaxInventoryItemsTransfer() && + gHippoLimits->getMaxInventoryItemsTransfer() != -1) //MAX_ITEMS) + { LLNotifications::instance().add("TooManyItems"); return; } diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index 78940cc30..416746477 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -82,6 +82,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" +#include "hippoLimits.h" // [RLVa:KB] #include "rlvhandler.h" @@ -181,6 +182,12 @@ void display_update_camera() { final_far *= 0.5f; } + if(gAgent.mLockedDrawDistance) + { + //Reset the draw distance and do not update with the new val + final_far = LLViewerCamera::getInstance()->getFar(); + gAgent.mDrawDistance = final_far; + } LLViewerCamera::getInstance()->setFar(final_far); gViewerWindow->setup3DRender(); @@ -305,13 +312,19 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // Update GL Texture statistics (used for discard logic?) // + LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats"); gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); - LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); + S32 RenderName = gSavedSettings.getS32("RenderName"); + + if(RenderName > gHippoLimits->mRenderName)//The most restricted gets set here + RenderName = gHippoLimits->mRenderName; + + LLVOAvatar::sRenderName = RenderName; LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; @@ -835,6 +848,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) //} LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; + + //Check for RenderWater + if (!gSavedSettings.getBOOL("RenderWater") || !gHippoLimits->mRenderWater) + LLPipeline::sUnderWaterRender = FALSE; + LLPipeline::updateRenderDeferred(); stop_glerror(); diff --git a/linden/indra/newview/llviewerinventory.cpp b/linden/indra/newview/llviewerinventory.cpp index 33113f17f..0e06353ab 100644 --- a/linden/indra/newview/llviewerinventory.cpp +++ b/linden/indra/newview/llviewerinventory.cpp @@ -268,7 +268,7 @@ void LLViewerInventoryItem::packMessage(LLMessageSystem* msg) const msg->addU32Fast(_PREHASH_Flags, mFlags); mSaleInfo.packMessage(msg); msg->addStringFast(_PREHASH_Name, mName); - msg->addStringFast(_PREHASH_Description, mDescription); + msg->addStringFast(_PREHASH_Description, mDescription); msg->addS32Fast(_PREHASH_CreationDate, mCreationDate); U32 crc = getCRC32(); msg->addU32Fast(_PREHASH_CRC, crc); diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index d3ca5f6f7..9e7b166d9 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -152,6 +152,7 @@ #include "hippoGridManager.h" #include "hippoLimits.h" +#include "wlsettingsmanager.h" #if LL_WINDOWS // For Windows specific error handler #include "llwindebug.h" // For the invalid message handler @@ -3116,8 +3117,17 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if (!is_muted && !is_busy) { - static BOOL* sUseChatBubbles = rebind_llcontrol<BOOL>("UseChatBubbles", &gSavedSettings, true); - visible_in_chat_bubble = *sUseChatBubbles; + + BOOL sUseChatBubbles = gSavedSettings.getBOOL("UseChatBubbles"); + if(sUseChatBubbles) + { + BOOL localChat = gSavedSettings.getBOOL("UseLocalChatWithBubbles"); + if(localChat) + sUseChatBubbles = FALSE; //Act like they arn't enabled and show it anyway + } + //Update.. + visible_in_chat_bubble = sUseChatBubbles; + ((LLVOAvatar*)chatter)->addChat(chat); } } @@ -3569,6 +3579,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**) // Tell the LightShare handler that we have changed regions. WindlightMessage::resetRegion(); + WLSettingsManager::wlresetRegion(); } // stuff we have to do every time we get an AvatarInitComplete from a sim @@ -3835,6 +3846,7 @@ void process_crossed_region(LLMessageSystem* msg, void**) // Tell the LightShare handler that we have changed regions. WindlightMessage::resetRegion(); + WLSettingsManager::wlresetRegion(); } diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index 4fd3bfb61..b63914c42 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp @@ -452,6 +452,12 @@ void LLViewerRegion::setWaterHeight(F32 water_level) mLandp->setWaterHeight(water_level); } + +void LLViewerRegion::rebuildWater() +{ + mLandp->rebuildWater(); +} + F32 LLViewerRegion::getWaterHeight() const { return mLandp->getWaterHeight(); @@ -1416,7 +1422,9 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLSD capabilityNames = LLSD::emptyArray(); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("DispatchOpenRegionSettings"); capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("DispatchWindLightSettings"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); capabilityNames.append("FetchInventory"); @@ -1434,6 +1442,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RequestTextureDownload"); + capabilityNames.append("RetrieveWindLightSettings"); capabilityNames.append("SearchStatRequest"); capabilityNames.append("SearchStatTracking"); capabilityNames.append("SendPostcard"); diff --git a/linden/indra/newview/llviewerregion.h b/linden/indra/newview/llviewerregion.h index 09280a53f..8cc80e3cf 100644 --- a/linden/indra/newview/llviewerregion.h +++ b/linden/indra/newview/llviewerregion.h @@ -132,6 +132,7 @@ class LLViewerRegion void setWaterHeight(F32 water_level); F32 getWaterHeight() const; + void rebuildWater(); BOOL isVoiceEnabled() const; @@ -315,10 +316,11 @@ class LLViewerRegion LLDynamicArray<U32> mMapAvatars; LLDynamicArray<LLUUID> mMapAvatarIDs; -private: // The surfaces and other layers LLSurface* mLandp; +private: + // Region geometry data LLVector3d mOriginGlobal; // Location of southwest corner of region (meters) LLVector3d mCenterGlobal; // Location of center in world space (meters) diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 9937ed973..a20769ec6 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -94,7 +94,7 @@ #include "boost/lexical_cast.hpp" #endif #include "hippoLimits.h"// getMaxPrimScale - +#include "llstartup.h" // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] @@ -3666,7 +3666,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } // [/RLVa:KB] - BOOL need_comma = FALSE; static BOOL* sShowClientNameTag = rebind_llcontrol<BOOL>("ShowClientNameTag", &gSavedSettings, true); diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index 50ce53a7a..548818dc8 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h @@ -148,6 +148,7 @@ class LLVOAvatar : void clampAttachmentPositions(); S32 getAttachmentCount(); // Warning: order(N) not order(1) + // HUD functions BOOL hasHUDAttachment() const; LLBBox getHUDBBox() const; diff --git a/linden/indra/newview/llwaterparammanager.cpp b/linden/indra/newview/llwaterparammanager.cpp index e01506e94..015662217 100644 --- a/linden/indra/newview/llwaterparammanager.cpp +++ b/linden/indra/newview/llwaterparammanager.cpp @@ -75,6 +75,7 @@ #include "curl/curl.h" LLWaterParamManager * LLWaterParamManager::sInstance = NULL; +LLFrameTimer waterSmoothTransitionTimer; LLWaterParamManager::LLWaterParamManager() : mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"), @@ -454,9 +455,44 @@ void LLWaterParamManager::update(LLViewerCamera * cam) shaders_iter->mUniformsDirty = TRUE; } } + //Mix windlight settings if needed + if(sNeedsMix == TRUE) + { + if(sMixSet == NULL) + { + sNeedsMix = FALSE; + return; + } + if (waterSmoothTransitionTimer.getElapsedTimeF32() >= + (sMixTime / 100)) //100 steps inbetween + { + waterSmoothTransitionTimer.reset(); + mCurParams.mix(mCurParams, *sMixSet, sMixCount / 100);//.01 to 1.0 + } + sMixCount++; + if((sMixCount / 100) == 1) + { + //All done + sNeedsMix = FALSE; + std::string wlWaterPresetName = "(Region settings)"; + mCurParams.mName = wlWaterPresetName; + removeParamSet( wlWaterPresetName, true ); + addParamSet( wlWaterPresetName, mCurParams ); + savePreset( wlWaterPresetName ); + loadPreset( wlWaterPresetName, true ); + sMixSet = NULL; + } + } } } - +void LLWaterParamManager::SetMixTime(LLWaterParamSet *mixSet, F32 mixTime) +{ + waterSmoothTransitionTimer.reset(); + sNeedsMix = TRUE; + sMixSet = mixSet; + sMixTime = mixTime; + sMixCount = 1; +} // static void LLWaterParamManager::initClass(void) { diff --git a/linden/indra/newview/llwaterparammanager.h b/linden/indra/newview/llwaterparammanager.h index 588e43689..96dd1aa28 100644 --- a/linden/indra/newview/llwaterparammanager.h +++ b/linden/indra/newview/llwaterparammanager.h @@ -304,6 +304,8 @@ class LLWaterParamManager // singleton pattern implementation static LLWaterParamManager * instance(); + void SetMixTime(LLWaterParamSet* mixSet, F32 mixTime); + public: LLWaterParamSet mCurParams; @@ -334,6 +336,11 @@ class LLWaterParamManager LLVector4 mWaterPlane; F32 mWaterFogKS; + BOOL sNeedsMix; + LLWaterParamSet* sMixSet; + F32 sMixTime; + F32 sMixCount; + // our parameter manager singleton instance static LLWaterParamManager * sInstance; diff --git a/linden/indra/newview/llwaterparamset.cpp b/linden/indra/newview/llwaterparamset.cpp index a26ccedfb..4b2e42608 100644 --- a/linden/indra/newview/llwaterparamset.cpp +++ b/linden/indra/newview/llwaterparamset.cpp @@ -229,4 +229,96 @@ F32 LLWaterParamSet::getFloat(const std::string& paramName, bool& error) error = true; return 0; } +void LLWaterParamSet::mix(LLWaterParamSet& src, LLWaterParamSet& dest, F32 weight) +{ + // set up the iterators + LLSD::map_iterator cIt = mParamValues.beginMap(); + + LLSD srcVal; + LLSD destVal; + + // do the interpolation for all the ones saved as vectors + // skip the weird ones + for(; cIt != mParamValues.endMap(); cIt++) { + + // check params to make sure they're actually there + if(src.mParamValues.has(cIt->first)) + { + srcVal = src.mParamValues[cIt->first]; + } + else + { + continue; + } + + if(dest.mParamValues.has(cIt->first)) + { + destVal = dest.mParamValues[cIt->first]; + } + else + { + continue; + } + + // skip if not a vector + if(!cIt->second.isArray()) + { + continue; + } + + // only Real vectors allowed + if(!cIt->second[0].isReal()) + { + continue; + } + + // make sure all the same size + if( cIt->second.size() != srcVal.size() || + cIt->second.size() != destVal.size()) + { + continue; + } + + // more error checking might be necessary; + + for(int i=0; i < cIt->second.size(); ++i) + { + cIt->second[i] = (1.0f - weight) * (F32) srcVal[i].asReal() + + weight * (F32) destVal[i].asReal(); + } + } + mParamValues["waterFogColor"][0] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][0].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][0].asReal(); + mParamValues["waterFogColor"][1] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][1].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][1].asReal(); + mParamValues["waterFogColor"][2] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][2].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][2].asReal(); + mParamValues["waterFogColor"][3] = (1 - weight) * (F32) src.mParamValues["waterFogColor"][3].asReal() + + weight * (F32) dest.mParamValues["waterFogColor"][3].asReal(); + + mParamValues["waterFogDensity"] = (1 - weight) * (F32) src.mParamValues["waterFogDensity"].asReal() + + weight * (F32) dest.mParamValues["waterFogDensity"].asReal(); + mParamValues["underWaterFogMod"] = (1 - weight) * (F32) src.mParamValues["underWaterFogMod"].asReal() + + weight * (F32) dest.mParamValues["underWaterFogMod"].asReal(); + mParamValues["fresnelScale"] = (1 - weight) * (F32) src.mParamValues["fresnelScale"].asReal() + + weight * (F32) dest.mParamValues["fresnelScale"].asReal(); + mParamValues["fresnelOffset"] = (1 - weight) * (F32) src.mParamValues["fresnelOffset"].asReal() + + weight * (F32) dest.mParamValues["fresnelOffset"].asReal(); + mParamValues["scaleAbove"] = (1 - weight) * (F32) src.mParamValues["scaleAbove"].asReal() + + weight * (F32) dest.mParamValues["scaleAbove"].asReal(); + mParamValues["scaleBelow"] = (1 - weight) * (F32) src.mParamValues["scaleBelow"].asReal() + + weight * (F32) dest.mParamValues["scaleBelow"].asReal(); + mParamValues["blurMultiplier"] = (1 - weight) * (F32) src.mParamValues["blurMultiplier"].asReal() + + weight * (F32) dest.mParamValues["blurMultiplier"].asReal(); + + mParamValues["wave2Dir"][0] = (1 - weight) * (F32) src.mParamValues["wave2Dir"][0].asReal() + + weight * (F32) dest.mParamValues["wave2Dir"][0].asReal(); + mParamValues["wave2Dir"][1] = (1 - weight) * (F32) src.mParamValues["wave2Dir"][1].asReal() + + weight * (F32) dest.mParamValues["wave2Dir"][1].asReal(); + + mParamValues["wave1Dir"][0] = (1 - weight) * (F32) src.mParamValues["wave1Dir"][0].asReal() + + weight * (F32) dest.mParamValues["wave1Dir"][0].asReal(); + mParamValues["wave1Dir"][1] = (1 - weight) * (F32) src.mParamValues["wave1Dir"][1].asReal() + + weight * (F32) dest.mParamValues["wave1Dir"][1].asReal(); +} diff --git a/linden/indra/newview/llwlparammanager.cpp b/linden/indra/newview/llwlparammanager.cpp index 31471d77c..8007cceed 100644 --- a/linden/indra/newview/llwlparammanager.cpp +++ b/linden/indra/newview/llwlparammanager.cpp @@ -71,11 +71,13 @@ #include "llviewerinventory.h" #include "llviewerregion.h" #include "llassetuploadresponders.h" +#include "llframetimer.h" #include "curl/curl.h" LLWLParamManager * LLWLParamManager::sInstance = NULL; std::vector<LLWLPresetsObserver*> LLWLParamManager::sObservers; +LLFrameTimer wlSmoothTransitionTimer; LLWLParamManager::LLWLParamManager() : @@ -562,6 +564,46 @@ void LLWLParamManager::update(LLViewerCamera * cam) } } } + + //Mix windlight settings if needed + if(sNeedsMix == TRUE) + { + if(sMixSet == NULL) + { + sNeedsMix = FALSE; + return; + } + if (wlSmoothTransitionTimer.getElapsedTimeF32() >= + (sMixTime / 100)) //100 steps inbetween + { + wlSmoothTransitionTimer.reset(); + mCurParams.mix(mCurParams, *sMixSet, sMixCount / 100);//.01 to 1.0 + } + sMixCount++; + if((sMixCount / 100) == 1) + { + //All done + sNeedsMix = FALSE; + std::string wlSkyPresetName = "(Region settings)"; + mCurParams.mName = wlSkyPresetName; + removeParamSet( wlSkyPresetName, true ); + addParamSet( wlSkyPresetName, mCurParams ); + savePreset( wlSkyPresetName ); + mAnimator.mIsRunning = false; + mAnimator.mUseLindenTime = false; + loadPreset( wlSkyPresetName, true ); + sMixSet = NULL; + } + } +} + +void LLWLParamManager::SetMixTime(LLWLParamSet *mixSet, F32 mixTime) +{ + wlSmoothTransitionTimer.reset(); + sNeedsMix = TRUE; + sMixSet = mixSet; + sMixTime = mixTime; + sMixCount = 1; } // static diff --git a/linden/indra/newview/llwlparammanager.h b/linden/indra/newview/llwlparammanager.h index 612a5079f..fc1127e02 100644 --- a/linden/indra/newview/llwlparammanager.h +++ b/linden/indra/newview/llwlparammanager.h @@ -221,6 +221,8 @@ class LLWLParamManager static void removeObserver(LLWLPresetsObserver* observer); static void notifyObservers(); + void SetMixTime(LLWLParamSet* mixSet, F32 mixTime); + public: // helper variables @@ -280,6 +282,11 @@ class LLWLParamManager private: // our parameter manager singleton instance static LLWLParamManager * sInstance; + + BOOL sNeedsMix; + LLWLParamSet* sMixSet; + F32 sMixTime; + F32 sMixCount; static std::vector<LLWLPresetsObserver*> sObservers; diff --git a/linden/indra/newview/llwlparamset.cpp b/linden/indra/newview/llwlparamset.cpp index ea9c00ae8..19528eb25 100644 --- a/linden/indra/newview/llwlparamset.cpp +++ b/linden/indra/newview/llwlparamset.cpp @@ -145,6 +145,11 @@ void LLWLParamSet::set(const std::string& paramName, float x) { mParamValues[paramName][0] = x; } + else + { + //Default this + mParamValues[paramName] = x; + } } void LLWLParamSet::set(const std::string& paramName, float x, float y) { diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp index ca8ce2d9e..c484462ab 100644 --- a/linden/indra/newview/llworld.cpp +++ b/linden/indra/newview/llworld.cpp @@ -669,7 +669,8 @@ void LLWorld::updateClouds(const F32 dt) { static BOOL* sFreezeTime = rebind_llcontrol<BOOL>("FreezeTime", &gSavedSettings, true); if ((*sFreezeTime) || - !gSavedSettings.getBOOL("SkyUseClassicClouds")) + !gSavedSettings.getBOOL("SkyUseClassicClouds") || + !gHippoLimits->skyUseClassicClouds) { // don't move clouds in snapshot mode return; @@ -830,6 +831,14 @@ void LLWorld::setLandFarClip(const F32 far_clip) } } +void LLWorld::rebuildClouds(LLViewerRegion *regionp) +{ + regionp->mCloudLayer.destroy(); + regionp->mCloudLayer.create(regionp); + regionp->mCloudLayer.setWidth((F32)mWidth); + regionp->mCloudLayer.setWindPointer(®ionp->mWind); +} + // Some region that we're connected to, but not the one we're in, gave us // a (possibly) new water height. Update it in our local copy. void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_height) diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h index 2c5815cde..964729d49 100644 --- a/linden/indra/newview/llworld.h +++ b/linden/indra/newview/llworld.h @@ -150,6 +150,8 @@ class LLWorld : public LLSingleton<LLWorld> void getInfo(LLSD& info); + void rebuildClouds(LLViewerRegion *regionp); + public: typedef std::list<LLViewerRegion*> region_list_t; const region_list_t& getRegionList() const { return mActiveRegionList; } diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index cf766e0f1..29328657b 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -101,6 +101,7 @@ #include "llwaterparammanager.h" #include "llspatialpartition.h" #include "llmutelist.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" @@ -5980,6 +5981,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) stop_glerror(); LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE; + + if (!gSavedSettings.getBOOL("RenderWater") || !gHippoLimits->mRenderWater) + LLPipeline::sUnderWaterRender = FALSE; if (LLPipeline::sUnderWaterRender) { diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml b/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml index 0e5a64245..cd88c2ee3 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml @@ -58,7 +58,7 @@ font="SansSerif" mouse_opaque="true" name="Refresh" scale_image="TRUE" /> <slider bottom_delta="-20" left="10" follows="left|top" width="175" height="15" name="near_me_range" label="Range" control_name="NearMeRange" - min_val="5" max_val="40" increment="1" initial_val="20" decimal_digits="0" /> + min_val="5" max_val="512" increment="1" initial_val="20" decimal_digits="0" /> <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom_delta="0" left="185" drop_shadow_visible="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="15" diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_env_settings.xml b/linden/indra/newview/skins/default/xui/en-us/floater_env_settings.xml index e2bafbf81..0a4f2a9dd 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_env_settings.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_env_settings.xml @@ -58,9 +58,11 @@ <button bottom="-140" follows="left|top" font="SansSerifSmall" height="20" label="Use Estate Time" left="8" name="EnvUseEstateTimeButton" width="137" /> <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="20" - label="Advanced Sky" left="154" name="EnvAdvancedSkyButton" width="137" /> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="20" - label="Advanced Water" left="300" name="EnvAdvancedWaterButton" width="137" /> - <button bottom="-40" follows="left|top" font="SansSerif" height="18" label="?" + label="Advanced Sky" left="154" name="EnvAdvancedSkyButton" width="107" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="20" + label="Advanced Water" left="270" name="EnvAdvancedWaterButton" width="137" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="20" + label="Advanced WindLight Manager" left="416" name="EnvWLManager" width="177" /> + <button bottom="-40" follows="left|top" font="SansSerif" height="18" label="?" left="570" name="EnvSettingsHelpButton" width="22" /> </floater> diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml b/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml index 82a65b8c6..0175508c1 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml @@ -5,7 +5,7 @@ embedded_items="false" enabled="true" follows="left|top|right|bottom" font="Monospace" height="376" ignore_tab="false" left="4" max_length="65536" mouse_opaque="true" name="Script Editor" width="492" border_drop_shadow_visible="false" border_visible="false" bevel_style="none" border_style="line" border_thickness="0" - word_wrap="true" show_line_numbers="true"> + word_wrap="true" show_line_numbers="true" spell_check="false"> Loading... </text_editor> <button bottom="-499" enabled="true" follows="right|bottom" font="SansSerif" diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tos.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tos.xml index 485cfcc27..beea02fa9 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tos.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tos.xml @@ -15,15 +15,14 @@ bottom="-50" drop_shadow_visible="true" follows="left|top" font="SansSerif" h_pad="0" halign="left" height="30" left="16" mouse_opaque="true" name="tos_heading" v_pad="0" width="552"> - Please read the following Terms of Service carefully. To continue logging in to Second Life, -you must accept the agreement. + Please read the following Terms of Service carefully. To continue logging in you must accept the agreement. </text> - <text_editor bottom="-376" embedded_items="false" follows="left|top" font="SansSerif" + <text_editor bottom="-376" embedded_items="false" follows="left|top" font="SansSerif" height="283" left="16" max_length="65536" mouse_opaque="true" name="tos_text" width="568" word_wrap="true"> - TOS_TEXT - </text_editor> + TOS_TEXT + </text_editor> <!-- Loading text says: "Loading Terms of Service..." URL encoded --> <web_browser bottom="-406" embedded_items="false" follows="left|top" font="SansSerif" height="340" left="16" max_length="65536" mouse_opaque="true" diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_water.xml b/linden/indra/newview/skins/default/xui/en-us/floater_water.xml index 441ce7b85..a05deb6f1 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_water.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_water.xml @@ -1,273 +1,276 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater bottom="-150" can_close="true" can_drag_on_left="false" can_minimize="true" - can_resize="false" height="240" left="50" min_height="200" - min_width="400" mouse_opaque="true" name="Water Floater" - rect_control="FloaterAdvancedWaterRect" title="Advanced Water Editor" - width="700"> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-50" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="10" mouse_opaque="true" name="KeyFramePresetsText" v_pad="0" - width="110"> - Water Presets: - </text> - <combo_box allow_text_entry="false" bottom="-52" follows="left|top" height="18" - left_delta="120" max_chars="20" mouse_opaque="true" - name="WaterPresetsCombo" width="150" /> - <button bottom="-53" enabled="true" font="SansSerif" halign="center" height="20" - label="" label_selected="" left_delta="-25" image_overlay="arrow_left.tga" - mouse_opaque="true" name="prev" scale_image="true" width="20" /> - <button bottom="-53" enabled="true" font="SansSerif" halign="center" height="20" - label="" label_selected="" left_delta="180" image_overlay="arrow_right.tga" - mouse_opaque="true" name="next" scale_image="true" width="20" /> - <button bottom="-53" enabled="true" font="SansSerif" halign="center" height="20" - label="New" right="-270" - mouse_opaque="true" name="WaterNewPreset" scale_image="true" width="100" /> - <flyout_button bottom_delta="0" follows="left|top" height="20" label="Save to Disk" - right="-140" halign="center" list_position="above" enabled="true" - mouse_opaque="true" width="125" name="WaterSavePreset"> - <flyout_button_item value="save_inventory_item" name="save_inventory_item"> - Save to Inventory - </flyout_button_item> - <flyout_button_item value="save_disk_item" name="save_disk_item"> - Save to Disk - </flyout_button_item> - </flyout_button> - <button bottom_delta="0" enabled="true" font="SansSerif" halign="center" height="20" - label="Delete File" label_selected="Delete File" right="-10" - mouse_opaque="true" name="WaterDeletePreset" scale_image="true" width="125" /> - <tab_container bottom="-240" follows="left|top" height="180" left="0" - mouse_opaque="false" name="Water Tabs" tab_position="top" width="700"> - <panel border="true" bottom="-240" follows="left|top|right|bottom" height="180" - label="Settings" left="1" mouse_opaque="false" - name="Settings" width="698"> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-20" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="10" mouse_opaque="true" name="BHText" v_pad="0" width="355"> - Water Fog Color - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="160" name="WaterFogColorHelp" width="18" /> - <color_swatch border_color="0.45098, 0.517647, 0.607843, 1" bottom="-80" - can_apply_immediately="true" color="0.5, 0.5, 0.5, 1" follows="left|top" - height="50" label="" left="40" mouse_opaque="true" - name="WaterFogColor" tool_tip="Click to open Color Picker" width="40" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-90" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="10" mouse_opaque="true" name="WaterFogDensText" v_pad="0" width="355"> - Fog Density Exponent - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="160" name="WaterFogDensityHelp" width="18" /> - <slider bottom_delta="-30" can_edit_text="false" control_name="WaterFogDensity" - decimal_digits="1" follows="left" height="10" increment=".1" - initial_val="16" label="" left="24" max_val="10" min_val="0" - mouse_opaque="true" name="WaterFogDensity" show_text="true" value="1.0" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-130" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="10" mouse_opaque="true" name="WaterUnderWaterFogModText" v_pad="0" - width="355"> - Underwater Fog Modifier - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="160" name="WaterUnderWaterFogModHelp" width="18" /> - <slider bottom_delta="-30" can_edit_text="false" control_name="" decimal_digits="2" - follows="left" height="10" increment=".01" initial_val="16" label="" - left="24" max_val="2" min_val="0" mouse_opaque="true" - name="WaterUnderWaterFogMod" show_text="true" value="0.25" width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-20" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="245" mouse_opaque="true" name="BDensText" v_pad="0" width="355"> - Reflection Wavelet Scale - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="395" name="WaterNormalScaleHelp" width="18" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-37" drop_shadow_visible="true" follows="left|top|right" - font="SansSerifSmall" h_pad="0" halign="center" height="16" - left="245" mouse_opaque="true" name="BHText2" v_pad="0" width="10"> - 1 - </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" - font="SansSerifSmall" h_pad="0" halign="center" height="16" - left_delta="0" mouse_opaque="true" name="BHText3" v_pad="0" width="10"> - 2 - </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" - font="SansSerifSmall" h_pad="0" halign="center" height="16" - left_delta="0" mouse_opaque="true" name="BHText4" v_pad="0" width="10"> - 3 - </text> - <slider bottom="-50" can_edit_text="false" control_name="WaterNormalScaleX" - decimal_digits="1" follows="left" height="10" increment="0.1" - initial_val="0.7" label="" left="259" max_val="10" min_val="0" - mouse_opaque="true" name="WaterNormalScaleX" show_text="true" value="1.0" - width="200" /> - <slider bottom_delta="-11" can_edit_text="false" control_name="WaterNormalScaleY" - decimal_digits="1" follows="left" height="10" increment="0.1" - initial_val="0.7" label="" left="259" max_val="10" min_val="0" - mouse_opaque="true" name="WaterNormalScaleY" show_text="true" value="1.0" - width="200" /> - <slider bottom_delta="-11" can_edit_text="false" control_name="WaterNormalScaleZ" - decimal_digits="1" follows="left" height="10" increment="0.1" - initial_val="0.7" label="" left="259" max_val="10" min_val="0" - mouse_opaque="true" name="WaterNormalScaleZ" show_text="true" value="1.0" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-80" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="245" mouse_opaque="true" name="HDText" v_pad="0" width="355"> - Fresnel Scale - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="395" name="WaterFresnelScaleHelp" width="18" /> - <slider bottom_delta="-30" can_edit_text="false" control_name="WaterFresnelScale" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0.7" label="" left="259" max_val="1" min_val="0" - mouse_opaque="true" name="WaterFresnelScale" show_text="true" value="1.0" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-115" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="245" mouse_opaque="true" name="FresnelOffsetText" v_pad="0" - width="355"> - Fresnel Offset - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="395" name="WaterFresnelOffsetHelp" width="18" /> - <slider bottom_delta="-30" can_edit_text="false" control_name="WaterFresnelOffset" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0.7" label="" left="259" max_val="1" min_val="0" - mouse_opaque="true" name="WaterFresnelOffset" show_text="true" value="1.0" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-20" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="480" mouse_opaque="true" name="DensMultText" v_pad="0" width="355"> - Refract Scale Above - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="630" name="WaterScaleAboveHelp" width="18" /> - <slider bottom_delta="-30" can_edit_text="false" control_name="WaterScaleAbove" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0.1" label="" left="494" max_val="1" min_val="0" - mouse_opaque="true" name="WaterScaleAbove" show_text="true" value="1.0" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-53" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="480" mouse_opaque="true" name="WaterScaleBelowText" v_pad="0" - width="355"> - Refract Scale Below - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="630" name="WaterScaleBelowHelp" width="18" /> - <slider bottom_delta="-30" can_edit_text="false" control_name="WaterScaleBelow" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0" label="" left="494" max_val="1" min_val="0" - mouse_opaque="true" name="WaterScaleBelow" show_text="true" value="0.0" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-87" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="480" mouse_opaque="true" name="MaxAltText" v_pad="0" width="355"> - Blur Multiplier - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="630" name="WaterBlurMultiplierHelp" width="18" /> - <slider bottom_delta="-30" can_edit_text="false" control_name="WaterBlurMult" - decimal_digits="3" follows="left" height="10" increment=".001" - initial_val="0" label="" left="494" max_val=".16" min_val="0" - mouse_opaque="true" name="WaterBlurMult" show_text="true" value="0" - width="200" /> - </panel> - <panel border="true" bottom="-240" follows="left|top|right|bottom" height="180" - label="Image" left="1" mouse_opaque="false" name="Waves" - width="698"> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-20" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="10" mouse_opaque="true" name="BHText" v_pad="0" width="355"> - Big Wave Direction - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="155" name="WaterWave1Help" width="18" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-37" drop_shadow_visible="true" follows="left|top|right" - font="SansSerifSmall" h_pad="0" halign="center" height="16" - left="10" mouse_opaque="true" name="WaterWave1DirXText" v_pad="0" - width="10"> - X - </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" - font="SansSerifSmall" h_pad="0" halign="center" height="16" - left_delta="0" mouse_opaque="true" name="WaterWave1DirYText" v_pad="0" - width="10"> - Y - </text> - <slider bottom="-50" can_edit_text="false" control_name="WaterWave1DirX" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0.7" label="" left="24" max_val="4" min_val="-4" - mouse_opaque="true" name="WaterWave1DirX" show_text="true" value="0.7" - width="200" /> - <slider bottom_delta="-11" can_edit_text="false" control_name="WaterWave1DirY" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0.7" label="" left="24" max_val="4" min_val="-4" - mouse_opaque="true" name="WaterWave1DirY" show_text="true" value="0.7" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-70" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="10" mouse_opaque="true" name="BHText2" v_pad="0" width="355"> - Little Wave Direction - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="155" name="WaterWave2Help" width="18" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-87" drop_shadow_visible="true" follows="left|top|right" - font="SansSerifSmall" h_pad="0" halign="center" height="16" - left="10" mouse_opaque="true" name="WaterWave2DirXText" v_pad="0" - width="10"> - X - </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" - font="SansSerifSmall" h_pad="0" halign="center" height="16" - left_delta="0" mouse_opaque="true" name="WaterWave2DirYText" v_pad="0" - width="10"> - Y - </text> - <slider bottom="-100" can_edit_text="false" control_name="WaterWave2DirX" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0.7" label="" left="24" max_val="4" min_val="-4" - mouse_opaque="true" name="WaterWave2DirX" show_text="true" value="0.7" - width="200" /> - <slider bottom_delta="-11" can_edit_text="false" control_name="WaterWave2DirY" - decimal_digits="2" follows="left" height="10" increment="0.01" - initial_val="0.7" label="" left="24" max_val="4" min_val="-4" - mouse_opaque="true" name="WaterWave2DirY" show_text="true" value="0.7" - width="200" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-20" drop_shadow_visible="true" follows="left|top|right" - font="SansSerif" h_pad="0" halign="left" height="16" - left="240" mouse_opaque="true" name="BHText3" v_pad="0" width="355"> - Normal Map - </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" - left="365" name="WaterNormalMapHelp" width="18" /> - <texture_picker bottom="-165" height="143" label="" left="250" name="WaterNormalMap" - width="128" /> - </panel> - </tab_container> - <string name="WLDefaultWaterNames"> - Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez - </string> -</floater> +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater bottom="-150" can_close="true" can_drag_on_left="false" can_minimize="true" + can_resize="false" height="240" left="50" min_height="200" + min_width="400" mouse_opaque="true" name="Water Floater" + rect_control="FloaterAdvancedWaterRect" title="Advanced Water Editor" + width="700"> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-50" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="10" mouse_opaque="true" name="KeyFramePresetsText" v_pad="0" + width="110"> + Water Presets: + </text> + <combo_box allow_text_entry="false" bottom="-52" follows="left|top" height="18" + left_delta="120" max_chars="20" mouse_opaque="true" + name="WaterPresetsCombo" width="150" /> + <button bottom="-53" enabled="true" font="SansSerif" halign="center" height="20" + label="" label_selected="" left_delta="-25" image_overlay="arrow_left.tga" + mouse_opaque="true" name="prev" scale_image="true" width="20" /> + <button bottom="-53" enabled="true" font="SansSerif" halign="center" height="20" + label="" label_selected="" left_delta="180" image_overlay="arrow_right.tga" + mouse_opaque="true" name="next" scale_image="true" width="20" /> + <button bottom="-53" enabled="true" font="SansSerif" halign="center" height="20" + label="New" right="-270" + mouse_opaque="true" name="WaterNewPreset" scale_image="true" width="100" /> + <flyout_button bottom_delta="0" follows="left|top" height="20" label="Save to Disk" + right="-140" halign="center" list_position="above" enabled="true" + mouse_opaque="true" width="125" name="WaterSavePreset"> + <flyout_button_item value="save_inventory_item" name="save_inventory_item"> + Save to Inventory + </flyout_button_item> + <flyout_button_item value="save_disk_item" name="save_disk_item"> + Save to Disk + </flyout_button_item> + <flyout_button_item value="send_to_server_item" name="send_to_server_item"> + Send to Server + </flyout_button_item> + </flyout_button> + <button bottom_delta="0" enabled="true" font="SansSerif" halign="center" height="20" + label="Delete File" label_selected="Delete File" right="-10" + mouse_opaque="true" name="WaterDeletePreset" scale_image="true" width="125" /> + <tab_container bottom="-240" follows="left|top" height="180" left="0" + mouse_opaque="false" name="Water Tabs" tab_position="top" width="700"> + <panel border="true" bottom="-240" follows="left|top|right|bottom" height="180" + label="Settings" left="1" mouse_opaque="false" + name="Settings" width="698"> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-20" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="10" mouse_opaque="true" name="BHText" v_pad="0" width="355"> + Water Fog Color + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="160" name="WaterFogColorHelp" width="18" /> + <color_swatch border_color="0.45098, 0.517647, 0.607843, 1" bottom="-80" + can_apply_immediately="true" color="0.5, 0.5, 0.5, 1" follows="left|top" + height="50" label="" left="40" mouse_opaque="true" + name="WaterFogColor" tool_tip="Click to open Color Picker" width="40" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-90" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="10" mouse_opaque="true" name="WaterFogDensText" v_pad="0" width="355"> + Fog Density Exponent + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="160" name="WaterFogDensityHelp" width="18" /> + <slider bottom_delta="-30" can_edit_text="false" control_name="WaterFogDensity" + decimal_digits="1" follows="left" height="10" increment=".1" + initial_val="16" label="" left="24" max_val="10" min_val="0" + mouse_opaque="true" name="WaterFogDensity" show_text="true" value="1.0" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-130" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="10" mouse_opaque="true" name="WaterUnderWaterFogModText" v_pad="0" + width="355"> + Underwater Fog Modifier + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="160" name="WaterUnderWaterFogModHelp" width="18" /> + <slider bottom_delta="-30" can_edit_text="false" control_name="" decimal_digits="2" + follows="left" height="10" increment=".01" initial_val="16" label="" + left="24" max_val="2" min_val="0" mouse_opaque="true" + name="WaterUnderWaterFogMod" show_text="true" value="0.25" width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-20" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="245" mouse_opaque="true" name="BDensText" v_pad="0" width="355"> + Reflection Wavelet Scale + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="395" name="WaterNormalScaleHelp" width="18" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-37" drop_shadow_visible="true" follows="left|top|right" + font="SansSerifSmall" h_pad="0" halign="center" height="16" + left="245" mouse_opaque="true" name="BHText2" v_pad="0" width="10"> + 1 + </text> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" + font="SansSerifSmall" h_pad="0" halign="center" height="16" + left_delta="0" mouse_opaque="true" name="BHText3" v_pad="0" width="10"> + 2 + </text> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" + font="SansSerifSmall" h_pad="0" halign="center" height="16" + left_delta="0" mouse_opaque="true" name="BHText4" v_pad="0" width="10"> + 3 + </text> + <slider bottom="-50" can_edit_text="false" control_name="WaterNormalScaleX" + decimal_digits="1" follows="left" height="10" increment="0.1" + initial_val="0.7" label="" left="259" max_val="10" min_val="0" + mouse_opaque="true" name="WaterNormalScaleX" show_text="true" value="1.0" + width="200" /> + <slider bottom_delta="-11" can_edit_text="false" control_name="WaterNormalScaleY" + decimal_digits="1" follows="left" height="10" increment="0.1" + initial_val="0.7" label="" left="259" max_val="10" min_val="0" + mouse_opaque="true" name="WaterNormalScaleY" show_text="true" value="1.0" + width="200" /> + <slider bottom_delta="-11" can_edit_text="false" control_name="WaterNormalScaleZ" + decimal_digits="1" follows="left" height="10" increment="0.1" + initial_val="0.7" label="" left="259" max_val="10" min_val="0" + mouse_opaque="true" name="WaterNormalScaleZ" show_text="true" value="1.0" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-80" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="245" mouse_opaque="true" name="HDText" v_pad="0" width="355"> + Fresnel Scale + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="395" name="WaterFresnelScaleHelp" width="18" /> + <slider bottom_delta="-30" can_edit_text="false" control_name="WaterFresnelScale" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0.7" label="" left="259" max_val="1" min_val="0" + mouse_opaque="true" name="WaterFresnelScale" show_text="true" value="1.0" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-115" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="245" mouse_opaque="true" name="FresnelOffsetText" v_pad="0" + width="355"> + Fresnel Offset + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="395" name="WaterFresnelOffsetHelp" width="18" /> + <slider bottom_delta="-30" can_edit_text="false" control_name="WaterFresnelOffset" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0.7" label="" left="259" max_val="1" min_val="0" + mouse_opaque="true" name="WaterFresnelOffset" show_text="true" value="1.0" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-20" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="480" mouse_opaque="true" name="DensMultText" v_pad="0" width="355"> + Refract Scale Above + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="630" name="WaterScaleAboveHelp" width="18" /> + <slider bottom_delta="-30" can_edit_text="false" control_name="WaterScaleAbove" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0.1" label="" left="494" max_val="1" min_val="0" + mouse_opaque="true" name="WaterScaleAbove" show_text="true" value="1.0" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-53" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="480" mouse_opaque="true" name="WaterScaleBelowText" v_pad="0" + width="355"> + Refract Scale Below + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="630" name="WaterScaleBelowHelp" width="18" /> + <slider bottom_delta="-30" can_edit_text="false" control_name="WaterScaleBelow" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0" label="" left="494" max_val="1" min_val="0" + mouse_opaque="true" name="WaterScaleBelow" show_text="true" value="0.0" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-87" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="480" mouse_opaque="true" name="MaxAltText" v_pad="0" width="355"> + Blur Multiplier + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="630" name="WaterBlurMultiplierHelp" width="18" /> + <slider bottom_delta="-30" can_edit_text="false" control_name="WaterBlurMult" + decimal_digits="3" follows="left" height="10" increment=".001" + initial_val="0" label="" left="494" max_val=".16" min_val="0" + mouse_opaque="true" name="WaterBlurMult" show_text="true" value="0" + width="200" /> + </panel> + <panel border="true" bottom="-240" follows="left|top|right|bottom" height="180" + label="Image" left="1" mouse_opaque="false" name="Waves" + width="698"> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-20" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="10" mouse_opaque="true" name="BHText" v_pad="0" width="355"> + Big Wave Direction + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="155" name="WaterWave1Help" width="18" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-37" drop_shadow_visible="true" follows="left|top|right" + font="SansSerifSmall" h_pad="0" halign="center" height="16" + left="10" mouse_opaque="true" name="WaterWave1DirXText" v_pad="0" + width="10"> + X + </text> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" + font="SansSerifSmall" h_pad="0" halign="center" height="16" + left_delta="0" mouse_opaque="true" name="WaterWave1DirYText" v_pad="0" + width="10"> + Y + </text> + <slider bottom="-50" can_edit_text="false" control_name="WaterWave1DirX" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0.7" label="" left="24" max_val="4" min_val="-4" + mouse_opaque="true" name="WaterWave1DirX" show_text="true" value="0.7" + width="200" /> + <slider bottom_delta="-11" can_edit_text="false" control_name="WaterWave1DirY" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0.7" label="" left="24" max_val="4" min_val="-4" + mouse_opaque="true" name="WaterWave1DirY" show_text="true" value="0.7" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-70" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="10" mouse_opaque="true" name="BHText2" v_pad="0" width="355"> + Little Wave Direction + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="155" name="WaterWave2Help" width="18" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-87" drop_shadow_visible="true" follows="left|top|right" + font="SansSerifSmall" h_pad="0" halign="center" height="16" + left="10" mouse_opaque="true" name="WaterWave2DirXText" v_pad="0" + width="10"> + X + </text> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-11" drop_shadow_visible="true" follows="left|top|right" + font="SansSerifSmall" h_pad="0" halign="center" height="16" + left_delta="0" mouse_opaque="true" name="WaterWave2DirYText" v_pad="0" + width="10"> + Y + </text> + <slider bottom="-100" can_edit_text="false" control_name="WaterWave2DirX" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0.7" label="" left="24" max_val="4" min_val="-4" + mouse_opaque="true" name="WaterWave2DirX" show_text="true" value="0.7" + width="200" /> + <slider bottom_delta="-11" can_edit_text="false" control_name="WaterWave2DirY" + decimal_digits="2" follows="left" height="10" increment="0.01" + initial_val="0.7" label="" left="24" max_val="4" min_val="-4" + mouse_opaque="true" name="WaterWave2DirY" show_text="true" value="0.7" + width="200" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-20" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="240" mouse_opaque="true" name="BHText3" v_pad="0" width="355"> + Normal Map + </text> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="365" name="WaterNormalMapHelp" width="18" /> + <texture_picker bottom="-165" height="143" label="" left="250" name="WaterNormalMap" + width="128" /> + </panel> + </tab_container> + <string name="WLDefaultWaterNames"> + Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez + </string> +</floater> diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_windlight_manager.xml b/linden/indra/newview/skins/default/xui/en-us/floater_windlight_manager.xml new file mode 100644 index 000000000..9ef70c8d4 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_windlight_manager.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater bottom="-150" can_close="true" can_drag_on_left="false" can_minimize="true" + can_resize="false" height="130" left="50" min_height="130" + min_width="300" mouse_opaque="true" name="WindLight send to server floater" + title="WindLight Manager" + width="300"> + <button bottom="-50" enabled="true" font="SansSerif" halign="center" height="20" + label="This Parcel" label_selected="This Parcel" left="10" + mouse_opaque="true" name="this_parcel" scale_image="true" width="90" /> + <button bottom="-50" enabled="true" font="SansSerif" halign="center" height="20" + label="All Parcels" label_selected="All Parcels" left_delta="95 " + mouse_opaque="true" name="all_parcels" scale_image="true" width="90" /> + <button bottom="-50" enabled="true" font="SansSerif" halign="center" height="20" + label="This Region" label_selected="This Region" left_delta="95 " + mouse_opaque="true" name="this_region" scale_image="true" width="90" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-75" drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="16" + left="10" mouse_opaque="true" name="KeyFramePresetsText" v_pad="0" + width="110"> + Settings: + </text> + <combo_box allow_text_entry="false" bottom="-77" follows="left|top" height="18" + left_delta="70" max_chars="20" mouse_opaque="true" name="WLSettingsCombo" + width="200" /> + <button bottom="-125" enabled="true" font="SansSerif" halign="center" height="20" + label="Show" label_selected="Show" left="10" + mouse_opaque="true" name="show" scale_image="true" width="80" /> + <button bottom="-125" enabled="true" font="SansSerif" halign="center" height="20" + label="Set to Current" label_selected="Set to Current" left="95" + mouse_opaque="true" name="set_to_current" scale_image="true" width="100" /> + <button bottom="-125" enabled="true" font="SansSerif" halign="center" height="20" + label="Remove" label_selected="Remove" left="200" + mouse_opaque="true" name="remove" scale_image="true" width="80" /> +</floater> diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_windlight_options.xml b/linden/indra/newview/skins/default/xui/en-us/floater_windlight_options.xml index 4f5fc4adf..c5e2c2aab 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_windlight_options.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_windlight_options.xml @@ -32,6 +32,9 @@ <flyout_button_item value="save_disk_item" name="save_disk_item"> Save to Disk </flyout_button_item> + <flyout_button_item value="send_to_server_item" name="send_to_server_item"> + Send to Server + </flyout_button_item> </flyout_button> <button bottom_delta="0" enabled="true" font="SansSerif" halign="center" height="20" label="Delete File" label_selected="Delete File" right="-10" @@ -211,6 +214,10 @@ initial_val="500" label="" left="494" max_val="4000" min_val="0" mouse_opaque="true" name="WLMaxAltitude" show_text="true" value="4000" width="205" /> + <button bottom="4" enabled="true" font="SansSerif" halign="center" height="20" + label="Day Cycle Editor" label_selected="Day Cycle Editor" + right="-10" mouse_opaque="true" name="WLDayCycleMenuButton" + scale_image="true" width="150" /> </panel> <panel border="true" bottom="-180" follows="left|top|right|bottom" height="160" label="Lighting" left="1" mouse_opaque="true" @@ -572,34 +579,54 @@ mouse_opaque="true" name="WLCloudScrollX" show_text="true" value="0.0" width="200" /> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-60" drop_shadow_visible="true" follows="left|top|right" + bottom="-52" drop_shadow_visible="true" follows="left|top|right" font="SansSerif" h_pad="0" halign="left" height="16" left="480" mouse_opaque="true" name="WLCloudScrollYText" v_pad="0" width="355"> Cloud Scroll Y </text> - <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + <button bottom_delta="-2" follows="left|top" font="SansSerifSmall" height="18" label="?" left="605" name="WLCloudScrollYHelp" width="18" /> <check_box control_name="WLCloudLockY" follows="left" font="SansSerifSmall" height="16" initial_value="false" label="Lock" left="625" mouse_opaque="true" name="WLCloudLockY" width="200" /> - <slider bottom_delta="-15" can_edit_text="false" control_name="WLCloudScrollY" + <slider bottom_delta="-10" can_edit_text="false" control_name="WLCloudScrollY" decimal_digits="2" follows="left" height="10" increment="0.01" initial_val="0.5" label="" left="494" max_val="10" min_val="-10" mouse_opaque="true" name="WLCloudScrollY" show_text="true" value="0.0" width="200" /> - <check_box bottom="-120" control_name="DrawClassicClouds" follows="left" + <check_box bottom="-102" control_name="DrawClassicClouds" follows="left" font="SansSerifSmall" height="16" initial_value="false" label="Draw Classic Clouds" left="480" mouse_opaque="true" name="DrawClassicClouds" width="200" /> - <button bottom="-102" follows="left|top" font="SansSerifSmall" height="18" label="?" + <button bottom="-85" follows="left|top" font="SansSerifSmall" height="18" label="?" left="608" name="WLClassicCloudsHelp" width="18" /> + <text bottom_delta="-19" type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="20" + left="480" mouse_opaque="true" name="WLCloudHeightText" v_pad="0" + width="355"> + Classic Cloud Height + </text> + <slider bottom_delta="-27" can_edit_text="true" control_name="WLCloudHeight" + decimal_digits="0" follows="left" height="16" increment="1" + initial_val="192" label="" left="494" max_val="1000" min_val="0" + mouse_opaque="true" name="WLCloudHeight" show_text="true" value="192" + width="200" /> + <text bottom_delta="0" type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + drop_shadow_visible="true" follows="left|top|right" + font="SansSerif" h_pad="0" halign="left" height="20" + left="480" mouse_opaque="true" name="WLCloudClassicRangeText" v_pad="0" + width="355"> + Classic Cloud Range + </text> + <slider bottom_delta="-27" can_edit_text="true" control_name="WLCloudClassicRange" + decimal_digits="0" follows="left" height="16" increment="1 " + initial_val="48" label="" left="494" max_val="100" min_val="0" + mouse_opaque="true" name="WLCloudRange" show_text="true" value="48" + width="200" /> </panel> </tab_container> - <button bottom="4" enabled="true" font="SansSerif" halign="center" height="20" - label="Day Cycle Editor" label_selected="Day Cycle Editor" - right="-10" mouse_opaque="true" name="WLDayCycleMenuButton" - scale_image="true" width="150" /> <string name="WLDefaultSkyNames"> A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality </string> diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_windlight_remote_save.xml b/linden/indra/newview/skins/default/xui/en-us/floater_windlight_remote_save.xml new file mode 100644 index 000000000..84c1d0498 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_windlight_remote_save.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater bottom="-150" can_close="true" can_drag_on_left="false" can_minimize="true" + can_resize="true" height="220" left="50" min_height="220" + min_width="300" mouse_opaque="true" name="WindLight send to server floater" + title="WindLight Send to Server" + width="300"> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + left="10" bottom="180" drop_shadow_visible="true" follows="left|top" + font="SansSerif" h_pad="0" halign="left" height="10" + mouse_opaque="true" name="label Type" v_pad="0" width="275"> + WindLight Send to Server + </text> + <slider can_edit_text="true" control_name="max_altitude" + left="20" bottom="110" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="4096.0" label="Max Altitude" max_val="4096.001" min_val="0" + mouse_opaque="true" name="max_altitude" show_text="true" value="4096.0" + width="200" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="125" name="max_altitude_help" width="18" enabled="true" /> + + <slider can_edit_text="true" control_name="min_altitude" + left="20" bottom="80" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="1.0" label="Min Altitude" max_val="4096" min_val="0" + mouse_opaque="true" name="min_altitude" show_text="true" value="0" + width="200" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="95" name="min_altitude_help" width="18" enabled="true" /> + <slider can_edit_text="true" control_name="Fade" + left="20" bottom="50" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="1.0" label="Fade" max_val="10" min_val="0" + mouse_opaque="true" name="Fade" show_text="true" value="1.0" + width="200" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="65" name="fade_help" width="18" /> + + <tab_container bottom="-220" follows="left|top" height="160" left="0" + mouse_opaque="false" name="WindLight_Setting_Types" tab_position="top" width="299"> + <panel border="true" bottom="175" follows="left|top|right|bottom" height="160" + label="Region" left="1" mouse_opaque="false" + name="Region" width="698"> + <check_box control_name="override_parcel" follows="left" font="SansSerifSmall" height="16" + left="20" bottom="30" + initial_value="false" label="Override Parcels" mouse_opaque="true" + name="override_parcel" width="200" enabled="true" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="45" name="override_parcel_help" width="18" enabled="true" /> + + <button follows="top|right" font="SansSerif" halign="center" + right="-10" bottom="20" + height="20" label="Send" label_selected="Send" + mouse_opaque="true" name="button_region_send_to_server" scale_image="TRUE" width="78" /> + </panel> + <panel border="true" bottom="175" follows="left|top|right|bottom" height="160" + label="Parcel" left="1" mouse_opaque="false" + name="Parcel" width="698"> + + <!--<slider can_edit_text="true" control_name="max_altitude" + left="20" bottom="110" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="4096.0" label="Max Altitude" max_val="4096.001" min_val="0" + mouse_opaque="true" name="max_altitude" show_text="true" value="4096.0" + width="200" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="125" name="max_altitude_help" width="18" enabled="true" /> + + <slider can_edit_text="true" control_name="min_altitude" + left="20" bottom="80" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="1.0" label="Min Altitude" max_val="4096" min_val="0" + mouse_opaque="true" name="min_altitude" show_text="true" value="0" + width="200" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="95" name="min_altitude_help" width="18" enabled="true" /> + + <slider can_edit_text="true" control_name="Fade" + left="20" bottom="50" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="1.0" label="Fade" max_val="10" min_val="0" + mouse_opaque="true" name="Fade" show_text="true" value="1.0" + width="200" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="65" name="fade_help" width="18" />--> + + <button follows="top|right" font="SansSerif" halign="center" + right="-10" bottom="20" height="20" label="Send" + mouse_opaque="true" name="button_parcel_send_to_server" width="78" /> + </panel> + <!--<panel border="true" bottom="175" follows="left|top|right|bottom" height="160" + label="Area" left="1" mouse_opaque="false" + name="Area" width="698"> + + <slider can_edit_text="true" control_name="Max Altitude" + left="20" bottom="110" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="4096.0" label="Max Altitude" max_val="4096.001" min_val="0" + mouse_opaque="true" name="Max Altitude" show_text="true" value="4096.0" + width="200" /> + <slider can_edit_text="true" control_name="Min Altitude" + left="20" bottom="80" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="1.0" label="Min Altitude" max_val="4096" min_val="0" + mouse_opaque="true" name="Min Altitude" show_text="true" value="0" + width="200" /> + + <slider can_edit_text="true" control_name="Fade" + left="20" bottom="50" + decimal_digits="2" follows="left" height="18" increment="0.1" + initial_val="1.0" label="Fade" max_val="10" min_val="0" + mouse_opaque="true" name="Fade" show_text="true" value="1.0" + width="200" /> + <button follows="left|top" font="SansSerifSmall" height="18" label="?" + left_delta="210" bottom="65" name="fade_help" width="18" /> + + <button follows="top|right" font="SansSerif" halign="center" + right="-10" bottom="20" + height="20" label="Send" label_selected="Send" + mouse_opaque="true" name="button send to server" scale_image="TRUE" width="78" /> + </panel>--> + </tab_container> +</floater> diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_world_map.xml b/linden/indra/newview/skins/default/xui/en-us/floater_world_map.xml index 389efb539..daf217ead 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_world_map.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_world_map.xml @@ -1,183 +1,183 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true" - height="711" min_height="520" min_width="410" name="worldmap" - rect_control="FloaterWorldMapRect2" title="World Map" width="1243"> - <tab_container bottom="-701" follows="left|top|right|bottom" height="681" left="15" - mouse_opaque="false" name="maptab" tab_position="top" width="995"> - <panel bottom="-680" follows="left|top|right|bottom" height="664" label="Objects" - left="1" mouse_opaque="true" name="objects_mapview" width="993" /> - <panel bottom="-680" follows="left|top|right|bottom" height="664" label="Terrain" - left="1" mouse_opaque="true" name="terrain_mapview" width="993" /> - </tab_container> - <icon bottom="-50" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="map_avatar_16.tga" left="1013" mouse_opaque="true" name="self" - width="16" /> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-50" drop_shadow_visible="true" follows="top|right" - font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" - mouse_opaque="true" name="you_label" v_pad="0" width="145"> - You - </text> - <icon bottom="-50" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="map_home.tga" left="1083" mouse_opaque="true" name="home" - width="16" /> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-50" drop_shadow_visible="true" follows="top|right" - font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" - mouse_opaque="true" name="home_label" v_pad="0" width="145"> - Home - </text> - <icon bottom="-70" color="0.5, 0.25, 1, 1" follows="top|right" height="16" - image_name="legend.tga" left="1013" mouse_opaque="true" name="square2" - width="16" /> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-70" drop_shadow_visible="true" follows="top|right" - font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" - mouse_opaque="true" name="auction_label" v_pad="0" width="145"> - Auction - </text> - <icon bottom="-70" color="1, 1, 0.25, 1" follows="top|right" height="16" - image_name="legend.tga" left="1083" mouse_opaque="true" name="square" - width="16" /> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-70" drop_shadow_visible="true" follows="top|right" - font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" - mouse_opaque="true" name="land_for_sale_label" v_pad="0" width="145"> - Land For Sale - </text> - <button bottom="-50" follows="top|right" font="SansSerifSmall" halign="center" - height="16" label="Go Home" label_selected="Go Home" left="1150" - mouse_opaque="true" name="Go Home" tool_tip="Teleport to your home" - width="88" /> - <icon bottom="-92" color="0, 1, 0, 1" follows="top|right" height="8" - image_name="map_avatar_8.tga" left="1017" mouse_opaque="true" name="person" - width="8" /> - <check_box bottom="-96" control_name="MapShowPeople" follows="top|right" - font="SansSerifSmall" height="16" initial_value="false" label="Resident" - left_delta="16" mouse_opaque="true" name="people_chk" width="110" /> - <icon bottom="-116" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="map_infohub.tga" left="1013" mouse_opaque="true" name="infohub" - width="16" /> - <check_box bottom="-116" control_name="MapShowInfohubs" follows="top|right" - font="SansSerifSmall" height="16" initial_value="false" label="Infohub" - left_delta="20" mouse_opaque="true" name="infohub_chk" width="110" /> - <icon bottom="-136" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="map_telehub.tga" left="1013" mouse_opaque="true" name="telehub" - width="16" /> - <check_box bottom="-136" control_name="MapShowTelehubs" follows="top|right" - font="SansSerifSmall" height="16" initial_value="false" label="Telehub" - left_delta="20" mouse_opaque="true" name="telehubchk" width="110" /> - <icon bottom="-156" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="icon_for_sale.tga" left="1013" mouse_opaque="true" - name="landforsale" width="16" /> - <check_box bottom="-156" control_name="MapShowLandForSale" follows="top|right" - font="SansSerifSmall" height="16" initial_value="false" label="Land for Sale" - left_delta="20" mouse_opaque="true" name="land_for_sale_chk" width="110" /> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-96" drop_shadow_visible="true" follows="top|right" - font="SansSerifSmall" h_pad="0" halign="left" height="16" left="1139" - mouse_opaque="true" name="events_label" v_pad="0" width="145"> - Events: - </text> - <icon bottom="-116" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="map_event.tga" left="1151" mouse_opaque="true" name="event" - width="16" /> - <check_box bottom="-116" control_name="MapShowEvents" follows="top|right" - font="SansSerifSmall" height="16" initial_value="false" label="PG" - left_delta="20" mouse_opaque="true" name="event_chk" width="55" /> - <icon bottom="-136" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="map_event_mature.tga" left="1151" mouse_opaque="true" - name="events_mature_icon" width="16" /> - <check_box bottom="-136" control_name="ShowMatureEvents" follows="top|right" - font="SansSerifSmall" height="16" initial_value="true" label="Mature" - left_delta="20" mouse_opaque="true" name="event_mature_chk" width="55" /> - <icon bottom="-156" color="1, 1, 1, 1" follows="top|right" height="16" - image_name="map_event_adult.tga" left="1151" mouse_opaque="true" - name="events_adult_icon" width="16" /> - <check_box bottom="-156" control_name="ShowAdultEvents" follows="top|right" - font="SansSerifSmall" height="16" initial_value="false" label="Adult" - left_delta="20" mouse_opaque="true" name="event_adult_chk" width="55" /> - <icon bottom="-180" color="0.5, 0, 0, 1" follows="top|right" height="16" - image_name="map_track_16.tga" left="1013" mouse_opaque="true" - name="avatar_icon" width="16" /> - <combo_box allow_text_entry="true" bottom_delta="0" follows="top|right" height="20" - label="Online Friends" left_delta="20" max_chars="60" mouse_opaque="true" - name="friend combo" tool_tip="Friend to Show on Map" width="202"> - <combo_item name="none_selected" value="None"> - Online Friends - </combo_item> - </combo_box> - <icon bottom_delta="-25" color="0.5, 0, 0, 1" follows="top|right" height="16" - image_name="map_track_16.tga" left="1013" mouse_opaque="true" - name="landmark_icon" width="16" /> - <combo_box allow_text_entry="true" bottom_delta="0" follows="top|right" height="20" - label="Landmarks" left_delta="20" max_chars="64" mouse_opaque="true" - name="landmark combo" tool_tip="Landmark to Show on Map" width="202"> - <combo_item name="none_selected" value="None"> - Landmarks - </combo_item> - </combo_box> - <icon bottom_delta="-25" color="0.5, 0, 0, 1" follows="top|right" height="16" - image_name="map_track_16.tga" left="1013" mouse_opaque="true" - name="location_icon" width="16" /> - <line_editor bottom_delta="0" follows="top|right" height="20" label="Search by Region Name" - left_delta="20" name="location" select_on_focus="true" - tool_tip="Type the name of a region" width="140" /> - <button bottom_delta="0" follows="top|right" font="SansSerif" halign="center" - height="20" label="Search" left_delta="145" mouse_opaque="true" - name="DoSearch" tool_tip="Search for region" width="60" /> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-20" drop_shadow_visible="true" follows="top|right" - font="SansSerif" h_pad="0" halign="left" height="16" left="1013" - mouse_opaque="true" name="search_label" v_pad="0" width="222"> - Search Results: - </text> - <scroll_list background_visible="true" bottom_delta="-326" draw_border="true" - draw_stripes="false" - follows="top|right|bottom" height="320" left="1013" multi_select="false" - name="search_results" width="222"> - <column label="" name="icon" width="16" /> - <column label="" name="sim_name" width="206" /> - </scroll_list> - <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-20" drop_shadow_visible="true" follows="bottom|right" - font="SansSerif" h_pad="0" halign="left" height="16" left="1013" - mouse_opaque="true" name="location_label" v_pad="0" width="98"> - Location: - </text> - <spinner bottom_delta="0" decimal_digits="0" follows="bottom|right" height="16" - increment="1" initial_val="128" left="1090" max_val="255" min_val="0" - mouse_opaque="true" name="spin x" - tool_tip="X coordinate of location to show on map" width="48" /> - <spinner bottom_delta="0" decimal_digits="0" follows="bottom|right" height="16" - increment="1" initial_val="128" left_delta="50" max_val="255" min_val="0" - mouse_opaque="true" name="spin y" - tool_tip="Y coordinate of location to show on map" width="48" /> - <spinner bottom_delta="0" decimal_digits="0" follows="bottom|right" height="16" - increment="1" initial_val="0" left_delta="50" max_val="4096" min_val="0" - mouse_opaque="true" name="spin z" - tool_tip="Z coordinate of location to show on map" width="48" /> - <button bottom="-625" follows="right|bottom" font="SansSerif" halign="center" - height="20" label="Teleport" label_selected="Teleport" left="-230" - mouse_opaque="true" name="Teleport" - tool_tip="Teleport to selected location" width="90" /> - <button bottom_delta="0" follows="right|bottom" font="SansSerif" halign="center" - height="20" label="Show Destination" label_selected="Show Destination" - left_delta="100" mouse_opaque="true" name="Show Destination" - tool_tip="Center map on selected location" width="125" /> - <button bottom_delta="-24" follows="right|bottom" font="SansSerif" halign="center" - height="20" label="Clear" label_selected="Clear" left="-230" - mouse_opaque="true" name="Clear" tool_tip="Stop tracking" width="90" /> - <button bottom_delta="0" follows="right|bottom" font="SansSerif" halign="center" - height="20" label="Show My Location" label_selected="Show My Location" - left_delta="100" mouse_opaque="true" name="Show My Location" - tool_tip="Center map on your avatar's location" width="125" /> - <button bottom_delta="-24" enabled="false" follows="bottom|right" font="SansSerif" - height="20" label="Copy SLURL to clipboard" left="-230" name="copy_slurl" - tool_tip="Copies current location as SLURL to be used on the web." - width="222" /> - <slider bottom="-697" can_edit_text="false" decimal_digits="3" follows="right|bottom" - height="16" increment="0.2" initial_val="48.5029" label="Zoom" left="-230" - max_val="0" min_val="-8" mouse_opaque="true" name="zoom slider" - show_text="false" value="48.5029" width="222" /> -</floater> +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true" + height="711" min_height="520" min_width="410" name="worldmap" + rect_control="FloaterWorldMapRect2" title="World Map" width="1243"> + <tab_container bottom="-701" follows="left|top|right|bottom" height="681" left="15" + mouse_opaque="false" name="maptab" tab_position="top" width="995"> + <panel bottom="-680" follows="left|top|right|bottom" height="664" label="Objects" + left="1" mouse_opaque="true" name="objects_mapview" width="993" /> + <panel bottom="-680" follows="left|top|right|bottom" height="664" label="Terrain" + left="1" mouse_opaque="true" name="terrain_mapview" width="993" /> + </tab_container> + <icon bottom="-50" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="map_avatar_16.tga" left="1013" mouse_opaque="true" name="self" + width="16" /> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-50" drop_shadow_visible="true" follows="top|right" + font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" + mouse_opaque="true" name="you_label" v_pad="0" width="145"> + You + </text> + <icon bottom="-50" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="map_home.tga" left="1083" mouse_opaque="true" name="home" + width="16" /> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-50" drop_shadow_visible="true" follows="top|right" + font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" + mouse_opaque="true" name="home_label" v_pad="0" width="145"> + Home + </text> + <icon bottom="-70" color="0.5, 0.25, 1, 1" follows="top|right" height="16" + image_name="legend.tga" left="1013" mouse_opaque="true" name="square2" + width="16" /> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-70" drop_shadow_visible="true" follows="top|right" + font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" + mouse_opaque="true" name="auction_label" v_pad="0" width="145"> + Auction + </text> + <icon bottom="-70" color="1, 1, 0.25, 1" follows="top|right" height="16" + image_name="legend.tga" left="1083" mouse_opaque="true" name="square" + width="16" /> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-70" drop_shadow_visible="true" follows="top|right" + font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="20" + mouse_opaque="true" name="land_for_sale_label" v_pad="0" width="145"> + Land For Sale + </text> + <button bottom="-50" follows="top|right" font="SansSerifSmall" halign="center" + height="16" label="Go Home" label_selected="Go Home" left="1150" + mouse_opaque="true" name="Go Home" tool_tip="Teleport to your home" + width="88" /> + <icon bottom="-92" color="0, 1, 0, 1" follows="top|right" height="8" + image_name="map_avatar_8.tga" left="1017" mouse_opaque="true" name="person" + width="8" /> + <check_box bottom="-96" control_name="MapShowPeople" follows="top|right" + font="SansSerifSmall" height="16" initial_value="false" label="Resident" + left_delta="16" mouse_opaque="true" name="people_chk" width="110" /> + <icon bottom="-116" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="map_infohub.tga" left="1013" mouse_opaque="true" name="infohub" + width="16" /> + <check_box bottom="-116" control_name="MapShowInfohubs" follows="top|right" + font="SansSerifSmall" height="16" initial_value="false" label="Infohub" + left_delta="20" mouse_opaque="true" name="infohub_chk" width="110" /> + <icon bottom="-136" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="map_telehub.tga" left="1013" mouse_opaque="true" name="telehub" + width="16" /> + <check_box bottom="-136" control_name="MapShowTelehubs" follows="top|right" + font="SansSerifSmall" height="16" initial_value="false" label="Telehub" + left_delta="20" mouse_opaque="true" name="telehubchk" width="110" /> + <icon bottom="-156" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="icon_for_sale.tga" left="1013" mouse_opaque="true" + name="landforsale" width="16" /> + <check_box bottom="-156" control_name="MapShowLandForSale" follows="top|right" + font="SansSerifSmall" height="16" initial_value="false" label="Land for Sale" + left_delta="20" mouse_opaque="true" name="land_for_sale_chk" width="110" /> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-96" drop_shadow_visible="true" follows="top|right" + font="SansSerifSmall" h_pad="0" halign="left" height="16" left="1139" + mouse_opaque="true" name="events_label" v_pad="0" width="145"> + Events: + </text> + <icon bottom="-116" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="map_event.tga" left="1151" mouse_opaque="true" name="event" + width="16" /> + <check_box bottom="-116" control_name="MapShowEvents" follows="top|right" + font="SansSerifSmall" height="16" initial_value="false" label="PG" + left_delta="20" mouse_opaque="true" name="event_chk" width="55" /> + <icon bottom="-136" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="map_event_mature.tga" left="1151" mouse_opaque="true" + name="events_mature_icon" width="16" /> + <check_box bottom="-136" control_name="ShowMatureEvents" follows="top|right" + font="SansSerifSmall" height="16" initial_value="true" label="Mature" + left_delta="20" mouse_opaque="true" name="event_mature_chk" width="55" /> + <icon bottom="-156" color="1, 1, 1, 1" follows="top|right" height="16" + image_name="map_event_adult.tga" left="1151" mouse_opaque="true" + name="events_adult_icon" width="16" /> + <check_box bottom="-156" control_name="ShowAdultEvents" follows="top|right" + font="SansSerifSmall" height="16" initial_value="false" label="Adult" + left_delta="20" mouse_opaque="true" name="event_adult_chk" width="55" /> + <icon bottom="-180" color="0.5, 0, 0, 1" follows="top|right" height="16" + image_name="map_track_16.tga" left="1013" mouse_opaque="true" + name="avatar_icon" width="16" /> + <combo_box allow_text_entry="true" bottom_delta="0" follows="top|right" height="20" + label="Online Friends" left_delta="20" max_chars="60" mouse_opaque="true" + name="friend combo" tool_tip="Friend to Show on Map" width="202"> + <combo_item name="none_selected" value="None"> + Online Friends + </combo_item> + </combo_box> + <icon bottom_delta="-25" color="0.5, 0, 0, 1" follows="top|right" height="16" + image_name="map_track_16.tga" left="1013" mouse_opaque="true" + name="landmark_icon" width="16" /> + <combo_box allow_text_entry="true" bottom_delta="0" follows="top|right" height="20" + label="Landmarks" left_delta="20" max_chars="64" mouse_opaque="true" + name="landmark combo" tool_tip="Landmark to Show on Map" width="202"> + <combo_item name="none_selected" value="None"> + Landmarks + </combo_item> + </combo_box> + <icon bottom_delta="-25" color="0.5, 0, 0, 1" follows="top|right" height="16" + image_name="map_track_16.tga" left="1013" mouse_opaque="true" + name="location_icon" width="16" /> + <line_editor bottom_delta="0" follows="top|right" height="20" label="Search by Region Name" + left_delta="20" name="location" select_on_focus="true" + tool_tip="Type the name of a region" width="140" /> + <button bottom_delta="0" follows="top|right" font="SansSerif" halign="center" + height="20" label="Search" left_delta="145" mouse_opaque="true" + name="DoSearch" tool_tip="Search for region" width="60" /> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-20" drop_shadow_visible="true" follows="top|right" + font="SansSerif" h_pad="0" halign="left" height="16" left="1013" + mouse_opaque="true" name="search_label" v_pad="0" width="222"> + Search Results: + </text> + <scroll_list background_visible="true" bottom_delta="-326" draw_border="true" + draw_stripes="false" + follows="top|right|bottom" height="320" left="1013" multi_select="false" + name="search_results" width="222"> + <column label="" name="icon" width="16" /> + <column label="" name="sim_name" width="206" /> + </scroll_list> + <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-20" drop_shadow_visible="true" follows="bottom|right" + font="SansSerif" h_pad="0" halign="left" height="16" left="1013" + mouse_opaque="true" name="location_label" v_pad="0" width="98"> + Location: + </text> + <spinner bottom_delta="0" decimal_digits="0" follows="bottom|right" height="16" + increment="1" initial_val="128" left="1090" max_val="99999" min_val="0" + mouse_opaque="true" name="spin x" + tool_tip="X coordinate of location to show on map" width="48" /> + <spinner bottom_delta="0" decimal_digits="0" follows="bottom|right" height="16" + increment="1" initial_val="128" left_delta="50" max_val="99999" min_val="0" + mouse_opaque="true" name="spin y" + tool_tip="Y coordinate of location to show on map" width="48" /> + <spinner bottom_delta="0" decimal_digits="0" follows="bottom|right" height="16" + increment="1" initial_val="0" left_delta="50" max_val="4096" min_val="0" + mouse_opaque="true" name="spin z" + tool_tip="Z coordinate of location to show on map" width="48" /> + <button bottom="-625" follows="right|bottom" font="SansSerif" halign="center" + height="20" label="Teleport" label_selected="Teleport" left="-230" + mouse_opaque="true" name="Teleport" + tool_tip="Teleport to selected location" width="90" /> + <button bottom_delta="0" follows="right|bottom" font="SansSerif" halign="center" + height="20" label="Show Destination" label_selected="Show Destination" + left_delta="100" mouse_opaque="true" name="Show Destination" + tool_tip="Center map on selected location" width="125" /> + <button bottom_delta="-24" follows="right|bottom" font="SansSerif" halign="center" + height="20" label="Clear" label_selected="Clear" left="-230" + mouse_opaque="true" name="Clear" tool_tip="Stop tracking" width="90" /> + <button bottom_delta="0" follows="right|bottom" font="SansSerif" halign="center" + height="20" label="Show My Location" label_selected="Show My Location" + left_delta="100" mouse_opaque="true" name="Show My Location" + tool_tip="Center map on your avatar's location" width="125" /> + <button bottom_delta="-24" enabled="false" follows="bottom|right" font="SansSerif" + height="20" label="Copy SLURL to clipboard" left="-230" name="copy_slurl" + tool_tip="Copies current location as SLURL to be used on the web." + width="222" /> + <slider bottom="-697" can_edit_text="false" decimal_digits="3" follows="right|bottom" + height="16" increment="0.2" initial_val="48.5029" label="Zoom" left="-230" + max_val="0" min_val="-8" mouse_opaque="true" name="zoom slider" + show_text="false" value="48.5029" width="222" /> +</floater> diff --git a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml index 18bedd0b5..35f3037c3 100644 --- a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml +++ b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml @@ -1,23 +1,23 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Attachment Pie"> - <menu_item_call enabled="false" label="Drop" mouse_opaque="true" name="Drop"> - <on_click function="Attachment.Drop" /> - <on_enable function="Attachment.EnableDrop" /> - </menu_item_call> - <menu_item_separator /> - <menu_item_separator /> - <menu_item_separator /> - <menu_item_call enabled="true" label="Inspect" mouse_opaque="true" name="Object Inspect"> - <on_click function="Object.Inspect" /> - <on_enable function="Object.EnableInspect" /> - </menu_item_call> - <menu_item_separator /> - <menu_item_call enabled="false" label="Detach" mouse_opaque="true" name="Detach"> - <on_click function="Attachment.Detach" /> - <on_enable function="Attachment.EnableDetach" /> - </menu_item_call> - <menu_item_call enabled="false" label="Edit..." mouse_opaque="true" name="Edit"> - <on_click function="Object.Edit" /> - <on_enable function="EnableEdit" /> - </menu_item_call> -</pie_menu> +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<pie_menu name="Attachment Pie"> + <menu_item_call enabled="false" label="Drop" mouse_opaque="true" name="Drop"> + <on_click function="Attachment.Drop" /> + <on_enable function="Attachment.EnableDrop" /> + </menu_item_call> + <menu_item_separator /> + <menu_item_separator /> + <menu_item_separator /> + <menu_item_call enabled="true" label="Inspect" mouse_opaque="true" name="Object Inspect"> + <on_click function="Object.Inspect" /> + <on_enable function="Object.EnableInspect" /> + </menu_item_call> + <menu_item_separator /> + <menu_item_call enabled="false" label="Detach" mouse_opaque="true" name="Detach"> + <on_click function="Attachment.Detach" /> + <on_enable function="Attachment.EnableDetach" /> + </menu_item_call> + <menu_item_call enabled="false" label="Edit..." mouse_opaque="true" name="Edit"> + <on_click function="Object.Edit" /> + <on_enable function="EnableEdit" /> + </menu_item_call> +</pie_menu> diff --git a/linden/indra/newview/skins/default/xui/en-us/notifications.xml b/linden/indra/newview/skins/default/xui/en-us/notifications.xml index 0ac74014a..b98ff7cc4 100644 --- a/linden/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/linden/indra/newview/skins/default/xui/en-us/notifications.xml @@ -3661,6 +3661,90 @@ If this box is checked, people will not be able to fly in this region regardless Default: off </notification> +<notification + icon="alertmodal.tga" + label="Force Draw Distance" + name="HelpForceDrawDistance" + type="alertmodal"> +If this box is checked, draw distance will be locked for all people in the sim. Note: This will lag people on older machines. PLEASE think before setting this setting. + +Default: off +</notification> + +<notification + icon="alertmodal.tga" + label="Max Inventory Items To Transfer" + name="HelpMaxInventoryItemsTransfer" + type="alertmodal"> +This box controls how many objects can be transfered between clients at a time. -1 sets no limit on the amount of objects. Default Second Life setting is 42. + +Default: -1 +</notification> +<notification + icon="alertmodal.tga" + label="Max Groups" + name="HelpMaxGroups" + type="alertmodal"> +This box controls how many groups an agent can join. -1 sets no limit on the amount of groups. + +Default: -1 +</notification> + <notification + icon="alertmodal.tga" + label="Render Water" + name="HelpRenderWater" + type="alertmodal"> + If this box is checked, water will not be shown for users in this sim. + + Default: -1 + </notification> +<notification + icon="alertmodal.tga" + label="Allow Minimap" + name="HelpAllowMinimap" + type="alertmodal"> +If this box is checked, the minimap will be disabled for users in this sim. + +Default: on +</notification> +<notification + icon="alertmodal.tga" + label="Allow Minimap" + name="HelpAllowPhysicalPrims" + type="alertmodal"> +If this box is checked, physical prims will be allowed to be created in this sim. + +Default: on +</notification> +<notification + icon="alertmodal.tga" + label="Enable Teen Mode" + name="HelpEnableTeenMode" + type="alertmodal"> +If this box is checked, all avatars will be forced to wear underwear and will not be able to take it off. + +Default: off +</notification> +<notification + icon="alertmodal.tga" + label="Show Tags" + name="HelpShowTags" + type="alertmodal"> +This box controls how avatar name tags are shown in this sim. 2 sets tags to always be shown. 1 sets tags to disappear after some time. 0 blocks the viewing of name tags. + +Default: 2 +</notification> +<notification + icon="alertmodal.tga" + label="Allow Parcel WindLight" + name="HelpAllowParcelWindLight" + type="alertmodal"> +If this box is checked, setting WindLight settings in parcels will be enabled. + +Default: on +</notification> + + <notification icon="alertmodal.tga" label="Bulk Change Content Permissions" diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml b/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml index 2360e6b36..0df65e799 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_avatar.xml @@ -138,11 +138,11 @@ bottom_delta="-6" drop_shadow_visible="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="0" mouse_opaque="true" name="About:" v_pad="0" width="170"> - About (500 chars): + About (8196 chars): </text> <text_editor bottom_delta="-137" embedded_items="false" enabled="true" follows="left|top" font="SansSerifSmall" height="137" - is_unicode="false" left_delta="0" max_length="511" mouse_opaque="true" + is_unicode="false" left_delta="0" max_length="8196" mouse_opaque="true" name="about" width="235" word_wrap="true" spell_check="true" /> <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" @@ -350,11 +350,11 @@ bottom_delta="-8" drop_shadow_visible="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="16" left="12" mouse_opaque="true" name="Info:" v_pad="0" width="161"> - Info (250 chars): + Info (8196 chars): </text> <text_editor bottom_delta="-179" embedded_items="false" enabled="true" follows="left|top" font="SansSerifSmall" height="178" - is_unicode="false" left="12" max_length="254" mouse_opaque="false" + is_unicode="false" left="12" max_length="8196" mouse_opaque="false" name="about" width="378" word_wrap="true" spell_check="true" /> </panel> <panel border="true" bottom="-482" follows="left|top|right|bottom" height="466" @@ -372,7 +372,7 @@ </text> <text_editor bottom_delta="-260" embedded_items="false" enabled="true" follows="left|top" font="SansSerif" height="256" is_unicode="false" left="10" - max_length="1023" mouse_opaque="true" name="notes edit" width="400" + max_length="8196" mouse_opaque="true" name="notes edit" width="400" word_wrap="false" spell_check="true" /> </panel> </tab_container> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml index 95d0c33dd..fe6020393 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml @@ -153,11 +153,15 @@ mouse_opaque="false" name="text_box7" v_pad="0" width="128"> Chat Bubbles: </text> - <check_box bottom="-386" control_name="UseChatBubbles" enabled="true" follows="left|top" + <check_box bottom="-386" control_name="UseChatBubbles" enabled="true" follows="left|top" font="SansSerifSmall" height="16" initial_value="false" label="Show chat bubbles" left="148" mouse_opaque="true" name="bubble_text_chat" radio_style="false" width="237" /> - <slider bottom="-402" can_edit_text="false" control_name="ChatBubbleOpacity" + <check_box bottom="-386" control_name="UseLocalChatBubbles" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="false" + label="Show local chat and bubbles" left="288" mouse_opaque="true" + name="local_bubble_text_chat" radio_style="false" width="237" /> + <slider bottom="-402" can_edit_text="false" control_name="ChatBubbleOpacity" decimal_digits="3" enabled="true" follows="left|top" height="12" increment="0.05" initial_val="1" label="Bubble opacity:" left="148" max_val="1" min_val="0" mouse_opaque="true" name="bubble_chat_opacity" show_text="true" diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml index f85e3c0a2..b47794bf0 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml @@ -61,34 +61,34 @@ font="SansSerifSmall" height="16" initial_value="false" label="Hide my group title" left="151" name="show_my_title_checkbox" radio_style="false" width="256" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-230" + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-210" can_apply_immediately="false" color="1 1 1 1" enabled="true" follows="left|top" height="65" label="" left="153" mouse_opaque="true" name="effect_color_swatch" tool_tip="Click to open Color Picker" width="55" /> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-235" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom="-215" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10" mouse_opaque="true" name="UI Size:" v_pad="0" width="128"> UI Size: </text> - <slider bottom="-237" can_edit_text="true" + <slider bottom="-217" can_edit_text="true" decimal_digits="3" enabled="true" height="16" increment="0.001" initial_val="1" left="148" max_val="1.4" min_val="0.75" mouse_opaque="true" name="ui_scale_slider" show_text="true" value="1" width="220" /> - <button bottom="-241" enabled="true" follows="left|top" + <button bottom="-221" enabled="true" follows="left|top" font="SansSerif" halign="center" height="22" label="Reset" label_selected="Reset" left_delta="226" mouse_opaque="true" name="reset_ui_size" scale_image="true" width="80" /> - <check_box bottom="-256" enabled="true" follows="left|top" + <check_box bottom="-236" enabled="true" follows="left|top" font="SansSerifSmall" height="16" initial_value="false" label="Use resolution independent scale" left="151" mouse_opaque="true" name="ui_auto_scale" radio_style="false" width="256" /> - <check_box bottom="-280" enabled="true" follows="left|top" + <check_box bottom="-260" enabled="true" follows="left|top" font="SansSerifSmall" height="16" initial_value="false" label="Go Away/AFK when idle" left="330" mouse_opaque="true" name="afk_timeout_checkbox" radio_style="false" width="256" /> - <spinner bottom="-280" decimal_digits="0" enabled="true" + <spinner bottom="-260" decimal_digits="0" enabled="true" follows="left|top" height="16" increment="1" initial_val="300" label="Away Timeout:" label_width="141" left="10" max_val="600" min_val="30" mouse_opaque="true" name="afk_timeout_spinner" width="202" /> @@ -109,18 +109,18 @@ mouse_opaque="true" name="mini_map_notify_sim" radio_style="false" width="256" /> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-332" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom="-312" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10" mouse_opaque="true" name="maturity_desired_label" v_pad="0" width="394"> Rating: </text> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-332" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom="-312" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left="151" mouse_opaque="true" name="maturity_desired_prompt" v_pad="0" width="394"> I want to access content rated: </text> - <combo_box bottom="-338" follows="left|top" height="18" left="320" + <combo_box bottom="-318" follows="left|top" height="18" left="315" mouse_opaque="true" name="maturity_desired_combobox" width="150"> <combo_item name="Desired_Adult" value="42"> PG, Mature and Adult @@ -133,8 +133,8 @@ </combo_item> </combo_box> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-332" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="10" left="320" + bottom="-312" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="10" left="315" mouse_opaque="true" name="maturity_desired_textbox" v_pad="0" width="150"> PG only </text> @@ -151,25 +151,25 @@ Nametags: </text> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-175" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom="-155" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10" mouse_opaque="true" name="effects_color_textbox" v_pad="0" width="394"> Selection Beam Color: </text> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-274" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom="-254" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left="220" mouse_opaque="true" name="seconds_textbox" v_pad="0" width="128"> seconds </text> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-372" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom="-352" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10" mouse_opaque="true" name="time_textbox" v_pad="0" width="394"> Clock: </text> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-404" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom="-384" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10" mouse_opaque="true" name="language_textbox" v_pad="0" width="394"> Language: @@ -181,10 +181,20 @@ v_pad="0" width="400"> (requires restart for full effect) </text> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10" + mouse_opaque="true" name="remember_password_text" v_pad="0" width="394"> + Remember Password: + </text> + <check_box bottom_delta="0" follows="left|top" + font="SansSerifSmall" height="16" initial_value="false" + label="Remember Password" left="151" mouse_opaque="true" + name="remember_password" radio_style="false" width="256" /> <string name="region_name_prompt"> <Type region name> </string> - <combo_box allow_text_entry="false" bottom="-372" enabled="true" follows="left|top" + <combo_box allow_text_entry="false" bottom="-352" enabled="true" follows="left|top" height="18" left="153" max_chars="20" mouse_opaque="true" name="time_combobox" width="146"> <combo_item type="string" name="12HourTime" value="PST 12"> @@ -197,7 +207,7 @@ UTC </combo_item> </combo_box> - <combo_box allow_text_entry="true" bottom="-402" enabled="true" + <combo_box allow_text_entry="true" bottom="-382" enabled="true" follows="left|top" height="16" left="153" max_chars="135" mouse_opaque="true" name="language_combobox" width="146"> <combo_item type="string" length="1" enabled="true" name="System Default Language" value="default"> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_skins.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_skins.xml index 0611ce348..58a2989b4 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_skins.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_skins.xml @@ -5,8 +5,8 @@ <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom="-22" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10" - mouse_opaque="true" name="muting_text" v_pad="0" width="400"> - Select a skin (requires restart). + mouse_opaque="true" name="muting_text" v_pad="0" width="500"> + Select a skin (requires restart). (Please see the skin folders for information and credits) </text> <radio_group bottom="0" draw_border="false" follows="top|left" height="380" left="12" name="skin_selection" width="480"> @@ -40,12 +40,24 @@ scale_image="true" label="" image_selected="skin_thumbnail_gemini.png" image_hover_selected="skin_thumbnail_gemini.png" image_unselected="skin_thumbnail_gemini.png" image_hover_unselected="skin_thumbnail_gemini.png" follows="left|top" /> - - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="10" drop_shadow_visible="true" enabled="true" follows="left|bottom" - font="SansSerifSmall" h_pad="0" halign="left" height="12" left="90" - mouse_opaque="true" name="muting_text" v_pad="0" width="400"> - (Please see the skin folders for information and credits) + <text name="skin_current_text" + left="10" bottom="5" halign="left" height="12" + follows="left|bottom" h_pad="0" v_pad="0" + bg_visible="false" drop_shadow_visible="true" + border_visible="false" border_drop_shadow_visible="false" + font="SansSerif" mouse_opaque="true"> + Other Skin Name: </text> + <line_editor name="skin_current_edit" + bottom_delta="0" left_delta="120" height="20" width="120" + follows="left|bottom" font="SansSerif" + bevel_style="in" border_style="line" border_thickness="1" + max_length="31" mouse_opaque="true" + handle_edit_keys_directly="true" + select_all_on_focus_received="true" /> + <button name="save_skin" label="Save" + bottom_delta="-2" left_delta="120" height="24" width="90" + follows="left|center" font="SansSerif" halign="center" + mouse_opaque="true" scale_image="TRUE" /> </panel> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml b/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml index 603f2d81d..ce2d5ad64 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml @@ -41,15 +41,15 @@ </text> <slider name="near_me_range" label="" control_name="NearMeRange" - bottom_delta="0" left_delta="62" width="110" height="15" - follows="left|top" min_val="5" max_val="512" increment="1" + bottom_delta="0" left_delta="62" width="150" height="15" + follows="left|top" min_val="5" max_val="2048" increment="1" initial_val="96" decimal_digits="0" /> <text name="meters" - bottom_delta="0" left="180" height="15" width="40" + bottom_delta="0" left_delta="10" height="15" width="40" h_pad="0" halign="left" v_pad="0" follows="left|top" bg_visible="false" border_drop_shadow_visible="false" - border_visible="false" drop_shadow_visible="true" + border_visible="false" drop_shadow_visible="true" font="SansSerifSmall" mouse_opaque="true"> m </text> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_region_estate.xml b/linden/indra/newview/skins/default/xui/en-us/panel_region_estate.xml index 84ce9d050..5dd738a12 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_region_estate.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_region_estate.xml @@ -25,7 +25,7 @@ regions in the estate. (unknown) </text> <view_border bevel_style="in" border="true" border_thickness="1" bottom_delta="-295" - follows="top|left" height="290" left="6" width="250" /> + follows="top|left" height="350" left="6" width="250" /> <check_box bottom_delta="265" follows="left|top" height="20" label="Use Global Time" left="12" name="use_global_time_check" width="200" /> <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" @@ -69,13 +69,12 @@ regions in the estate. left="12" name="allow_direct_teleport" width="80" /> <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" name="allow_direct_teleport_help" right="250" width="18" /> - <text bottom_delta="-26" follows="left|top" font="SansSerifSmall" height="20" - left="10" name="abuse_email_text" width="180"> - Abuse email address: - </text> - <line_editor bottom_delta="-16" follows="top|left" height="19" left="15" max_length="254" + <text bottom_delta="-26" follows="left|top" font="SansSerifSmall" height="20" + left="10" name="abuse_email_text" width="180"> + Abuse email address: + </text> + <line_editor bottom_delta="-16" follows="top|left" height="19" left="15" max_length="254" name="abuse_email_address" width="205" /> - <string name="email_unsupported">Feature unsupported</string> <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" name="abuse_email_address_help" right="250" width="18" /> <button bottom_delta="-26" enabled="false" follows="left|top" height="20" label="Apply" diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_region_general.xml b/linden/indra/newview/skins/default/xui/en-us/panel_region_general.xml index 6302428c8..70df1df45 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_region_general.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_region_general.xml @@ -58,16 +58,21 @@ <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" left="205" name="parcel_search_help" width="18" /> <spinner bottom_delta="-40" follows="left|top" height="20" increment="1" - label="Agent Limit" label_width="97" left="10" max_val="100" min_val="1" + label="Agent Limit" label_width="100" left="10" max_val="100" min_val="1" name="agent_limit_spin" width="170" /> <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" left="205" name="agent_limit_help" width="18" /> <spinner bottom_delta="-20" follows="left|top" height="20" increment="0.5" - label="Object Bonus" label_width="97" left="10" max_val="10" min_val="1" + label="Object Bonus" label_width="100" left="10" max_val="10" min_val="1" name="object_bonus_spin" width="170" /> <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" left="205" name="object_bonus_help" width="18" /> - <text bottom_delta="-30" follows="left|top" height="20" label="Maturity" left="10" + <spinner bottom_delta="-20" follows="left|top" height="20" increment="0.5" + label="Minimum Agent Age" label_width="100" left="10" max_val="1000" min_val="0" + name="minimum_agent_age" width="170" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="205" name="minimum_agent_age_help" width="18" /> + <text bottom_delta="-30" follows="left|top" height="20" label="Maturity" left="10" name="access_text" width="100"> Rating: </text> @@ -87,7 +92,7 @@ left="205" name="access_help" width="18" /> <button bottom_delta="-30" enabled="false" follows="left|top" height="20" label="Apply" left="108" name="apply_btn" width="100" /> - <button bottom_delta="-60" follows="left|top" height="20" + <button bottom_delta="-40" follows="left|top" height="20" label="Teleport Home One User..." left="10" name="kick_btn" width="250" /> <button bottom_delta="-23" follows="left|top" height="20" label="Teleport Home All Users..." left="10" name="kick_all_btn" width="250" /> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_region_open_region_settings.xml b/linden/indra/newview/skins/default/xui/en-us/panel_region_open_region_settings.xml new file mode 100644 index 000000000..3eb78061f --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/panel_region_open_region_settings.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel border="true" bottom="100" follows="top|left" height="320" label="Region Settings" + left="0" name="RegionSettings" width="480"> + <spinner bottom_delta="-40" follows="left|top" height="20" increment="1" + label="Default Draw Distance" label_width="175" left="10" max_val="10000" min_val="1" + name="draw_distance" width="250" /> + <check_box bottom_delta="-20" follows="left|top" height="20" label="Force Draw Distance" + left="10" name="force_draw_distance" width="80" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="force_draw_distance_help" width="18" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Drag Distance" label_width="175" left="10" max_val="1000 0" min_val="0" + name="max_drag_distance" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Prim Scale" label_width="175" left="10" max_val="10000" min_val="0" + name="max_prim_scale" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Min Prim Scale" label_width="175" left="10" max_val="10000" min_val="0" + name="min_prim_scale" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Physical Prim Scale" label_width="175" left="10" max_val="10000" min_val="0" + name="max_phys_prim_scale" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Hollow Size" label_width="175" left="10" max_val="100" min_val="0" + name="max_hollow_size" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Min Hole Size" label_width="175" left="10" max_val="100" min_val="0" + name="min_hole_size" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Link Count" label_width="175" left="10" max_val="100000" min_val="0" + name="max_link_count" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Link Count Phys" label_width="175" left="10" max_val="100000" min_val="0" + name="max_link_count_phys" width="250" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Inventory Items To Transfer" label_width="175" left="10" max_val="10000" min_val="-1" + name="max_inventory_items_transfer" width="250" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="max_inventory_items_transfer_help" width="18" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Show Tags" label_width="175" left="10" max_val="2" min_val="0" + name="show_tags" width="250" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="show_tags_help" width="18" /> + <spinner bottom_delta="-20" follows="left|top" height="20" increment="1" + label="Max Groups" label_width="175" left="10" max_val="1000" min_val="-1" + name="max_groups" width="250" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="max_groups_help" width="18" /> + <check_box bottom_delta="-20" follows="left|top" height="20" label="Render Water" left="10" + name="render_water" width="80" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="render_water_help" width="18" /> + <check_box bottom_delta="-20" follows="left|top" height="20" label="Allow Minimap" + left="10" name="allow_minimap" width="80" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="allow_minimap_help" width="18" /> + <check_box bottom_delta="-20" follows="left|top" height="20" label="Allow Physical Prims" + left="10" name="allow_physical_prims" width="80" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="allow_physical_prims_help" width="18" /> + <check_box bottom_delta="-20" follows="left|top" height="20" label="Enable Teen Mode" + left="10" name="enable_teen_mode" width="80" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="enable_teen_mode_help" width="18" /> + <check_box bottom_delta="-20" follows="left|top" height="20" label="Enforce Max Build Constraints" + left="10" name="enforce_max_build" width="80" /> + <check_box bottom_delta="-20" follows="left|top" height="20" + label="Allow Parcel WindLight" left="10" + name="allow_parcel_windlight" + width="80" /> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="18" label="?" + left="285" name="allow_parcel_windlight_help" width="18" /> + <button bottom_delta="-30" enabled="false" follows="left|top" height="20" label="Apply" + left="108" name="apply_ors_btn" width="100" /> +</panel> diff --git a/linden/indra/newview/viewertime.cpp b/linden/indra/newview/viewertime.cpp index 06dd91a24..06436b648 100644 --- a/linden/indra/newview/viewertime.cpp +++ b/linden/indra/newview/viewertime.cpp @@ -47,6 +47,9 @@ ViewerTime* gViewerTime = 0; // We use statics here for speed reasons bool ViewerTime::sUse24HourTime = false; bool ViewerTime::sUseUTCTime = false; +bool ViewerTime::sUseTimeOffset = false; +S32 ViewerTime::sTimeOffset = 0; +bool ViewerTime::sTimeOffsetDST = false; std::vector<std::string> ViewerTime::sDays; std::vector<std::string> ViewerTime::sMonths; @@ -87,16 +90,21 @@ void ViewerTime::refresh() // There's only one internal tm buffer. struct tm* internal_time; - if (!sUseUTCTime) + if (sUseUTCTime) { - // Convert to Pacific, based on server's opinion of whether - // it's daylight savings time there. - internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime); + time(&utc_time); + internal_time = gmtime(&utc_time); + } + else if (sUseTimeOffset) + { + //Its a UTC offset, deal with it + internal_time = utc_to_offset_time(utc_time, sTimeOffset, sTimeOffsetDST); } else { - time(&utc_time); - internal_time = gmtime(&utc_time); + // Convert to Pacific, based on server's opinion of whether + // it's daylight savings time there. + internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime); } mMinute = internal_time->tm_min; diff --git a/linden/indra/newview/viewertime.h b/linden/indra/newview/viewertime.h index 525a2bcb4..f7a80a6f6 100644 --- a/linden/indra/newview/viewertime.h +++ b/linden/indra/newview/viewertime.h @@ -59,6 +59,9 @@ class ViewerTime static bool sUse24HourTime; static bool sUseUTCTime; + static bool sUseTimeOffset; + static S32 sTimeOffset; + static bool sTimeOffsetDST; void updateTimeFormat(const U32& index); diff --git a/linden/indra/newview/windlightsettingsupdate.cpp b/linden/indra/newview/windlightsettingsupdate.cpp new file mode 100644 index 000000000..a5f9cb7ba --- /dev/null +++ b/linden/indra/newview/windlightsettingsupdate.cpp @@ -0,0 +1,200 @@ +/* + * @file kowopenregionsettings.cpp + * @brief Handler for OpenRegionInfo event queue message. + * + * Copyright (c) 2010, Patrick Sapinski + * + * The source code in this file ("Source Code") is provided to you + * under the terms of the GNU General Public License, version 2.0 + * ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in + * this distribution, or online at + * http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#include "llviewerprecompiledheaders.h" +#include "llhttpnode.h" +#include "hippoLimits.h" +#include "llfloatertools.h" +#include "llviewercontrol.h" +#include "llagent.h" +#include "llsurface.h" +#include "llviewerregion.h" +#include "llviewerobject.h" + +#include "linden_common.h" +#include "llwaterparammanager.h" +#include "llwaterparamset.h" +#include "llwlparammanager.h" +#include "llwlparamset.h" +#include "message.h" +#include "meta7windlight.h" +#include "lightshare.h" +#include "wlsettingsmanager.h" + +//DEBUG includes +//#include "llsdserialize.h" //LLSDNotationStreamer - for dumping LLSD to string + +class WindLightSettingsUpdate : public LLHTTPNode +{ + /*virtual*/ void post( + LLHTTPNode::ResponsePtr response, + const LLSD& context, + const LLSD& input) const + { + if (!input.isMap() || !input.has("body")) + { + llinfos << "malformed WindLightSettingsUpdate update!" << llendl; + return; + } + LLWaterParamSet* mWater; + LLWLParamSet* mSky; + LLUUID* mWaterNormal; + + mWater = new LLWaterParamSet(); + mSky = new LLWLParamSet(); + mWaterNormal = new LLUUID(); + + LLSD body = input["body"]; + + mWater->set("waterFogColor", + body["waterColorX"].asReal() / 256.f, + body["waterColorY"].asReal() / 256.f, + body["waterColorZ"].asReal() / 256.f, + body["waterColorW"].asReal() / 256.f); + mWater->set("waterFogDensity", body["waterFogDensityExponent"].asReal()); + mWater->set("underWaterFogMod", body["underwaterFogModifier"].asReal()); + mWater->set("normScale", body["reflectionWaveletScaleX"].asReal(), + body["reflectionWaveletScaleY"].asReal(), + body["reflectionWaveletScaleZ"].asReal()); + mWater->set("fresnelScale", body["fresnelScale"].asReal()); + mWater->set("fresnelOffset", body["fresnelOffset"].asReal()); + mWater->set("scaleAbove", body["refractScaleAbove"].asReal()); + mWater->set("scaleBelow", body["refractScaleBelow"].asReal()); + mWater->set("blurMultiplier", body["blurMultiplier"].asReal()); + mWater->set("wave2Dir", body["bigWaveDirectionX"].asReal(), + body["bigWaveDirectionY"].asReal()); + mWater->set("wave1Dir", body["littleWaveDirectionX"].asReal(), + body["littleWaveDirectionY"].asReal()); + mWaterNormal->parseUUID(body["normalMapTexture"].asUUID().asString(), mWaterNormal); + + mSky->setSunAngle(body["sunMoonPosition"].asReal()); + mSky->setEastAngle(body["eastAngle"].asReal()); + + mSky->set("sunlight_color", + body["sunMoonColorX"].asReal() * 3.0f, + body["sunMoonColorY"].asReal() * 3.0f, + body["sunMoonColorZ"].asReal() * 3.0f, + body["sunMoonColorW"].asReal() * 3.0f); + + mSky->set("ambient", + body["ambientX"].asReal() * 3.0f, + body["ambientY"].asReal() * 3.0f, + body["ambientZ"].asReal() * 3.0f, + body["ambientW"].asReal() * 3.0f); + + mSky->set("blue_horizon", + body["horizonX"].asReal() * 2.0f, + body["horizonY"].asReal() * 2.0f, + body["horizonZ"].asReal() * 2.0f, + body["horizonW"].asReal() * 2.0f); + + mSky->set("blue_density", + body["blueDensityX"].asReal(), + body["blueDensityY"].asReal(), + body["blueDensityZ"].asReal(), + 1.0); + + mSky->set("haze_horizon", + body["hazeHorizon"].asReal(), + body["hazeHorizon"].asReal(), + body["hazeHorizon"].asReal(), + 1.f); + + mSky->set("haze_density", + body["hazeDensity"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("cloud_shadow", + body["cloudCoverage"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("density_multiplier", + body["densityMultiplier"].asReal() / 1000.0f, + 0.f, 0.f, 1.f); + + mSky->set("distance_multiplier", + body["distanceMultiplier"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("max_y", + body["maxAltitude"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("cloud_color", + body["cloudColorX"].asReal(), + body["cloudColorY"].asReal(), + body["cloudColorZ"].asReal(), + body["cloudColorW"].asReal()); + + mSky->set("cloud_pos_density1", + body["cloudXYDensityX"].asReal(), + body["cloudXYDensityY"].asReal(), + body["cloudXYDensityZ"].asReal(), + 1.f); + + mSky->set("cloud_pos_density2", + body["cloudDetailXYDensityX"].asReal(), + body["cloudDetailXYDensityY"].asReal(), + body["cloudDetailXYDensityZ"].asReal(), + 1.f); + + mSky->set("cloud_scale", + body["cloudScale"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("gamma", + body["sceneGamma"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("glow", + (2 - body["sunGlowSize"].asReal()) * 20, + 0.f, + -body["sunGlowFocus"].asReal() * 5, + 1.f); + + mSky->setCloudScrollX(body["cloudScrollX"].asReal() + 10.0f); + mSky->setCloudScrollY(body["cloudScrollY"].asReal() + 10.0f); + + mSky->setEnableCloudScrollX(!body["cloudScrollXLock"].asBoolean()); + mSky->setEnableCloudScrollY(!body["cloudScrollYLock"].asBoolean()); + + mSky->setStarBrightness(body["starBrightness"].asReal()); + + mSky->set("fade", body["fade"].asReal()); + + //Update this here.. since it isn't a part of WL... go figure + gHippoLimits->skyUseClassicClouds = body["drawClassicClouds"].asBoolean(); + gSavedSettings.setF32("ClassicCloudHeight",body["classicCloudHeight"].asReal()); + gSavedSettings.setF32("ClassicCloudRange",body["classicCloudRange"].asReal()); + + WLSettingsManager::Apply(mSky, mWater, mWaterNormal); +} +}; + +LLHTTPRegistration<WindLightSettingsUpdate> +gHTTPRegistrationWindLightSettingsUpdate( + "/message/WindLightSettingsUpdate"); \ No newline at end of file diff --git a/linden/indra/newview/wlfloatermanager.cpp b/linden/indra/newview/wlfloatermanager.cpp new file mode 100644 index 000000000..19468078e --- /dev/null +++ b/linden/indra/newview/wlfloatermanager.cpp @@ -0,0 +1,281 @@ +/** +* @file wlfloaterwindlightsend.cpp +* @brief WLFloaterWindLightSend class definition +* +* $LicenseInfo:firstyear=2007&license=viewergpl$ +* +* Copyright (c) 2007-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwindlight.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llmultislider.h" +#include "llmultisliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "lluictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llfloaterdaycycle.h" +#include "lltabcontainer.h" +#include "llboost.h" + +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llsavedsettingsglue.h" + +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llpostprocess.h" +#include "hippoLimits.h" +#include "wlfloatermanager.h" +#include "llviewerregion.h" +#include "llviewerparcelmgr.h" +#include "llparcel.h" +#include "wlretrievesettings.h" +#include "wlsettingsmanager.h" +#include "wlfloaterwindlightsend.h" + +#undef max +WLFloaterManager* WLFloaterManager::sWindLight; +std::map<std::string, LLWLParamSet*> WLFloaterManager::mWLParamList; +std::map<std::string, LLWaterParamSet*> WLFloaterManager::mWaterParamList; +std::map<std::string, LLUUID*> WLFloaterManager::mWaterNormalParamList; +std::map<std::string, LLSD> WLFloaterManager::mMinAltParamList; +std::map<std::string, LLSD> WLFloaterManager::mMaxAltParamList; +std::map<std::string, LLSD> WLFloaterManager::mFadeParamList; + +WLFloaterManager::WLFloaterManager() : LLFloater(std::string("windlight manager floater")) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_manager.xml"); + + // load it up + initCallbacks(); +} + +WLFloaterManager::~WLFloaterManager() +{ +} + +void WLFloaterManager::initCallbacks(void) { + + // help buttons + childSetAction("this_parcel", onGetThisParcel, this); + childSetAction("all_parcels", onGetAllParcels, this); + childSetAction("this_region", onGetThisRegion, this); + childSetAction("show", onShow, this); + childSetAction("set_to_current", onSetToCurrent, this); + childSetAction("remove", onRemove, this); +} + +void WLFloaterManager::onClickHelp(void* data) +{ + LLFloaterWindLight* self = LLFloaterWindLight::instance(); + + const std::string xml_alert = *(std::string*)data; + LLNotifications::instance().add(self->contextualNotification(xml_alert)); +} + +void WLFloaterManager::initHelpBtn(const std::string& name, const std::string& xml_alert) +{ + childSetAction(name, onClickHelp, new std::string(xml_alert)); +} + +// static +WLFloaterManager* WLFloaterManager::instance() +{ + if (!sWindLight) + { + sWindLight = new WLFloaterManager(); + sWindLight->open(); + sWindLight->setFocus(TRUE); + } + return sWindLight; +} + +void WLFloaterManager::show() +{ + if (!sWindLight) + { + WLFloaterManager::instance(); + } + else + { + if (sWindLight->getVisible()) + { + sWindLight->close(); + } + else + { + sWindLight->open(); + } + } +} + +bool WLFloaterManager::isOpen() +{ + if (sWindLight != NULL) { + return true; + } + return false; +} + +// virtual +void WLFloaterManager::onClose(bool app_quitting) +{ + if (sWindLight) + { + sWindLight->setVisible(FALSE); + } +} + +void WLFloaterManager::onGetThisRegion(void* userData) +{ + LLSD body; + + //Send the update CAPS to the server + std::string url = gAgent.getRegion()->getCapability("RetrieveWindLightSettings"); + if (!url.empty()) + { + body["RegionID"] = gAgent.getRegion()->getRegionID(); + LLHTTPClient::post(url, body, new retrieveWindlightSettings(body)); + } +} + +void WLFloaterManager::onGetThisParcel(void* userData) +{ + LLSD body; + + //Send the update CAPS to the server + std::string url = gAgent.getRegion()->getCapability("RetrieveWindLightSettings"); + if (!url.empty()) + { + body["ParcelID"] = LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID(); + LLHTTPClient::post(url, body, new retrieveWindlightSettings(body)); + } +} +void WLFloaterManager::onGetAllParcels(void* userData) +{ + LLSD body; + + //Send the update CAPS to the server + std::string url = gAgent.getRegion()->getCapability("RetrieveWindLightSettings"); + if (!url.empty()) + { + body["ParcelID"] = -1; + LLHTTPClient::post(url, body, new retrieveWindlightSettings(body)); + } +} + +void WLFloaterManager::onShow(void* userData) +{ + WLFloaterManager* mgr = WLFloaterManager::instance(); + LLComboBox* comboBox = mgr->getChild<LLComboBox>("WLSettingsCombo"); + std::string name = comboBox->getSelectedItemLabel(); + //Set the new settings up + LLWLParamSet* mSky = mgr->mWLParamList[name]; + LLWaterParamSet* mWater = mgr->mWaterParamList[name]; + LLUUID* mWaterNormal = mgr->mWaterNormalParamList[name]; + if(mSky != NULL && mWater != NULL && mWaterNormal != NULL) + WLSettingsManager::Apply(mSky, mWater, mWaterNormal); +} +void WLFloaterManager::onSetToCurrent(void* userData) +{ + WLFloaterManager* mgr = WLFloaterManager::instance(); + LLComboBox* comboBox = mgr->getChild<LLComboBox>("WLSettingsCombo"); + std::string name = comboBox->getSelectedItemLabel(); + + LLWLParamSet* mSky = mgr->mWLParamList[name]; + LLWaterParamSet* mWater = mgr->mWaterParamList[name]; + LLUUID* mWaterNormal = mgr->mWaterNormalParamList[name]; + LLSD fade = mgr->mFadeParamList[name]; + LLSD minAlt = mgr->mMinAltParamList[name]; + LLSD maxAlt = mgr->mMaxAltParamList[name]; + + int type = 1; + if(name == "(Region Settings)") + { + type = 0; + } + + if(mSky != NULL && mWater != NULL && mWaterNormal != NULL) + WLFloaterWindLightSend::SendSettings(false, type, NULL, *mSky, *mWater, fade, minAlt, maxAlt, *mWaterNormal); +} +void WLFloaterManager::onRemove(void* userData) +{ + WLFloaterManager* mgr = WLFloaterManager::instance(); + LLComboBox* comboBox = mgr->getChild<LLComboBox>("WLSettingsCombo"); + std::string name = comboBox->getSelectedItemLabel(); + + LLWLParamSet* mSky = mgr->mWLParamList[name]; + LLWaterParamSet* mWater = mgr->mWaterParamList[name]; + LLUUID* mWaterNormal = mgr->mWaterNormalParamList[name]; + LLSD fade = mgr->mFadeParamList[name]; + LLSD minAlt = mgr->mMinAltParamList[name]; + LLSD maxAlt = mgr->mMaxAltParamList[name]; + + int type = 1; + if(name == "(Region Settings)") + { + type = 0; + } + + if(mSky != NULL && mWater != NULL && mWaterNormal != NULL) + WLFloaterWindLightSend::SendSettings(true, type, false, *mSky, *mWater, fade, minAlt, maxAlt, *mWaterNormal); +} + + +//static +void WLFloaterManager::UpdateFloater() +{ + WLFloaterManager* mgr = WLFloaterManager::instance(); + LLComboBox* comboBox = mgr->getChild<LLComboBox>("WLSettingsCombo"); + comboBox->clear(); + comboBox->removeall(); + std::map<std::string, LLWLParamSet*>::iterator mIt = + WLFloaterManager::instance()->mWLParamList.begin(); + for(; mIt != WLFloaterManager::instance()->mWLParamList.end(); mIt++) + { + comboBox->add(mIt->first); + } + //Reorder them + comboBox->sortByName(); +} + diff --git a/linden/indra/newview/wlfloatermanager.h b/linden/indra/newview/wlfloatermanager.h new file mode 100644 index 000000000..0a2d0ca88 --- /dev/null +++ b/linden/indra/newview/wlfloatermanager.h @@ -0,0 +1,93 @@ +/** + * @file wlfloaterwindlightsend.h + * @brief WLFloaterWindLightSend class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* + * Menu for adjusting the atmospheric settings of the world + */ + +#include "llfloater.h" + +#include <vector> +#include "llwlparamset.h" + +struct WLColorControl; +struct WLFloatControl; + + +/// Menuing system for all of windlight's functionality +class WLFloaterManager : public LLFloater +{ +public: + + WLFloaterManager(); + virtual ~WLFloaterManager(); + + /// initialize all + void initCallbacks(void); + + /// one and one instance only + static WLFloaterManager* instance(); + + // help button stuff + static void onClickHelp(void* data); + void initHelpBtn(const std::string& name, const std::string& xml_alert); + + static void onGetThisRegion(void* userData); + static void onGetThisParcel(void* userData); + static void onGetAllParcels(void* userData); + static void onShow(void* userData); + static void onSetToCurrent(void* userData); + static void onRemove(void* userData); + + //// menu management + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + static void UpdateFloater(); + static std::map<std::string, LLWLParamSet*> mWLParamList; + static std::map<std::string, LLWaterParamSet*> mWaterParamList; + static std::map<std::string, LLUUID*> mWaterNormalParamList; + static std::map<std::string, LLSD> mMinAltParamList; + static std::map<std::string, LLSD> mMaxAltParamList; + static std::map<std::string, LLSD> mFadeParamList; + +private: + // one instance on the inside + static WLFloaterManager* sWindLight; +}; \ No newline at end of file diff --git a/linden/indra/newview/wlfloaterwindlightsend.cpp b/linden/indra/newview/wlfloaterwindlightsend.cpp new file mode 100644 index 000000000..5244bcd4f --- /dev/null +++ b/linden/indra/newview/wlfloaterwindlightsend.cpp @@ -0,0 +1,300 @@ +/** +* @file wlfloaterwindlightsend.cpp +* @brief WLFloaterWindLightSend class definition +* +* $LicenseInfo:firstyear=2007&license=viewergpl$ +* +* Copyright (c) 2007-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwindlight.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llmultislider.h" +#include "llmultisliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "lluictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llfloaterdaycycle.h" +#include "lltabcontainer.h" +#include "llboost.h" + +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llsavedsettingsglue.h" + +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llpostprocess.h" +#include "hippoLimits.h" +#include "wlfloaterwindlightsend.h" +#include "llviewerregion.h" + +#undef max + + +WLFloaterWindLightSend* WLFloaterWindLightSend::sWindLight = NULL; + +WLFloaterWindLightSend::WLFloaterWindLightSend() : LLFloater(std::string("windlight send floater")) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_remote_save.xml"); + + // load it up + initCallbacks(); +} + +WLFloaterWindLightSend::~WLFloaterWindLightSend() +{ +} + +void WLFloaterWindLightSend::initCallbacks(void) { + + // help buttons + initHelpBtn("fade_help", "HelpBlueHorizon"); + initHelpBtn("override_parcel_default_help", "HelpHazeHorizon"); + initHelpBtn("override_parcel_help", "HelpBlueDensity"); + initHelpBtn("max_altitude_help", "HelpHazeDensity"); + initHelpBtn("min_altitude_help", "HelpDensityMult"); + childSetAction("button_region_send_to_server", onSaveRegionPreset, this); + childSetAction("button_parcel_send_to_server", onSaveParcelPreset, this); +} + +void WLFloaterWindLightSend::onClickHelp(void* data) +{ + LLFloaterWindLight* self = LLFloaterWindLight::instance(); + + const std::string xml_alert = *(std::string*)data; + LLNotifications::instance().add(self->contextualNotification(xml_alert)); +} + +void WLFloaterWindLightSend::initHelpBtn(const std::string& name, const std::string& xml_alert) +{ + childSetAction(name, onClickHelp, new std::string(xml_alert)); +} + +// static +WLFloaterWindLightSend* WLFloaterWindLightSend::instance() +{ + if (!sWindLight) + { + sWindLight = new WLFloaterWindLightSend(); + sWindLight->open(); + sWindLight->setFocus(TRUE); + } + return sWindLight; +} + +void WLFloaterWindLightSend::show() +{ + if (!sWindLight) + { + WLFloaterWindLightSend::instance(); + } + else + { + if (sWindLight->getVisible()) + { + sWindLight->close(); + } + else + { + sWindLight->open(); + } + } +} + +bool WLFloaterWindLightSend::isOpen() +{ + if (sWindLight != NULL) { + return true; + } + return false; +} + +// virtual +void WLFloaterWindLightSend::onClose(bool app_quitting) +{ + if (sWindLight) + { + sWindLight->setVisible(FALSE); + } +} + +void WLFloaterWindLightSend::onSaveRegionPreset(void* userData) +{ + int RegionType = 0; + SendSettings(false, RegionType, + WLFloaterWindLightSend::instance()->childGetValue("override_parcel"), + LLWLParamManager::instance()->mCurParams, + LLWaterParamManager::instance()->mCurParams, + WLFloaterWindLightSend::instance()->childGetValue("Fade"), + WLFloaterWindLightSend::instance()->childGetValue("min_altitude"), + WLFloaterWindLightSend::instance()->childGetValue("max_altitude"), + LLWaterParamManager::instance()->getNormalMapID()); +} +void WLFloaterWindLightSend::onSaveParcelPreset(void* userData) +{ + int ParcelType = 1; + SendSettings(false, ParcelType, false, LLWLParamManager::instance()->mCurParams, + LLWaterParamManager::instance()->mCurParams, + WLFloaterWindLightSend::instance()->childGetValue("Fade"), + WLFloaterWindLightSend::instance()->childGetValue("min_altitude"), + WLFloaterWindLightSend::instance()->childGetValue("max_altitude"), + LLWaterParamManager::instance()->getNormalMapID()); +} +void WLFloaterWindLightSend::SendSettings(bool remove, int type, bool overrideParcels, + LLWLParamSet mSky, LLWaterParamSet mWater, + LLSD fade, LLSD minAlt, LLSD maxAlt, + LLUUID normalMap) +{ + LLSD body; + std::string url = gAgent.getRegion()->getCapability("DispatchWindLightSettings"); + if (!url.empty()) + { + bool error; + + body["type"] = type; + body["remove"] = remove; + body["fade"] = fade; + body["maxEffectiveAltitude"] = maxAlt; + body["minEffectiveAltitude"] = minAlt; + if(overrideParcels == true || overrideParcels == false) + body["overrideParcels"] = overrideParcels; + + LLVector4 v = mSky.getVector("ambient", error); + body["ambientX"] = v[0] / 3.0; + body["ambientY"] = v[1] / 3.0; + body["ambientZ"] = v[2] / 3.0; + body["ambientW"] = v[3] / 3.0; + + body["eastAngle"] = mSky.getEastAngle(); + body["sunMoonPosition"] = mSky.getSunAngle(); + + v = mSky.getVector("sunlight_color",error); + body["sunMoonColorX"] = v[0] / 3.0; + body["sunMoonColorY"] = v[1] / 3.0; + body["sunMoonColorZ"] = v[2] / 3.0; + body["sunMoonColorW"] = v[3] / 3.0; + + v = mSky.getVector("blue_horizon",error); + body["horizonX"] = v[0] / 2.0; + body["horizonY"] = v[1] / 2.0; + body["horizonZ"] = v[2] / 2.0; + body["horizonW"] = v[3] / 2.0; + + v = mSky.getVector("blue_density",error); + body["blueDensityX"] = v[0]; + body["blueDensityY"] = v[1]; + body["blueDensityZ"] = v[2]; + + v = mSky.getVector("haze_horizon",error); + body["hazeHorizon"] = v[0]; + + body["hazeDensity"] = mSky.getFloat("haze_density",error); + body["cloudCoverage"] = mSky.getFloat("cloud_shadow",error); + body["densityMultiplier"] = mSky.getFloat("density_multiplier",error) * 1000; + body["distanceMultiplier"] = mSky.getFloat("distance_multiplier",error); + body["maxAltitude"] = mSky.getFloat("max_y",error); + + v = mSky.getVector("cloud_color",error); + body["cloudColorX"] = v[0]; + body["cloudColorY"] = v[1]; + body["cloudColorZ"] = v[2]; + body["cloudColorW"] = v[3]; + + v = mSky.getVector("cloud_pos_density1",error); + body["cloudXYDensityX"] = v[0]; + body["cloudXYDensityY"] = v[1]; + body["cloudXYDensityZ"] = v[2]; + + v = mSky.getVector("cloud_pos_density2",error); + body["cloudDetailXYDensityX"] = v[0]; + body["cloudDetailXYDensityY"] = v[1]; + body["cloudDetailXYDensityZ"] = v[2]; + + v = mSky.getVector("glow",error); + body["sunGlowSize"] = -((v[0]/ 20) - 2); + body["sunGlowFocus"] = -v[2] / 5; + + body["cloudScale"] = mSky.getFloat("cloud_scale",error); + body["sceneGamma"] = mSky.getFloat("gamma",error); + body["cloudScrollX"] = mSky.getCloudScrollX() - 10; + body["cloudScrollY"] = mSky.getCloudScrollY() - 10; + body["cloudScrollXLock"] = !mSky.getEnableCloudScrollX(); + body["cloudScrollYLock"] = !mSky.getEnableCloudScrollY(); + body["starBrightness"] = mSky.getStarBrightness(); + body["drawClassicClouds"] = gHippoLimits->skyUseClassicClouds; + body["classicCloudHeight"] = gSavedSettings.getF32("ClassicCloudHeight"); + body["classicCloudRange"] = gSavedSettings.getF32("ClassicCloudRange"); + + LLVector3 vvv = mWater.getVector3("normScale",error); + body["reflectionWaveletScaleX"] = vvv[0]; + body["reflectionWaveletScaleY"] = vvv[1]; + body["reflectionWaveletScaleZ"] = vvv[2]; + + v = mWater.getVector4("waterFogColor",error); + body["waterColorX"] = v[0] * 256.0; + body["waterColorY"] = v[1] * 256.0; + body["waterColorZ"] = v[2] * 256.0; + body["waterColorW"] = v[3] * 256.0; + + body["waterFogDensityExponent"] = mWater.getFloat("waterFogDensity", error); + body["underwaterFogModifier"] = mWater.getFloat("underWaterFogMod", error); + + body["fresnelScale"] = mWater.getFloat("fresnelScale", error); + body["fresnelOffset"] = mWater.getFloat("fresnelOffset", error); + body["refractScaleAbove"] = mWater.getFloat("scaleAbove", error); + body["refractScaleBelow"] = mWater.getFloat("scaleBelow", error); + body["blurMultiplier"] = mWater.getFloat("blurMultiplier", error); + + LLVector2 vv = mWater.getVector2("wave1Dir",error); + body["littleWaveDirectionX"] = vv[0]; + body["littleWaveDirectionY"] = vv[1]; + + vv = mWater.getVector2("wave2Dir",error); + body["bigWaveDirectionX"] = vv[0]; + body["bigWaveDirectionY"] = vv[1]; + + body["normalMapTexture"] = normalMap; + + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } +} \ No newline at end of file diff --git a/linden/indra/newview/wlfloaterwindlightsend.h b/linden/indra/newview/wlfloaterwindlightsend.h new file mode 100644 index 000000000..acd438606 --- /dev/null +++ b/linden/indra/newview/wlfloaterwindlightsend.h @@ -0,0 +1,88 @@ +/** + * @file wlfloaterwindlightsend.h + * @brief WLFloaterWindLightSend class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* + * Menu for adjusting the atmospheric settings of the world + */ + +#include "llfloater.h" + +#include <vector> +#include "llwlparamset.h" +#include "llwaterparamset.h" +#include "llsd.h" + +struct WLColorControl; +struct WLFloatControl; + + +/// Menuing system for all of windlight's functionality +class WLFloaterWindLightSend : public LLFloater +{ +public: + + WLFloaterWindLightSend(); + virtual ~WLFloaterWindLightSend(); + + /// initialize all + void initCallbacks(void); + + /// one and one instance only + static WLFloaterWindLightSend* instance(); + + // help button stuff + static void onClickHelp(void* data); + void initHelpBtn(const std::string& name, const std::string& xml_alert); + + static void onSaveParcelPreset(void* userData); + static void onSaveRegionPreset(void* userData); + + //// menu management + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + static void SendSettings(bool remove, int type, bool overrideParcel, + LLWLParamSet mSky, LLWaterParamSet mWater, + LLSD Fade, LLSD minAlt, LLSD maxAlt, + LLUUID normalMap); + +private: + // one instance on the inside + static WLFloaterWindLightSend* sWindLight; +}; \ No newline at end of file diff --git a/linden/indra/newview/wlretrievesettings.cpp b/linden/indra/newview/wlretrievesettings.cpp new file mode 100644 index 000000000..ca91ba2ae --- /dev/null +++ b/linden/indra/newview/wlretrievesettings.cpp @@ -0,0 +1,238 @@ +/** +* @file wlfloaterwindlightsend.cpp +* @brief WLFloaterWindLightSend class definition +* +* $LicenseInfo:firstyear=2007&license=viewergpl$ +* +* Copyright (c) 2007-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwindlight.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llmultislider.h" +#include "llmultisliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "lluictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llfloaterdaycycle.h" +#include "lltabcontainer.h" +#include "llboost.h" + +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llsavedsettingsglue.h" + +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llpostprocess.h" +#include "hippoLimits.h" +#include "wlfloaterwindlightsend.h" +#include "llviewerregion.h" +#include "wlsettingsmanager.h" +#include "lightshare.h" + +#include "linden_common.h" +#include "llviewercontrol.h" +#include "message.h" +#include "meta7windlight.h" +#include "wlretrievesettings.h" +#include "wlfloatermanager.h" + +#undef max + +//If we get back a normal response, handle it here +void retrieveWindlightSettings::result(const LLSD& content) +{ + //Clear the lists first + WLFloaterManager::mMinAltParamList.clear(); + WLFloaterManager::mMaxAltParamList.clear(); + WLFloaterManager::mFadeParamList.clear(); + WLFloaterManager::mWLParamList.clear(); + WLFloaterManager::mWaterParamList.clear(); + WLFloaterManager::mWaterNormalParamList.clear(); + + for(LLSD::array_const_iterator wls = content["WindLight"].beginArray(); + wls != content["WindLight"].endArray(); + ++wls) + { + LLSD windLightLLSD = *wls; + LLWaterParamSet* mWater; + LLWLParamSet* mSky; + LLUUID* mWaterNormal; + + mWater = new LLWaterParamSet(); + mSky = new LLWLParamSet(); + mWaterNormal = new LLUUID(); + + mWater->set("waterFogColor", + windLightLLSD["waterColorX"].asReal() / 256.f, + windLightLLSD["waterColorY"].asReal() / 256.f, + windLightLLSD["waterColorZ"].asReal() / 256.f, + windLightLLSD["waterColorW"].asReal() / 256.f); + mWater->set("waterFogDensity", windLightLLSD["waterFogDensityExponent"].asReal()); + mWater->set("underWaterFogMod", windLightLLSD["underwaterFogModifier"].asReal()); + mWater->set("normScale", windLightLLSD["reflectionWaveletScaleX"].asReal(), + windLightLLSD["reflectionWaveletScaleY"].asReal(), + windLightLLSD["reflectionWaveletScaleZ"].asReal()); + mWater->set("fresnelScale", windLightLLSD["fresnelScale"].asReal()); + mWater->set("fresnelOffset", windLightLLSD["fresnelOffset"].asReal()); + mWater->set("scaleAbove", windLightLLSD["refractScaleAbove"].asReal()); + mWater->set("scaleBelow", windLightLLSD["refractScaleBelow"].asReal()); + mWater->set("blurMultiplier", windLightLLSD["blurMultiplier"].asReal()); + mWater->set("wave2Dir", windLightLLSD["bigWaveDirectionX"].asReal(), + windLightLLSD["bigWaveDirectionY"].asReal()); + mWater->set("wave1Dir", windLightLLSD["littleWaveDirectionX"].asReal(), + windLightLLSD["littleWaveDirectionY"].asReal()); + mWaterNormal->parseUUID(windLightLLSD["normalMapTexture"].asUUID().asString(), mWaterNormal); + + mSky->setSunAngle(windLightLLSD["sunMoonPosition"].asReal()); + mSky->setEastAngle(windLightLLSD["eastAngle"].asReal()); + + mSky->set("sunlight_color", + windLightLLSD["sunMoonColorX"].asReal() * 3.0f, + windLightLLSD["sunMoonColorY"].asReal() * 3.0f, + windLightLLSD["sunMoonColorZ"].asReal() * 3.0f, + windLightLLSD["sunMoonColorW"].asReal() * 3.0f); + + mSky->set("ambient", + windLightLLSD["ambientX"].asReal() * 3.0f, + windLightLLSD["ambientY"].asReal() * 3.0f, + windLightLLSD["ambientZ"].asReal() * 3.0f, + windLightLLSD["ambientW"].asReal() * 3.0f); + + mSky->set("blue_horizon", + windLightLLSD["horizonX"].asReal() * 2.0f, + windLightLLSD["horizonY"].asReal() * 2.0f, + windLightLLSD["horizonZ"].asReal() * 2.0f, + windLightLLSD["horizonW"].asReal() * 2.0f); + + mSky->set("blue_density", + windLightLLSD["blueDensityX"].asReal(), + windLightLLSD["blueDensityY"].asReal(), + windLightLLSD["blueDensityZ"].asReal(), + 1.0); + + mSky->set("haze_horizon", + windLightLLSD["hazeHorizon"].asReal(), + windLightLLSD["hazeHorizon"].asReal(), + windLightLLSD["hazeHorizon"].asReal(), + 1.f); + + mSky->set("haze_density", + windLightLLSD["hazeDensity"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("cloud_shadow", + windLightLLSD["cloudCoverage"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("density_multiplier", + windLightLLSD["densityMultiplier"].asReal() / 1000.0f, + 0.f, 0.f, 1.f); + + mSky->set("distance_multiplier", + windLightLLSD["distanceMultiplier"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("max_y", + windLightLLSD["maxAltitude"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("cloud_color", + windLightLLSD["cloudColorX"].asReal(), + windLightLLSD["cloudColorY"].asReal(), + windLightLLSD["cloudColorZ"].asReal(), + windLightLLSD["cloudColorW"].asReal()); + + mSky->set("cloud_pos_density1", + windLightLLSD["cloudXYDensityX"].asReal(), + windLightLLSD["cloudXYDensityY"].asReal(), + windLightLLSD["cloudXYDensityZ"].asReal(), + 1.f); + + mSky->set("cloud_pos_density2", + windLightLLSD["cloudDetailXYDensityX"].asReal(), + windLightLLSD["cloudDetailXYDensityY"].asReal(), + windLightLLSD["cloudDetailXYDensityZ"].asReal(), + 1.f); + + mSky->set("cloud_scale", + windLightLLSD["cloudScale"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("gamma", + windLightLLSD["sceneGamma"].asReal(), + 0.f, 0.f, 1.f); + + mSky->set("glow", + (2 - windLightLLSD["sunGlowSize"].asReal()) * 20, + 0.f, + -windLightLLSD["sunGlowFocus"].asReal() * 5, + 1.f); + + mSky->setCloudScrollX(windLightLLSD["cloudScrollX"].asReal() + 10.0f); + mSky->setCloudScrollY(windLightLLSD["cloudScrollY"].asReal() + 10.0f); + + mSky->setEnableCloudScrollX(!windLightLLSD["cloudScrollXLock"].asBoolean()); + mSky->setEnableCloudScrollY(!windLightLLSD["cloudScrollYLock"].asBoolean()); + + mSky->setStarBrightness(windLightLLSD["starBrightness"].asReal()); + + mSky->set("fade", windLightLLSD["fade"].asReal()); + + WLFloaterManager::mMinAltParamList[windLightLLSD["Name"].asString()] = windLightLLSD["minEffectiveAltitude"].asReal(); + WLFloaterManager::mMaxAltParamList[windLightLLSD["Name"].asString()] = windLightLLSD["maxEffectiveAltitude"].asReal(); + WLFloaterManager::mFadeParamList[windLightLLSD["Name"].asString()] = windLightLLSD["fade"].asReal(); + + WLFloaterManager::mWLParamList[windLightLLSD["Name"].asString()] = mSky; + WLFloaterManager::mWaterParamList[windLightLLSD["Name"].asString()] = mWater; + WLFloaterManager::mWaterNormalParamList[windLightLLSD["Name"].asString()] = mWaterNormal; + } + WLFloaterManager::UpdateFloater(); +} + +//If we get back an error (not found, etc...), handle it here +void retrieveWindlightSettings::error(U32 status, const std::string& reason) +{ + LL_INFOS("Inventory") << "retrieveWindlightSettings::error " + << status << ": " << reason << LL_ENDL; +} \ No newline at end of file diff --git a/linden/indra/newview/wlretrievesettings.h b/linden/indra/newview/wlretrievesettings.h new file mode 100644 index 000000000..d75d0d16e --- /dev/null +++ b/linden/indra/newview/wlretrievesettings.h @@ -0,0 +1,59 @@ +/** + * @file wlfloaterwindlightsend.h + * @brief WLFloaterWindLightSend class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* + * Menu for adjusting the atmospheric settings of the world + */ + + +#include <string> +#include "llwlparamset.h" +#include "llwaterparamset.h" +#include "lluuid.h" + +class LLSD; +class LLTimer; +class LLUUID; +class LLWaterParamSet; +class LLWLParamSet; + + +/// Menuing system for all of windlight's functionality +class retrieveWindlightSettings: public LLHTTPClient::Responder +{ +public: + retrieveWindlightSettings(const LLSD& request_sd) : mRequestSD(request_sd) {}; + void result(const LLSD& content); + void error(U32 status, const std::string& reason); +protected: + LLSD mRequestSD; +}; \ No newline at end of file diff --git a/linden/indra/newview/wlsettingsmanager.cpp b/linden/indra/newview/wlsettingsmanager.cpp new file mode 100644 index 000000000..78516df42 --- /dev/null +++ b/linden/indra/newview/wlsettingsmanager.cpp @@ -0,0 +1,249 @@ +/** +* @file wlfloaterwindlightsend.cpp +* @brief WLFloaterWindLightSend class definition +* +* $LicenseInfo:firstyear=2007&license=viewergpl$ +* +* Copyright (c) 2007-2009, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwindlight.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llmultislider.h" +#include "llmultisliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "lluictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llfloaterdaycycle.h" +#include "lltabcontainer.h" +#include "llboost.h" + +#include "llagent.h" +#include "llinventorymodel.h" +#include "llviewerinventory.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llsavedsettingsglue.h" + +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llpostprocess.h" +#include "hippoLimits.h" +#include "wlfloaterwindlightsend.h" +#include "llviewerregion.h" +#include "wlsettingsmanager.h" +#include "lightshare.h" + +#include "linden_common.h" +#include "llviewercontrol.h" +#include "message.h" +#include "meta7windlight.h" + +#undef max + +const std::string WLSettingsManager::wlWaterPresetName = "(Region settings)"; +const std::string WLSettingsManager::wlSkyPresetName = "(Region settings)"; + +LLTimer* WLSettingsManager::wlIgnoreTimer = new LLTimer(); +bool WLSettingsManager::wlIgnoreRegion = false; +LLWaterParamSet* WLSettingsManager::mWater = NULL; +LLWLParamSet* WLSettingsManager::mSky = NULL; +LLUUID* WLSettingsManager::mWaterNormal = NULL; + +void WLSettingsManager::Apply( LLWLParamSet* Sky, LLWaterParamSet* Water, LLUUID* WaterNormal ) +{ + if( gSavedSettings.getU32("LightShareAllowed") <= WindlightMessage::LIGHTSHARE_NEVER ) + return; + + std::string water = LLWaterParamManager::instance()->mCurParams.mName; + std::string sky = LLWLParamManager::instance()->mCurParams.mName; + + // If they are using region settings already, or LightShare is + // always allowed, just apply the new settings, don't bother asking. + if( gSavedSettings.getU32("LightShareAllowed") == WindlightMessage::LIGHTSHARE_ALWAYS || + (sky == wlSkyPresetName && water == wlWaterPresetName) ) + { + mSky = Sky; + mWater = Water; + mWaterNormal = WaterNormal; + Apply(); + return; + } + + if( !wlignoreTimerHasExpired() ) + { + // The user recently ignored a windlight message, so ignore + // this one too, and restart the timer. + wlrestartIgnoreTimer(); + return; + } + + if(wlIgnoreRegion) + { + // We are ignoring new settings until user enters a new region. + return; + } + + if( gSavedSettings.getU32("LightShareAllowed") == WindlightMessage::LIGHTSHARE_ASK && + mSky == NULL && mWater == NULL) + { + // No most recent, so store this and create notification + // asking the user whether to apply or not. + mSky = Sky; + mWater = Water; + mWaterNormal = WaterNormal; + LLNotifications::instance().add("ConfirmLightShare", LLSD(), LLSD(), + boost::bind(&wlapplyCallback, _1, _2)); + } + else + { + // No new notification (to avoid spamming the user, we do keep the saves from above) + mSky = Sky; + mWater = Water; + mWaterNormal = WaterNormal; + } +} + +// static +bool WLSettingsManager::wlapplyCallback(const LLSD& notification, + const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + + switch(option) + { + case 0:{ + // "Apply" + Apply(); + break; + } + case 1:{ + // "Not Now", ignore until the region stops spamming + wlrestartIgnoreTimer(); + break; + } + case 2:{ + // "Ignore", ignore all until user leaves the region + wlIgnoreRegion = true; + break; + } + } + return false; +} + +//static +void WLSettingsManager::Apply() +{ + LLWaterParamManager* water_mgr = LLWaterParamManager::instance(); + LLWLParamManager* sky_mgr = LLWLParamManager::instance(); + + F32 fade = 0; //Instant + bool error; + fade = mSky->getFloat("fade", error); + + mWater->mName = wlWaterPresetName; + if(fade != 0) + { + LLWaterParamSet oldWset = water_mgr->mCurParams; + //This still needs done so that we update right, but load it to the old + water_mgr->removeParamSet( wlWaterPresetName, false ); + water_mgr->addParamSet( wlWaterPresetName, oldWset ); + water_mgr->savePreset( wlWaterPresetName ); + water_mgr->loadPreset( wlWaterPresetName, true ); + water_mgr->setNormalMapID( *mWaterNormal ); + //Then mix with the new + water_mgr->SetMixTime(mWater, fade); + } + else + { + //Instant if fade is 0 + water_mgr->removeParamSet( wlWaterPresetName, false ); + water_mgr->addParamSet( wlWaterPresetName, *mWater ); + water_mgr->savePreset( wlWaterPresetName ); + water_mgr->loadPreset( wlWaterPresetName, true ); + water_mgr->setNormalMapID( *mWaterNormal ); + } + + mSky->mName = wlSkyPresetName; + if(fade != 0) + { + LLWLParamSet oldset = sky_mgr->mCurParams; + //This still needs done so that we update right, but load it to the old + sky_mgr->removeParamSet( wlSkyPresetName, true ); + sky_mgr->addParamSet( wlSkyPresetName, oldset ); + sky_mgr->savePreset( wlSkyPresetName ); + sky_mgr->loadPreset( wlSkyPresetName, true ); + //Then mix with the new + sky_mgr->SetMixTime(mSky, fade); + } + else + { + //Instant if fade is 0 + sky_mgr->mAnimator.mIsRunning = false; + sky_mgr->mAnimator.mUseLindenTime = false; + sky_mgr->removeParamSet( wlSkyPresetName, false ); + sky_mgr->addParamSet( wlSkyPresetName, *mSky ); + sky_mgr->savePreset( wlSkyPresetName ); + sky_mgr->loadPreset( wlSkyPresetName, true ); + } + + mSky = NULL; + mWater = NULL; + mWaterNormal = NULL; +} + +// static +void WLSettingsManager::wlresetRegion() +{ + wlIgnoreRegion = false; +} + +// static +void WLSettingsManager::wlrestartIgnoreTimer() +{ + F32 time = gSavedSettings.getF32("LightShareIgnoreTimer"); + wlIgnoreTimer->start(); + wlIgnoreTimer->setTimerExpirySec( (time < 0) ? 0 : time ); +} + +// static +bool WLSettingsManager::wlignoreTimerHasExpired() +{ + return wlIgnoreTimer->hasExpired(); +} \ No newline at end of file diff --git a/linden/indra/newview/wlsettingsmanager.h b/linden/indra/newview/wlsettingsmanager.h new file mode 100644 index 000000000..5a0e9e737 --- /dev/null +++ b/linden/indra/newview/wlsettingsmanager.h @@ -0,0 +1,90 @@ +/** + * @file wlfloaterwindlightsend.h + * @brief WLFloaterWindLightSend class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* + * Menu for adjusting the atmospheric settings of the world + */ + +#ifndef WINDLIGHTSETTINGSMANAGER_H +#define WINDLIGHTSETTINGSMANAGER_H + +#include <string> +#include "llwlparamset.h" +#include "llwaterparamset.h" +#include "lluuid.h" + +class LLSD; +class LLTimer; +class LLUUID; +class LLWaterParamSet; +class LLWLParamSet; + + +/// Menuing system for all of windlight's functionality +class WLSettingsManager +{ +public: + + static LLTimer* wlIgnoreTimer; + static bool wlIgnoreRegion; + + // Called after the user has entered a new region, to reset the + // "ignore while in this region" state. + static void wlresetRegion(); + + static void Apply( LLWLParamSet* Sky, LLWaterParamSet* Water, LLUUID* WaterNormal ); + + // Callback when the user interacts with the notification. + static bool wlapplyCallback(const LLSD& notification, + const LLSD& response); + + static LLWaterParamSet* mWater; + static LLWLParamSet* mSky; + static LLUUID* mWaterNormal; + +private: + static void Apply(); + + // The name of the water preset where the region settings are stored. + static const std::string wlWaterPresetName; + + // The name of the sky preset where the region settings are stored. + static const std::string wlSkyPresetName; + + // Restart the timer for temporarily ignoring settings. + static void wlrestartIgnoreTimer(); + + // Returns true if the ignore timer has expired (i.e. new settings + // should not be ignored anymore). + static bool wlignoreTimerHasExpired(); +}; +#endif \ No newline at end of file From 72c4d73706267a32bb31d93e14425b1c0c8a5715 Mon Sep 17 00:00:00 2001 From: RevolutionSmythe <asdfisbetterthanjkl@gmail.com> Date: Sat, 23 Oct 2010 20:51:07 -0500 Subject: [PATCH 108/239] Merges the Message log and Message builder from Inertia in. --- linden/indra/llmessage/llcircuit.cpp | 11 + linden/indra/llmessage/llcircuit.h | 3 + linden/indra/llmessage/llmessagelog.cpp | 54 + linden/indra/llmessage/llmessagelog.h | 41 + linden/indra/llmessage/llpacketring.cpp | 5 + .../llmessage/lltemplatemessagereader.cpp | 50 +- .../indra/llmessage/lltemplatemessagereader.h | 16 +- linden/indra/llmessage/message.cpp | 18 +- linden/indra/llmessage/message.h | 18 +- linden/indra/llui/llscrolllistctrl.cpp | 17 + linden/indra/llui/llscrolllistctrl.h | 11 + .../indra/newview/llfloatermessagebuilder.cpp | 978 ++++++++++++++++++ .../indra/newview/llfloatermessagebuilder.h | 55 + linden/indra/newview/llfloatermessagelog.cpp | 962 +++++++++++++++++ linden/indra/newview/llfloatermessagelog.h | 84 ++ linden/indra/newview/llviewermenu.cpp | 45 + .../skins/default/xui/en-us/menu_viewer.xml | 9 + 17 files changed, 2358 insertions(+), 19 deletions(-) create mode 100644 linden/indra/llmessage/llmessagelog.cpp create mode 100644 linden/indra/llmessage/llmessagelog.h create mode 100644 linden/indra/newview/llfloatermessagebuilder.cpp create mode 100644 linden/indra/newview/llfloatermessagebuilder.h create mode 100644 linden/indra/newview/llfloatermessagelog.cpp create mode 100644 linden/indra/newview/llfloatermessagelog.h diff --git a/linden/indra/llmessage/llcircuit.cpp b/linden/indra/llmessage/llcircuit.cpp index 725425cc2..0ff5093ca 100644 --- a/linden/indra/llmessage/llcircuit.cpp +++ b/linden/indra/llmessage/llcircuit.cpp @@ -1231,6 +1231,17 @@ void LLCircuit::getCircuitRange( first = mCircuitData.upper_bound(key); } +// <edit> +std::vector<LLCircuitData*> LLCircuit::getCircuitDataList() +{ + std::vector<LLCircuitData*> list; + circuit_data_map::iterator end = mCircuitData.end(); + for(circuit_data_map::iterator iter = mCircuitData.begin(); iter != end; ++iter) + list.push_back((*iter).second); + return list; +} +// </edit> + TPACKETID LLCircuitData::nextPacketOutID() { mPacketsOut++; diff --git a/linden/indra/llmessage/llcircuit.h b/linden/indra/llmessage/llcircuit.h index e373cb116..379453e19 100644 --- a/linden/indra/llmessage/llcircuit.h +++ b/linden/indra/llmessage/llcircuit.h @@ -336,6 +336,9 @@ class LLCircuit // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up. circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data circuit_data_map mSendAckMap; // Map of circuits which need to send acks + + std::vector<LLCircuitData*> getCircuitDataList(); + protected: circuit_data_map mCircuitData; diff --git a/linden/indra/llmessage/llmessagelog.cpp b/linden/indra/llmessage/llmessagelog.cpp new file mode 100644 index 000000000..965b8c0de --- /dev/null +++ b/linden/indra/llmessage/llmessagelog.cpp @@ -0,0 +1,54 @@ +// <edit> +#include "llmessagelog.h" + +LLMessageLogEntry::LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, U8* data, S32 data_size) +: mType(type), + mFromHost(from_host), + mToHost(to_host), + mDataSize(data_size) +{ + if(data) + { + mData.resize(data_size); + memcpy(&(mData[0]), data, data_size); + } +} +LLMessageLogEntry::LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, std::vector<U8> data, S32 data_size) +: mType(type), + mFromHost(from_host), + mToHost(to_host), + mDataSize(data_size), + mData(data) +{ +} +LLMessageLogEntry::~LLMessageLogEntry() +{ +} +U32 LLMessageLog::sMaxSize = 4096; // testzone fixme todo boom +std::deque<LLMessageLogEntry> LLMessageLog::sDeque; +void (*(LLMessageLog::sCallback))(LLMessageLogEntry); +void LLMessageLog::setMaxSize(U32 size) +{ + sMaxSize = size; + while(sDeque.size() > sMaxSize) + sDeque.pop_front(); +} +void LLMessageLog::setCallback(void (*callback)(LLMessageLogEntry)) +{ + sCallback = callback; +} +void LLMessageLog::log(LLHost from_host, LLHost to_host, U8* data, S32 data_size) +{ + LLMessageLogEntry entry = LLMessageLogEntry(LLMessageLogEntry::TEMPLATE, from_host, to_host, data, data_size); + if(!entry.mDataSize || !entry.mData.size()) return; + if(sCallback) sCallback(entry); + if(!sMaxSize) return; + sDeque.push_back(entry); + if(sDeque.size() > sMaxSize) + sDeque.pop_front(); +} +std::deque<LLMessageLogEntry> LLMessageLog::getDeque() +{ + return sDeque; +} +// </edit> diff --git a/linden/indra/llmessage/llmessagelog.h b/linden/indra/llmessage/llmessagelog.h new file mode 100644 index 000000000..5046d808b --- /dev/null +++ b/linden/indra/llmessage/llmessagelog.h @@ -0,0 +1,41 @@ +// <edit> +#ifndef LL_LLMESSAGELOG_H +#define LL_LLMESSAGELOG_H +#include "stdtypes.h" +#include "llhost.h" +#include <queue> +#include <string.h> + +class LLMessageSystem; +class LLMessageLogEntry +{ +public: + enum EType + { + TEMPLATE, + HTTP_REQUEST, + HTTP_RESPONSE + }; + LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, U8* data, S32 data_size); + LLMessageLogEntry(EType type, LLHost from_host, LLHost to_host, std::vector<U8> data, S32 data_size); + ~LLMessageLogEntry(); + EType mType; + LLHost mFromHost; + LLHost mToHost; + S32 mDataSize; + std::vector<U8> mData; +}; +class LLMessageLog +{ +public: + static void setMaxSize(U32 size); + static void setCallback(void (*callback)(LLMessageLogEntry)); + static void log(LLHost from_host, LLHost to_host, U8* data, S32 data_size); + static std::deque<LLMessageLogEntry> getDeque(); +private: + static U32 sMaxSize; + static void (*sCallback)(LLMessageLogEntry); + static std::deque<LLMessageLogEntry> sDeque; +}; +#endif +// </edit> diff --git a/linden/indra/llmessage/llpacketring.cpp b/linden/indra/llmessage/llpacketring.cpp index 35d5aac77..7dcb606ce 100644 --- a/linden/indra/llmessage/llpacketring.cpp +++ b/linden/indra/llmessage/llpacketring.cpp @@ -40,6 +40,8 @@ #include "timing.h" #include "llrand.h" #include "u64.h" +#include "llmessagelog.h" +#include "message.h" /////////////////////////////////////////////////////////// LLPacketRing::LLPacketRing () : @@ -246,6 +248,9 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap) BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host) { + //<edit> + LLMessageLog::log(LLHost(16777343, gMessageSystem->getListenPort()), host, (U8*)send_buffer, buf_size); + //</edit> BOOL status = TRUE; if (!mUseOutThrottle) { diff --git a/linden/indra/llmessage/lltemplatemessagereader.cpp b/linden/indra/llmessage/lltemplatemessagereader.cpp index d8904a9ce..9f68fe979 100644 --- a/linden/indra/llmessage/lltemplatemessagereader.cpp +++ b/linden/indra/llmessage/lltemplatemessagereader.cpp @@ -449,7 +449,10 @@ S32 LLTemplateMessageReader::getMessageSize() const // Returns template for the message contained in buffer BOOL LLTemplateMessageReader::decodeTemplate( const U8* buffer, S32 buffer_size, // inputs - LLMessageTemplate** msg_template ) // outputs + // <edit> + //LLMessageTemplate** msg_template ) // outputs + LLMessageTemplate** msg_template, BOOL custom) + // </edit> { const U8* header = buffer + LL_PACKET_ID_SIZE; @@ -491,6 +494,9 @@ BOOL LLTemplateMessageReader::decodeTemplate( } else // bogus packet received (too short) { + // <edit> + if(!custom) + // </edit> llwarns << "Packet with unusable length received (too short): " << buffer_size << llendl; return(FALSE); @@ -503,9 +509,16 @@ BOOL LLTemplateMessageReader::decodeTemplate( } else { + // <edit> + if(!custom) + { + // </edit> llwarns << "Message #" << std::hex << num << std::dec << " received but not registered!" << llendl; gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE); + // <edit> + } + // </edit> return(FALSE); } @@ -532,7 +545,8 @@ void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S3 } // decode a given message -BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender ) +BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender, BOOL custom) +// </edit> { llassert( mReceiveSize >= 0 ); llassert( mCurrentRMessageTemplate); @@ -594,6 +608,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender } else { + // <edit> + if(!custom) + // </edit> llerrs << "Unknown block type" << llendl; return FALSE; } @@ -640,6 +657,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender if ((decode_pos + data_size) > mReceiveSize) { + // <edit> + if(!custom) + // </edit> logRanOffEndOfPacket(sender, decode_pos, data_size); // default to 0 length variable blocks @@ -676,6 +696,9 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender // so, copy data pointer and set data size to fixed size if ((decode_pos + mvci.getSize()) > mReceiveSize) { + // <edit> + if(!custom) + // </edit> logRanOffEndOfPacket(sender, decode_pos, mvci.getSize()); // default to 0s. @@ -703,7 +726,10 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl; return FALSE; } - + + // <edit> + if(!custom) + // </edit> { static LLTimer decode_timer; @@ -756,14 +782,26 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender return TRUE; } +// <edit> +LLMessageTemplate* LLTemplateMessageReader::getTemplate() +{ + return mCurrentRMessageTemplate; +} +// </edit> + BOOL LLTemplateMessageReader::validateMessage(const U8* buffer, S32 buffer_size, const LLHost& sender, - bool trusted) + bool trusted, + BOOL custom) { mReceiveSize = buffer_size; - BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); - if(valid) + // <edit> + //BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); + BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate, custom ); + //if(result) + if(valid && !custom) + // </edit> { mCurrentRMessageTemplate->mReceiveCount++; //lldebugs << "MessageRecvd:" diff --git a/linden/indra/llmessage/lltemplatemessagereader.h b/linden/indra/llmessage/lltemplatemessagereader.h index ab06ab433..0eef93a76 100644 --- a/linden/indra/llmessage/lltemplatemessagereader.h +++ b/linden/indra/llmessage/lltemplatemessagereader.h @@ -102,28 +102,32 @@ class LLTemplateMessageReader : public LLMessageReader virtual const char* getMessageName() const; virtual S32 getMessageSize() const; + // <edit> + LLMessageTemplate* getTemplate(); + // </edit> + virtual void copyToBuilder(LLMessageBuilder&) const; BOOL validateMessage(const U8* buffer, S32 buffer_size, - const LLHost& sender, bool trusted = false); + const LLHost& sender, bool trusted = false, BOOL custom = FALSE); BOOL readMessage(const U8* buffer, const LLHost& sender); bool isTrusted() const; bool isBanned(bool trusted_source) const; bool isUdpBanned() const; + + BOOL decodeData(const U8* buffer, const LLHost& sender, BOOL custom = FALSE); + + BOOL decodeTemplate(const U8* buffer, S32 buffer_size, // inputs + LLMessageTemplate** msg_template, BOOL custom = FALSE); // outputs private: void getData(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); - BOOL decodeTemplate(const U8* buffer, S32 buffer_size, // inputs - LLMessageTemplate** msg_template ); // outputs - void logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted ); - BOOL decodeData(const U8* buffer, const LLHost& sender ); - S32 mReceiveSize; LLMessageTemplate* mCurrentRMessageTemplate; LLMsgData* mCurrentRMessageData; diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp index 78af35bf6..7e8aff16d 100644 --- a/linden/indra/llmessage/message.cpp +++ b/linden/indra/llmessage/message.cpp @@ -86,6 +86,7 @@ #include "v3math.h" #include "v4math.h" #include "lltransfertargetvfile.h" +#include "llmessagelog.h" // Constants //const char* MESSAGE_LOG_FILENAME = "message.log"; @@ -524,10 +525,10 @@ LLCircuitData* LLMessageSystem::findCircuit(const LLHost& host, } // Returns TRUE if a valid, on-circuit message has been received. -BOOL LLMessageSystem::checkMessages( S64 frame_count ) +BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fake_buffer[MAX_BUFFER_SIZE], LLHost fake_host, S32 fake_size ) { // Pump - BOOL valid_packet = FALSE; + BOOL valid_packet = FALSE; mMessageReader = mTemplateMessageReader; LLTransferTargetVFile::updateQueue(); @@ -557,6 +558,13 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count ) mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer); // If you want to dump all received packets into SecondLife.log, uncomment this //dumpPacketToLog(); + // <edit> + if(mTrueReceiveSize && receive_size > (S32) LL_MINIMUM_VALID_PACKET_SIZE) + { + LLMessageLog::log(mLastSender, LLHost(16777343, mPort), buffer, mTrueReceiveSize); + } + // </edit> + receive_size = mTrueReceiveSize; mLastSender = mPacketRing.getLastSender(); @@ -1549,6 +1557,12 @@ U32 LLMessageSystem::getOurCircuitCode() return mOurCircuitCode; } +// <edit> +LLCircuit* LLMessageSystem::getCircuit() +{ + return &mCircuitInfo; +} + void LLMessageSystem::getCircuitInfo(LLSD& info) const { mCircuitInfo.getInfo(info); diff --git a/linden/indra/llmessage/message.h b/linden/indra/llmessage/message.h index b25b27eb0..e6391d969 100644 --- a/linden/indra/llmessage/message.h +++ b/linden/indra/llmessage/message.h @@ -230,11 +230,14 @@ class LLMessageSystem : public LLMessageSenderInterface typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t; typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; -private: +// <edit> +//private: +// </edit> message_template_name_map_t mMessageTemplates; message_template_number_map_t mMessageNumbers; - -public: +// <edit> +//public: +// </edit> S32 mSystemVersionMajor; S32 mSystemVersionMinor; S32 mSystemVersionPatch; @@ -341,7 +344,7 @@ class LLMessageSystem : public LLMessageSenderInterface bool addCircuitCode(U32 code, const LLUUID& session_id); BOOL poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received - BOOL checkMessages( S64 frame_count = 0 ); + BOOL checkMessages( S64 frame_count = 0, bool faked_message = false, U8 fake_buffer[MAX_BUFFER_SIZE] = NULL, LLHost fake_host = LLHost(), S32 fake_size = 0 ); void processAcks(); BOOL isMessageFast(const char *msg); @@ -569,6 +572,10 @@ class LLMessageSystem : public LLMessageSenderInterface void showCircuitInfo(); void getCircuitInfo(LLSD& info) const; + // <edit> + LLCircuit* getCircuit(); + // </edit> + U32 getOurCircuitCode(); void enableCircuit(const LLHost &host, BOOL trusted); @@ -733,6 +740,8 @@ class LLMessageSystem : public LLMessageSenderInterface // This will cause all trust queries to return true until the next message // is read: use with caution! void receivedMessageFromTrustedSender(); + + LLTemplateMessageBuilder* mTemplateMessageBuilder; private: @@ -807,7 +816,6 @@ class LLMessageSystem : public LLMessageSenderInterface TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting) LLMessageBuilder* mMessageBuilder; - LLTemplateMessageBuilder* mTemplateMessageBuilder; LLSDMessageBuilder* mLLSDMessageBuilder; LLMessageReader* mMessageReader; LLTemplateMessageReader* mTemplateMessageReader; diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index 3c2293f54..9635f99f7 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp @@ -103,6 +103,10 @@ struct SortScrollListItem LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) : LLScrollListCell(width), mIcon(icon), + // <edit> + mCallback(NULL), + mUserData(NULL), + // </edit> mColor(LLColor4::white) { } @@ -145,6 +149,19 @@ void LLScrollListIcon::setValue(const LLSD& value) } } +// <edit> +void LLScrollListIcon::setClickCallback(BOOL (*callback)(void*), void* user_data) +{ + mCallback = callback; + mUserData = user_data; +} + +BOOL LLScrollListIcon::handleClick() +{ + if(mCallback) return mCallback(mUserData); + return FALSE; +} +// </edit> void LLScrollListIcon::setColor(const LLColor4& color) { diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index 516e4f1d6..e875d7a52 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h @@ -163,10 +163,18 @@ class LLScrollListIcon : public LLScrollListCell virtual void setColor(const LLColor4&); virtual BOOL isText()const { return FALSE; } virtual void setValue(const LLSD& value); + // <edit> + void setClickCallback(BOOL (*callback)(void*), void* user_data); + virtual BOOL handleClick(); + // </edit> private: LLUIImagePtr mIcon; LLColor4 mColor; + // <edit> + BOOL (*mCallback)(void*); + void* mUserData; + // </edit> }; /* @@ -493,6 +501,9 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, virtual S32 getScrollPos() const; virtual void setScrollPos( S32 pos ); + // <edit> + S32 getPageLines() { return mPageLines; } + // </edit> S32 getSearchColumn(); void setSearchColumn(S32 column) { mSearchColumn = column; } S32 getColumnIndexFromOffset(S32 x); diff --git a/linden/indra/newview/llfloatermessagebuilder.cpp b/linden/indra/newview/llfloatermessagebuilder.cpp new file mode 100644 index 000000000..90c0f9ee1 --- /dev/null +++ b/linden/indra/newview/llfloatermessagebuilder.cpp @@ -0,0 +1,978 @@ +// <edit> +#include "llviewerprecompiledheaders.h" +#include "llfloatermessagebuilder.h" +#include "lluictrlfactory.h" +#include "llmessagetemplate.h" +#include "llagent.h" +#include "llchat.h" +#include "llfloaterchat.h" +#include "llviewerregion.h" // getHandle +#include "llcombobox.h" +#include "llselectmgr.h" // fill in stuff about selected object +#include "llparcel.h" +#include "llviewerparcelmgr.h" // same for parcel +#include "llscrolllistctrl.h" +#include "llworld.h" +#include "lltemplatemessagebuilder.h" + +//////////////////////////////// +// LLNetListItem +//////////////////////////////// +LLNetListItem::LLNetListItem(LLUUID id) +: mID(id), + mAutoName(TRUE), + mName("No name"), + mPreviousRegionName(""), + mCircuitData(NULL) +{ +} + +//////////////////////////////// +// LLFloaterMessageBuilder +//////////////////////////////// +std::list<LLNetListItem*> LLFloaterMessageBuilder::sNetListItems; + +LLFloaterMessageBuilder::LLFloaterMessageBuilder(std::string initial_text) +: LLFloater(), + LLEventTimer(1.0f), + mNetInfoMode(NI_NET), + mInitialText(initial_text) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_message_builder.xml"); +} +LLFloaterMessageBuilder::~LLFloaterMessageBuilder() +{ +} +void LLFloaterMessageBuilder::show(std::string initial_text) +{ + (new LLFloaterMessageBuilder(initial_text))->open(); +} +BOOL LLFloaterMessageBuilder::tick() +{ + refreshNetList(); + return FALSE; +} +LLNetListItem* LLFloaterMessageBuilder::findNetListItem(LLHost host) +{ + std::list<LLNetListItem*>::iterator end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) + if((*iter)->mCircuitData && (*iter)->mCircuitData->getHost() == host) + return (*iter); + return NULL; +} +LLNetListItem* LLFloaterMessageBuilder::findNetListItem(LLUUID id) +{ + std::list<LLNetListItem*>::iterator end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) + if((*iter)->mID == id) + return (*iter); + return NULL; +} +void LLFloaterMessageBuilder::refreshNetList() +{ + LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list"); + // Update circuit data of net list items + std::vector<LLCircuitData*> circuits = gMessageSystem->getCircuit()->getCircuitDataList(); + std::vector<LLCircuitData*>::iterator circuits_end = circuits.end(); + for(std::vector<LLCircuitData*>::iterator iter = circuits.begin(); iter != circuits_end; ++iter) + { + LLNetListItem* itemp = findNetListItem((*iter)->getHost()); + if(!itemp) + { + LLUUID id; id.generate(); + itemp = new LLNetListItem(id); + sNetListItems.push_back(itemp); + } + itemp->mCircuitData = (*iter); + } + // Clear circuit data of items whose circuits are gone + std::list<LLNetListItem*>::iterator items_end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) + { + if(std::find(circuits.begin(), circuits.end(), (*iter)->mCircuitData) == circuits.end()) + (*iter)->mCircuitData = NULL; + } + // Remove net list items that are totally useless now + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != sNetListItems.end();) + { + if((*iter)->mCircuitData == NULL) + iter = sNetListItems.erase(iter); + else ++iter; + } + // Update names of net list items + items_end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) + { + LLNetListItem* itemp = (*iter); + if(itemp->mAutoName) + { + if(itemp->mCircuitData) + { + LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(itemp->mCircuitData->getHost()); + if(regionp) + { + std::string name = regionp->getName(); + if(name == "") name = llformat("%s (awaiting region name)", itemp->mCircuitData->getHost().getString().c_str()); + itemp->mName = name; + itemp->mPreviousRegionName = name; + } + else + { + itemp->mName = itemp->mCircuitData->getHost().getString(); + if(itemp->mPreviousRegionName != "") + itemp->mName.append(llformat(" (was %s)", itemp->mPreviousRegionName.c_str())); + } + } + else + { + // an item just for an event queue, not handled yet + itemp->mName = "Something else"; + } + } + } + // Rebuild scroll list from scratch + LLUUID selected_id = scrollp->getFirstSelected() ? scrollp->getFirstSelected()->getUUID() : LLUUID::null; + S32 scroll_pos = scrollp->getScrollPos(); + scrollp->clearRows(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) + { + LLNetListItem* itemp = (*iter); + LLSD element; + element["id"] = itemp->mID; + LLSD& text_column = element["columns"][0]; + text_column["column"] = "text"; + text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : ""); + + LLSD& state_column = element["columns"][ 1]; + state_column["column"] = "state"; + state_column["value"] = ""; + + LLScrollListItem* scroll_itemp = scrollp->addElement(element); + BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive(); + + LLScrollListText* state = (LLScrollListText*)scroll_itemp->getColumn(1); + + if(has_live_circuit) + state->setText(std::string("Alive")); + else + state->setText(std::string("Alive")); + } + if(selected_id.notNull()) scrollp->selectByID(selected_id); + if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos); +} +BOOL LLFloaterMessageBuilder::postBuild() +{ + childSetText("message_edit", mInitialText); + childSetAction("send_btn", onClickSend, this); + std::vector<std::string> names; + LLComboBox* combo; + LLMessageSystem::message_template_name_map_t::iterator temp_end = gMessageSystem->mMessageTemplates.end(); + LLMessageSystem::message_template_name_map_t::iterator temp_iter; + std::vector<std::string>::iterator names_end; + std::vector<std::string>::iterator names_iter; + for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter) + if((*temp_iter).second->getTrust() == MT_NOTRUST) + names.push_back((*temp_iter).second->mName); + std::sort(names.begin(), names.end()); + combo = getChild<LLComboBox>("untrusted_message_combo"); + names_end = names.end(); + for(names_iter = names.begin(); names_iter != names_end; ++names_iter) + combo->add((*names_iter)); + names.clear(); + for(temp_iter = gMessageSystem->mMessageTemplates.begin(); temp_iter != temp_end; ++temp_iter) + if((*temp_iter).second->getTrust() == MT_TRUST) + names.push_back((*temp_iter).second->mName); + std::sort(names.begin(), names.end()); + combo = getChild<LLComboBox>("trusted_message_combo"); + names_end = names.end(); + for(names_iter = names.begin(); names_iter != names_end; ++names_iter) + combo->add((*names_iter)); + childSetCommitCallback("untrusted_message_combo", onCommitPacketCombo, this); + childSetCommitCallback("trusted_message_combo", onCommitPacketCombo, this); + return TRUE; +} +inline std::vector<std::string> split(std::string input, std::string separator) +{ + S32 size = input.length(); + char* buffer = new char[size + 1]; + strncpy(buffer, input.c_str(), size); + buffer[size] = '\0'; + std::vector<std::string> lines; + char* result = strtok(buffer, separator.c_str()); + while(result) + { + lines.push_back(result); + result = strtok(NULL, separator.c_str()); + } + delete[] buffer; + return lines; +} +std::string mvtstr(e_message_variable_type var_type) +{ + switch(var_type) + { + case MVT_U8: + return "U8"; + break; + case MVT_U16: + return "U16"; + break; + case MVT_U32: + return "U32"; + break; + case MVT_U64: + return "U64"; + break; + case MVT_S8: + return "S8"; + break; + case MVT_S16: + return "S16"; + break; + case MVT_S32: + return "S32"; + break; + case MVT_S64: + return "S64"; + break; + case MVT_F32: + return "F32"; + break; + case MVT_F64: + return "F64"; + break; + case MVT_LLVector3: + return "LLVector3"; + break; + case MVT_LLVector3d: + return "LLVector3d"; + break; + case MVT_LLVector4: + return "LLVector4"; + break; + case MVT_LLQuaternion: + return "LLQuaternion"; + break; + case MVT_LLUUID: + return "LLUUID"; + break; + case MVT_BOOL: + return "BOOL"; + break; + case MVT_IP_ADDR: + return "IPADDR"; + break; + case MVT_IP_PORT: + return "IPPORT"; + break; + case MVT_VARIABLE: + return "Variable"; + break; + case MVT_FIXED: + return "Fixed"; + break; + default: + return "Missingno."; + break; + } +} +// static +BOOL LLFloaterMessageBuilder::addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex) +{ + LLStringUtil::trim(input); + if(input.length() < 1 && var_type != MVT_VARIABLE) + return FALSE; + U8 valueU8; + U16 valueU16; + U32 valueU32; + U64 valueU64; + S8 valueS8; + S16 valueS16; + S32 valueS32; + // S64 valueS64; + F32 valueF32; + F64 valueF64; + LLVector3 valueVector3; + LLVector3d valueVector3d; + LLVector4 valueVector4; + LLQuaternion valueQuaternion; + LLUUID valueLLUUID; + BOOL valueBOOL; + std::string input_lower = input; + LLStringUtil::toLower(input_lower); + if(input_lower == "$agentid") + input = gAgent.getID().asString(); + else if(input_lower == "$sessionid") + input = gAgent.getSessionID().asString(); + else if(input_lower == "$uuid") + { + LLUUID id; + id.generate(); + input = id.asString(); + } + else if(input_lower == "$circuitcode") + { + std::stringstream temp_stream; + temp_stream << gMessageSystem->mOurCircuitCode; + input = temp_stream.str(); + } + else if(input_lower == "$regionhandle") + { + std::stringstream temp_stream; + temp_stream << (gAgent.getRegion() ? gAgent.getRegion()->getHandle() : 0); + input = temp_stream.str(); + } + else if(input_lower == "$position" || input_lower == "$pos") + { + std::stringstream temp_stream; + valueVector3 = gAgent.getPositionAgent(); + temp_stream << "<" << valueVector3[0] << ", " << valueVector3[1] << ", " << valueVector3[2] << ">"; + input = temp_stream.str(); + } + if(hex) + { + if(var_type != MVT_VARIABLE && var_type != MVT_FIXED) + return FALSE; + int len = input_lower.length(); + const char* cstr = input_lower.c_str(); + std::string new_input(""); + BOOL nibble = FALSE; + char byte = 0; + for(int i = 0; i < len; i++) + { + char c = cstr[i]; + if(c >= 0x30 && c <= 0x39) + c -= 0x30; + else if(c >= 0x61 && c <= 0x66) + c -= 0x57; + else if(c != 0x20) + return FALSE; + else + continue; + if(!nibble) + byte = c << 4; + else + new_input.push_back(byte | c); + nibble = !nibble; + } + if(nibble) + return FALSE; + input = new_input; + } + std::stringstream stream(input); + std::vector<std::string> tokens; + switch(var_type) + { + case MVT_U8: + if(input.substr(0, 1) == "-") + return FALSE; + if((stream >> valueU32).fail()) + return FALSE; + valueU8 = (U8)valueU32; + gMessageSystem->addU8(var_name, valueU8); + return TRUE; + break; + case MVT_U16: + if(input.substr(0, 1) == "-") + return FALSE; + if((stream >> valueU16).fail()) + return FALSE; + gMessageSystem->addU16(var_name, valueU16); + return TRUE; + break; + case MVT_U32: + if(input.substr(0, 1) == "-") + return FALSE; + if((stream >> valueU32).fail()) + return FALSE; + gMessageSystem->addU32(var_name, valueU32); + return TRUE; + break; + case MVT_U64: + if(input.substr(0, 1) == "-") + return FALSE; + if((stream >> valueU64).fail()) + return FALSE; + gMessageSystem->addU64(var_name, valueU64); + return TRUE; + break; + case MVT_S8: + if((stream >> valueS8).fail()) + return FALSE; + gMessageSystem->addS8(var_name, valueS8); + return TRUE; + break; + case MVT_S16: + if((stream >> valueS16).fail()) + return FALSE; + gMessageSystem->addS16(var_name, valueS16); + return TRUE; + break; + case MVT_S32: + if((stream >> valueS32).fail()) + return FALSE; + gMessageSystem->addS32(var_name, valueS32); + return TRUE; + break; + /* + case MVT_S64: + if((stream >> valueS64).fail()) + return FALSE; + gMessageSystem->addS64(var_name, valueS64); + return TRUE; + break; + */ + case MVT_F32: + if((stream >> valueF32).fail()) + return FALSE; + gMessageSystem->addF32(var_name, valueF32); + return TRUE; + break; + case MVT_F64: + if((stream >> valueF64).fail()) + return FALSE; + gMessageSystem->addF64(var_name, valueF64); + return TRUE; + break; + case MVT_LLVector3: + LLStringUtil::trim(input); + if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") + return FALSE; + tokens = split(input.substr(1, input.length() - 2), ","); + if(tokens.size() != 3) + return FALSE; + for(int i = 0; i < 3; i++) + { + stream.clear(); + stream.str(tokens[i]); + if((stream >> valueF32).fail()) + return FALSE; + valueVector3.mV[i] = valueF32; + } + gMessageSystem->addVector3(var_name, valueVector3); + return TRUE; + break; + case MVT_LLVector3d: + LLStringUtil::trim(input); + if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") + return FALSE; + tokens = split(input.substr(1, input.length() - 2), ","); + if(tokens.size() != 3) + return FALSE; + for(int i = 0; i < 3; i++) + { + stream.clear(); + stream.str(tokens[i]); + if((stream >> valueF64).fail()) + return FALSE; + valueVector3d.mdV[i] = valueF64; + } + gMessageSystem->addVector3d(var_name, valueVector3d); + return TRUE; + break; + case MVT_LLVector4: + LLStringUtil::trim(input); + if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") + return FALSE; + tokens = split(input.substr(1, input.length() - 2), ","); + if(tokens.size() != 4) + return FALSE; + for(int i = 0; i < 4; i++) + { + stream.clear(); + stream.str(tokens[i]); + if((stream >> valueF32).fail()) + return FALSE; + valueVector4.mV[i] = valueF32; + } + gMessageSystem->addVector4(var_name, valueVector4); + return TRUE; + break; + case MVT_LLQuaternion: + LLStringUtil::trim(input); + if(input.substr(0, 1) != "<" || input.substr(input.length() - 1, 1) != ">") + return FALSE; + tokens = split(input.substr(1, input.length() - 2), ","); + if(tokens.size() != 3) + return FALSE; + for(int i = 0; i < 3; i++) + { + stream.clear(); + stream.str(tokens[i]); + if((stream >> valueF32).fail()) + return FALSE; + valueVector3.mV[i] = valueF32; + } + valueQuaternion.unpackFromVector3(valueVector3); + gMessageSystem->addQuat(var_name, valueQuaternion); + return TRUE; + break; + case MVT_LLUUID: + if((stream >> valueLLUUID).fail()) + return FALSE; + gMessageSystem->addUUID(var_name, valueLLUUID); + return TRUE; + break; + case MVT_BOOL: + if(input_lower == "true") + valueBOOL = TRUE; + else if(input_lower == "false") + valueBOOL = FALSE; + else if((stream >> valueBOOL).fail()) + return FALSE; + //gMessageSystem->addBOOL(var_name, valueBOOL); + gMessageSystem->addU8(var_name, (U8)valueBOOL); + return TRUE; + break; + case MVT_IP_ADDR: + if((stream >> valueU32).fail()) + return FALSE; + gMessageSystem->addIPAddr(var_name, valueU32); + return TRUE; + break; + case MVT_IP_PORT: + if((stream >> valueU16).fail()) + return FALSE; + gMessageSystem->addIPPort(var_name, valueU16); + return TRUE; + break; + case MVT_VARIABLE: + if(!hex) + { + char* buffer = new char[input.size() + 1]; + strncpy(buffer, input.c_str(), input.size()); + buffer[input.size()] = '\0'; + gMessageSystem->addBinaryData(var_name, buffer, input.size() + 1); + delete[] buffer; + } + else + gMessageSystem->addBinaryData(var_name, input.c_str(), input.size()); + return TRUE; + break; + case MVT_FIXED: + if(!hex) + { + char* buffer = new char[input.size() + 1]; + strncpy(buffer, input.c_str(), input.size()); + buffer[input.size()] = '\0'; + gMessageSystem->addBinaryData(var_name, buffer, input.size()); + delete[] buffer; + } + else + gMessageSystem->addBinaryData(var_name, input.c_str(), input.size()); + return TRUE; + break; + default: + break; + } + return FALSE; +} +// static +void LLFloaterMessageBuilder::onCommitPacketCombo(LLUICtrl* ctrl, void* user_data) +{ + LLFloaterMessageBuilder* floaterp = (LLFloaterMessageBuilder*)user_data; + LLViewerObject* selected_objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + LLParcel* agent_parcelp = LLViewerParcelMgr::getInstance()->getAgentParcel(); + std::string message = ctrl->getValue(); + std::map<const char *, LLMessageTemplate*>::iterator template_iter; + template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) ); + if(template_iter == gMessageSystem->mMessageTemplates.end()) + { + floaterp->childSetText("message_edit", std::string("")); + return; + } + std::string text(llformat((*template_iter).second->getTrust() == MT_NOTRUST ? "out %s\n" : "in %s\n", message.c_str())); + LLMessageTemplate* temp = (*template_iter).second; + LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end(); + for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin(); + blocks_iter != blocks_end; ++blocks_iter) + { + LLMessageBlock* block = (*blocks_iter); + const char* block_name = block->mName; + std::string block_name_string = std::string(block_name); + S32 num_blocks = 1; + if(block->mType == MBT_MULTIPLE) + num_blocks = block->mNumber; + else if(("ObjectLink" == message && "ObjectData" == block_name_string)) + num_blocks = 2; + for(S32 i = 0; i < num_blocks; i++) + { + text.append(llformat("[%s]\n", block_name)); + LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end(); + for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin(); + var_iter != var_end; ++var_iter) + { + LLMessageVariable* variable = (*var_iter); + const char* var_name = variable->getName(); + std::string var_name_string = std::string(var_name); + text.append(llformat("%s = ", var_name)); + std::string value(""); + S32 size = variable->getSize(); + switch(variable->getType()) + { + case MVT_U8: + case MVT_U16: + case MVT_U32: + case MVT_U64: + case MVT_S8: + case MVT_S16: + case MVT_S32: + case MVT_IP_ADDR: + case MVT_IP_PORT: + if("RegionHandle" == var_name_string || "Handle" == var_name_string) + value = "$RegionHandle"; + else if("CircuitCode" == var_name_string || "ViewerCircuitCode" == var_name_string + || ("Code" == var_name_string && "CircuitCode" == block_name_string) ) + { + value = "$CircuitCode"; + } + else if(selected_objectp && + ( + "ObjectLocalID" == var_name_string + || "TaskLocalID" == var_name_string + || ("LocalID" == var_name_string && + ( + "ObjectData" == block_name_string + || "UpdateData" == block_name_string + || "InventoryData" == block_name_string + ) + ) + ) + ) + { + std::stringstream temp_stream; + temp_stream << selected_objectp->getLocalID(); + value = temp_stream.str(); + } + else if( agent_parcelp && + "LocalID" == var_name_string && + ( + "ParcelData" == block_name_string + || message.find("Parcel") != message.npos + ) + ) + { + std::stringstream temp_stream; + temp_stream << agent_parcelp->getLocalID(); + value = temp_stream.str(); + } + else if("PCode" == var_name_string) + value = "9"; + else if("PathCurve" == var_name_string) + value = "16"; + else if("ProfileCurve" == var_name_string) + value = "1"; + else if("PathScaleX" == var_name_string || "PathScaleY" == var_name_string) + value = "100"; + else if("BypassRaycast" == var_name_string) + value = "1"; + else + value = "0"; + break; + case MVT_F32: + case MVT_F64: + value = "0.0"; + break; + case MVT_LLVector3: + case MVT_LLVector3d: + case MVT_LLQuaternion: + if("Position" == var_name_string || "RayStart" == var_name_string || "RayEnd" == var_name_string) + value = "$Position"; + else if("Scale" == var_name_string) + value = "<0.5, 0.5, 0.5>"; + else + value = "<0, 0, 0>"; + break; + case MVT_LLVector4: + value = "<0, 0, 0, 0>"; + break; + case MVT_LLUUID: + if("AgentID" == var_name_string) + value = "$AgentID"; + else if("SessionID" == var_name_string) + value = "$SessionID"; + else if("ObjectID" == var_name_string && selected_objectp) + value = selected_objectp->getID().asString(); + else if("ParcelID" == var_name_string && agent_parcelp) + value = agent_parcelp->getID().asString(); + else + value = "00000000-0000-0000-0000-000000000000"; + break; + case MVT_BOOL: + value = "false"; + break; + case MVT_VARIABLE: + value = "Hello, world!"; + break; + case MVT_FIXED: + for(S32 si = 0; si < size; si++) + //value.append(std::string("0123456789abcdef").substr(si & 0xf, 1)); + value.append("a"); + break; + default: + value = ""; + break; + } + text.append(llformat("%s\n", value.c_str())); + } + } + } + text = text.substr(0, text.length() - 1); + floaterp->childSetText("message_edit", text); +} +// static +void LLFloaterMessageBuilder::onClickSend(void* user_data) +{ + LLFloaterMessageBuilder* floaterp = (LLFloaterMessageBuilder*)user_data; + std::vector<std::string> lines = split(floaterp->childGetText("message_edit"), "\n"); + if(!lines.size()) + { + LLFloaterChat::addChat(LLChat("Not enough information :O")); + return; + } + std::vector<std::string> tokens = split(lines[0], " "); + if(!tokens.size()) + { + LLFloaterChat::addChat(LLChat("Not enough information :O")); + return; + } + std::string dir_str = tokens[0]; + LLStringUtil::toLower(dir_str); + // Direction + BOOL outgoing; + if(dir_str == "out") + outgoing = TRUE; + else if(dir_str == "in") + outgoing = FALSE; + else + { + LLFloaterChat::addChat(LLChat("Expected direction 'in' or 'out'")); + return; + } + // Message + std::string message = "Invalid"; + if(tokens.size() > 1) + { + if(tokens.size() > 2) + { + LLFloaterChat::addChat(LLChat("Unexpected extra stuff at the top")); + return; + } + message = tokens[1]; + LLStringUtil::trim(message); + } + // Body + std::vector<parts_block> parts; + if(lines.size() > 1) + { + std::vector<std::string>::iterator line_end = lines.end(); + std::vector<std::string>::iterator line_iter = lines.begin(); + ++line_iter; + std::string current_block(""); + int current_block_index = -1; + for( ; line_iter != line_end; ++line_iter) + { + std::string line = (*line_iter); + LLStringUtil::trim(line); + if(!line.length()) + continue; + if(line.substr(0, 1) == "[" && line.substr(line.size() - 1, 1) == "]") + { + current_block = line.substr(1, line.length() - 2); + LLStringUtil::trim(current_block); + ++current_block_index; + parts_block pb; + pb.name = current_block; + parts.push_back(pb); + } + else + { + if(current_block.empty()) + { + LLFloaterChat::addChat(LLChat("Unexpected field when no block yet")); + return; + } + int eqpos = line.find("="); + if(eqpos == line.npos) + { + LLFloaterChat::addChat(LLChat("Missing an equal sign")); + return; + } + std::string field = line.substr(0, eqpos); + LLStringUtil::trim(field); + if(!field.length()) + { + LLFloaterChat::addChat(LLChat("Missing name of field")); + return; + } + std::string value = line.substr(eqpos + 1); + LLStringUtil::trim(value); + parts_var pv; + if(value.substr(0, 1) == "|") + { + pv.hex = TRUE; + value = value.substr(1); + LLStringUtil::trim(value); + } + else + pv.hex = FALSE; + pv.name = field; + pv.value = value; + parts[current_block_index].vars.push_back(pv); + } + } + } + // Verification + std::map<const char *, LLMessageTemplate*>::iterator template_iter; + template_iter = gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) ); + if(template_iter == gMessageSystem->mMessageTemplates.end()) + { + LLFloaterChat::addChat(LLChat(llformat("Don't know how to build a '%s' message", message.c_str()))); + return; + } + LLMessageTemplate* temp = (*template_iter).second; + std::vector<parts_block>::iterator parts_end = parts.end(); + std::vector<parts_block>::iterator parts_iter = parts.begin(); + LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end(); + for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin(); + blocks_iter != blocks_end; ) + { + LLMessageBlock* block = (*blocks_iter); + const char* block_name = block->mName; + if(parts_iter == parts_end) + { + if(block->mType != MBT_VARIABLE) + LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name))); + else + { + ++blocks_iter; + continue; + } + return; + } + else if((*parts_iter).name != block_name) + { + if(block->mType != MBT_VARIABLE) + LLFloaterChat::addChat(LLChat(llformat("Expected '%s' block", block_name))); + else + { + ++blocks_iter; + continue; + } + return; + } + std::vector<parts_var>::iterator part_var_end = (*parts_iter).vars.end(); + std::vector<parts_var>::iterator part_var_iter = (*parts_iter).vars.begin(); + LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end(); + for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin(); + var_iter != var_end; ++var_iter) + { + LLMessageVariable* variable = (*var_iter); + const char* var_name = variable->getName(); + if(part_var_iter == part_var_end) + { + LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name))); + return; + } + else if((*part_var_iter).name != var_name) + { + LLFloaterChat::addChat(LLChat(llformat("Expected '%s' field under '%s' block", var_name, block_name))); + return; + } + (*part_var_iter).var_type = variable->getType(); + ++part_var_iter; + } + if(part_var_iter != part_var_end) + { + LLFloaterChat::addChat(LLChat(llformat("Unexpected field(s) at end of '%s' block", block_name))); + return; + } + ++parts_iter; + // test + if((block->mType != MBT_SINGLE) && (parts_iter != parts_end) && ((*parts_iter).name == block_name)) + { + // block will repeat + } + else ++blocks_iter; + } + if(parts_iter != parts_end) + { + LLFloaterChat::addChat(LLChat("Unexpected block(s) at end")); + return; + } + // Build and send + gMessageSystem->newMessage( message.c_str() ); + for(parts_iter = parts.begin(); parts_iter != parts_end; ++parts_iter) + { + const char* block_name = (*parts_iter).name.c_str(); + gMessageSystem->nextBlock(block_name); + std::vector<parts_var>::iterator part_var_end = (*parts_iter).vars.end(); + for(std::vector<parts_var>::iterator part_var_iter = (*parts_iter).vars.begin(); + part_var_iter != part_var_end; ++part_var_iter) + { + parts_var pv = (*part_var_iter); + if(!addField(pv.var_type, pv.name.c_str(), pv.value, pv.hex)) + { + LLFloaterChat::addChat(LLChat(llformat("Error adding the provided data for %s '%s' to '%s' block", mvtstr(pv.var_type).c_str(), pv.name.c_str(), block_name))); + gMessageSystem->clearMessage(); + return; + } + } + } + + LLScrollListCtrl* scrollp = floaterp->getChild<LLScrollListCtrl>("net_list"); + LLScrollListItem* selected_itemp = scrollp->getFirstSelected(); + + //if a specific circuit is selected, send it to that, otherwise send it to the current sim + if(selected_itemp) + { + LLNetListItem* itemp = findNetListItem(selected_itemp->getUUID()); + LLScrollListText* textColumn = (LLScrollListText*)selected_itemp->getColumn(1); + + //why would you send data through a dead circuit? + if(textColumn->getValue().asString() == "Dead") + { + LLFloaterChat::addChat(LLChat("No sending messages through dead circuits!")); + return; + } + if(outgoing) + { + gMessageSystem->sendMessage(itemp->mCircuitData->getHost()); + } else { + U8 builtMessageBuffer[MAX_BUFFER_SIZE]; + + S32 message_size = gMessageSystem->mTemplateMessageBuilder->buildMessage(builtMessageBuffer, MAX_BUFFER_SIZE, 0); + gMessageSystem->clearMessage(); + gMessageSystem->checkMessages(0, true, builtMessageBuffer, itemp->mCircuitData->getHost(), message_size); + + } + } else { + if(outgoing) + { + gMessageSystem->sendMessage(gAgent.getRegionHost()); + } else { + U8 builtMessageBuffer[MAX_BUFFER_SIZE]; + + S32 message_size = gMessageSystem->mTemplateMessageBuilder->buildMessage(builtMessageBuffer, MAX_BUFFER_SIZE, 0); + gMessageSystem->clearMessage(); + gMessageSystem->checkMessages(0, true, builtMessageBuffer, gAgent.getRegionHost(), message_size); + + } + } +} + +BOOL LLFloaterMessageBuilder::handleKeyHere(KEY key, MASK mask) +{ + if(key == KEY_RETURN && (mask & MASK_CONTROL)) + { + onClickSend(this); + return TRUE; + } + if(key == KEY_ESCAPE) + { + releaseFocus(); + return TRUE; + } + return FALSE; +} +// </edit> diff --git a/linden/indra/newview/llfloatermessagebuilder.h b/linden/indra/newview/llfloatermessagebuilder.h new file mode 100644 index 000000000..5dc9b4297 --- /dev/null +++ b/linden/indra/newview/llfloatermessagebuilder.h @@ -0,0 +1,55 @@ +// <edit>] +#ifndef LL_LLFLOATERMESSAGEBUILDER_H +#define LL_LLFLOATERMESSAGEBUILDER_H +#include "llfloater.h" +#include "lltemplatemessagereader.h" +#include "llmessagelog.h" + +class LLNetListItem +{ +public: + LLNetListItem(LLUUID id); + LLUUID mID; + BOOL mAutoName; + std::string mName; + std::string mPreviousRegionName; + LLCircuitData* mCircuitData; +}; + +class LLFloaterMessageBuilder : public LLFloater, public LLEventTimer +{ +public: + LLFloaterMessageBuilder(std::string initial_text); + ~LLFloaterMessageBuilder(); + static void show(std::string initial_text); + static std::list<LLNetListItem*> sNetListItems; + BOOL postBuild(); + BOOL tick(); + static BOOL addField(e_message_variable_type var_type, const char* var_name, std::string input, BOOL hex); + static void onClickSend(void* user_data); + static void onCommitPacketCombo(LLUICtrl* ctrl, void* user_data); + static LLFloaterMessageBuilder* sInstance; + BOOL handleKeyHere(KEY key, MASK mask); + std::string mInitialText; + struct parts_var + { + std::string name; + std::string value; + BOOL hex; + e_message_variable_type var_type; + }; + struct parts_block + { + std::string name; + std::vector<parts_var> vars; + }; + static LLNetListItem* findNetListItem(LLHost host); + static LLNetListItem* findNetListItem(LLUUID id); + void refreshNetList(); + enum ENetInfoMode { NI_NET, NI_LOG }; + ENetInfoMode mNetInfoMode; + static void onCommitMessageLog(LLUICtrl* ctrl, void* user_data); + static void onCommitFilter(LLUICtrl* ctrl, void* user_data); +}; +#endif +// </edit> diff --git a/linden/indra/newview/llfloatermessagelog.cpp b/linden/indra/newview/llfloatermessagelog.cpp new file mode 100644 index 000000000..161779b35 --- /dev/null +++ b/linden/indra/newview/llfloatermessagelog.cpp @@ -0,0 +1,962 @@ +// <edit> +#include "llviewerprecompiledheaders.h" +#include "llfloatermessagelog.h" +#include "lluictrlfactory.h" +#include "llworld.h" +#include "llviewerregion.h" +#include "llscrolllistctrl.h" +#include "lltexteditor.h" +#include "llviewerwindow.h" // alertXml +#include "llmessagetemplate.h" +#include <boost/tokenizer.hpp> +#include "llmenugl.h" +#include "llfloatermessagebuilder.h" +#include "llagent.h" +//////////////////////////////// +// LLFloaterMessageLogItem +//////////////////////////////// +#define MAX_PACKET_LEN (0x2000) +LLTemplateMessageReader* LLFloaterMessageLogItem::sTemplateMessageReader = NULL; +LLFloaterMessageLogItem::LLFloaterMessageLogItem(LLMessageLogEntry entry) +: LLMessageLogEntry(entry.mType, entry.mFromHost, entry.mToHost, entry.mData, entry.mDataSize) +{ + if(!sTemplateMessageReader) + { + sTemplateMessageReader = new LLTemplateMessageReader(gMessageSystem->mMessageNumbers); + } + mID.generate(); + mSequenceID = 0; + if(mType == TEMPLATE) + { + BOOL decode_invalid = FALSE; + S32 decode_len = mDataSize; + std::vector<U8> DecodeBuffer(MAX_PACKET_LEN,0); + memcpy(&(DecodeBuffer[0]),&(mData[0]),decode_len); + U8* decodep = &(DecodeBuffer[0]); + mFlags = DecodeBuffer[0]; + gMessageSystem->zeroCodeExpand(&decodep, &decode_len); + if(decode_len < 7) + decode_invalid = TRUE; + else + { + mSequenceID = ntohl(*((U32*)(&decodep[1]))); + sTemplateMessageReader->clearMessage(); + if(!sTemplateMessageReader->validateMessage(decodep, decode_len, mFromHost, TRUE)) + decode_invalid = TRUE; + else + { + if(!sTemplateMessageReader->decodeData(decodep, mFromHost, TRUE)) + decode_invalid = TRUE; + else + { + LLMessageTemplate* temp = sTemplateMessageReader->getTemplate(); + mName = temp->mName; + mSummary = ""; + + if(mFlags) + { + mSummary.append(" [ "); + if(mFlags & LL_ZERO_CODE_FLAG) + mSummary.append(" Zer "); + if(mFlags & LL_RELIABLE_FLAG) + mSummary.append(" Rel "); + if(mFlags & LL_RESENT_FLAG) + mSummary.append(" Rsd "); + if(mFlags & LL_ACK_FLAG) + mSummary.append(" Ack "); + mSummary.append(" ] "); + } + + LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end(); + for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin(); + blocks_iter != blocks_end; ++blocks_iter) + { + LLMessageBlock* block = (*blocks_iter); + const char* block_name = block->mName; + S32 num_blocks = sTemplateMessageReader->getNumberOfBlocks(block_name); + if(!num_blocks) + mSummary.append(" { } "); + else if(num_blocks > 1) + mSummary.append(llformat(" %s [ %d ] { ... } ", block_name, num_blocks)); + else for(S32 i = 0; i < 1; i++) + { + mSummary.append(" { "); + LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end(); + for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin(); + var_iter != var_end; ++var_iter) + { + LLMessageVariable* variable = (*var_iter); + const char* var_name = variable->getName(); + BOOL returned_hex; + std::string value = getString(sTemplateMessageReader, block_name, i, var_name, variable->getType(), returned_hex, TRUE); + mSummary.append(llformat(" %s=%s ", var_name, value.c_str())); + } + mSummary.append(" } "); + if(mSummary.length() > 255) break; + } + if(mSummary.length() > 255) + { + mSummary.append(" ... "); + break; + } + } // blocks_iter + } // decode_valid + } + } + if(decode_invalid) + { + mName = "Invalid"; + mSummary = ""; + for(S32 i = 0; i < mDataSize; i++) + mSummary.append(llformat("%02X ", mData[i])); + } + } + else // not template + { + mName = "SOMETHING ELSE"; + mSummary = "TODO: SOMETHING ELSE"; + } +} +LLFloaterMessageLogItem::~LLFloaterMessageLogItem() +{ +} +BOOL LLFloaterMessageLogItem::isOutgoing() +{ + return mFromHost == LLHost(16777343, gMessageSystem->getListenPort()); +} +std::string LLFloaterMessageLogItem::getFull(BOOL show_header) +{ + std::string full(""); + if(mType == TEMPLATE) + { + BOOL decode_invalid = FALSE; + S32 decode_len = mDataSize; + std::vector<U8> DecodeBuffer(MAX_PACKET_LEN,0); + memcpy(&(DecodeBuffer[0]),&(mData[0]),decode_len); + U8* decodep = &(DecodeBuffer[0]); + gMessageSystem->zeroCodeExpand(&decodep, &decode_len); + if(decode_len < 7) + decode_invalid = TRUE; + else + { + sTemplateMessageReader->clearMessage(); + if(!sTemplateMessageReader->validateMessage(decodep, decode_len, mFromHost, TRUE)) + decode_invalid = TRUE; + else + { + if(!sTemplateMessageReader->decodeData(decodep, mFromHost, TRUE)) + decode_invalid = TRUE; + else + { + LLMessageTemplate* temp = sTemplateMessageReader->getTemplate(); + full.append(isOutgoing() ? "out " : "in "); + full.append(llformat("%s\n", temp->mName)); + if(show_header) + { + full.append("[Header]\n"); + full.append(llformat("SequenceID = %u\n", mSequenceID)); + full.append(llformat("LL_ZERO_CODE_FLAG = %s\n", (mFlags & LL_ZERO_CODE_FLAG) ? "True" : "False")); + full.append(llformat("LL_RELIABLE_FLAG = %s\n", (mFlags & LL_RELIABLE_FLAG) ? "True" : "False")); + full.append(llformat("LL_RESENT_FLAG = %s\n", (mFlags & LL_RESENT_FLAG) ? "True" : "False")); + full.append(llformat("LL_ACK_FLAG = %s\n", (mFlags & LL_ACK_FLAG) ? "True" : "False")); + } + LLMessageTemplate::message_block_map_t::iterator blocks_end = temp->mMemberBlocks.end(); + for (LLMessageTemplate::message_block_map_t::iterator blocks_iter = temp->mMemberBlocks.begin(); + blocks_iter != blocks_end; ++blocks_iter) + { + LLMessageBlock* block = (*blocks_iter); + const char* block_name = block->mName; + S32 num_blocks = sTemplateMessageReader->getNumberOfBlocks(block_name); + for(S32 i = 0; i < num_blocks; i++) + { + full.append(llformat("[%s]\n", block->mName)); + LLMessageBlock::message_variable_map_t::iterator var_end = block->mMemberVariables.end(); + for (LLMessageBlock::message_variable_map_t::iterator var_iter = block->mMemberVariables.begin(); + var_iter != var_end; ++var_iter) + { + LLMessageVariable* variable = (*var_iter); + const char* var_name = variable->getName(); + BOOL returned_hex; + std::string value = getString(sTemplateMessageReader, block_name, i, var_name, variable->getType(), returned_hex); + if(returned_hex) + full.append(llformat("%s =| ", var_name)); + else + full.append(llformat("%s = ", var_name)); + // llformat has a 1024 char limit!? + full.append(value); + full.append("\n"); + } + } + } // blocks_iter + } // decode_valid + } + } + if(decode_invalid) + { + full = isOutgoing() ? "out" : "in"; + full.append("\n"); + for(S32 i = 0; i < mDataSize; i++) + full.append(llformat("%02X ", mData[i])); + } + } + else // not template + { + full = "FIXME"; + } + return full; +} +// static +std::string LLFloaterMessageLogItem::getString(LLTemplateMessageReader* readerp, const char* block_name, S32 block_num, const char* var_name, e_message_variable_type var_type, BOOL &returned_hex, BOOL summary_mode) +{ + returned_hex = FALSE; + std::stringstream stream; + char* value; + U32 valueU32; + U16 valueU16; + LLVector3 valueVector3; + LLVector3d valueVector3d; + LLVector4 valueVector4; + LLQuaternion valueQuaternion; + LLUUID valueLLUUID; + switch(var_type) + { + case MVT_U8: + U8 valueU8; + readerp->getU8(block_name, var_name, valueU8, block_num); + stream << U32(valueU8); + break; + case MVT_U16: + readerp->getU16(block_name, var_name, valueU16, block_num); + stream << valueU16; + break; + case MVT_U32: + readerp->getU32(block_name, var_name, valueU32, block_num); + stream << valueU32; + break; + case MVT_U64: + U64 valueU64; + readerp->getU64(block_name, var_name, valueU64, block_num); + stream << valueU64; + break; + case MVT_S8: + S8 valueS8; + readerp->getS8(block_name, var_name, valueS8, block_num); + stream << S32(valueS8); + break; + case MVT_S16: + S16 valueS16; + readerp->getS16(block_name, var_name, valueS16, block_num); + stream << valueS16; + break; + case MVT_S32: + S32 valueS32; + readerp->getS32(block_name, var_name, valueS32, block_num); + stream << valueS32; + break; + /*case MVT_S64: + S64 valueS64; + readerp->getS64(block_name, var_name, valueS64, block_num); + stream << valueS64; + break;*/ + case MVT_F32: + F32 valueF32; + readerp->getF32(block_name, var_name, valueF32, block_num); + stream << valueF32; + break; + case MVT_F64: + F64 valueF64; + readerp->getF64(block_name, var_name, valueF64, block_num); + stream << valueF64; + break; + case MVT_LLVector3: + readerp->getVector3(block_name, var_name, valueVector3, block_num); + //stream << valueVector3; + stream << "<" << valueVector3.mV[0] << ", " << valueVector3.mV[1] << ", " << valueVector3.mV[2] << ">"; + break; + case MVT_LLVector3d: + readerp->getVector3d(block_name, var_name, valueVector3d, block_num); + //stream << valueVector3d; + stream << "<" << valueVector3d.mdV[0] << ", " << valueVector3d.mdV[1] << ", " << valueVector3d.mdV[2] << ">"; + break; + case MVT_LLVector4: + readerp->getVector4(block_name, var_name, valueVector4, block_num); + //stream << valueVector4; + stream << "<" << valueVector4.mV[0] << ", " << valueVector4.mV[1] << ", " << valueVector4.mV[2] << ", " << valueVector4.mV[3] << ">"; + break; + case MVT_LLQuaternion: + readerp->getQuat(block_name, var_name, valueQuaternion, block_num); + //stream << valueQuaternion; + stream << "<" << valueQuaternion.mQ[0] << ", " << valueQuaternion.mQ[1] << ", " << valueQuaternion.mQ[2] << ", " << valueQuaternion.mQ[3] << ">"; + break; + case MVT_LLUUID: + readerp->getUUID(block_name, var_name, valueLLUUID, block_num); + stream << valueLLUUID; + break; + case MVT_BOOL: + BOOL valueBOOL; + readerp->getBOOL(block_name, var_name, valueBOOL, block_num); + stream << valueBOOL; + break; + case MVT_IP_ADDR: + readerp->getIPAddr(block_name, var_name, valueU32, block_num); + stream << LLHost(valueU32, 0).getIPString(); + break; + case MVT_IP_PORT: + readerp->getIPPort(block_name, var_name, valueU16, block_num); + stream << valueU16; + case MVT_VARIABLE: + case MVT_FIXED: + default: + S32 size = readerp->getSize(block_name, block_num, var_name); + if(size) + { + value = new char[size + 1]; + readerp->getBinaryData(block_name, var_name, value, size, block_num); + value[size] = '\0'; + S32 readable = 0; + S32 unreadable = 0; + S32 end = (summary_mode && (size > 64)) ? 64 : size; + for(S32 i = 0; i < end; i++) + { + if(!value[i]) + { + if(i != (end - 1)) + { // don't want null terminator hiding data + unreadable = S32_MAX; + break; + } + } + else if(value[i] < 0x20 || value[i] >= 0x7F) + { + if(summary_mode) + unreadable++; + else + { // never want any wrong characters outside of summary mode + unreadable = S32_MAX; + break; + } + } + else readable++; + } + if(readable >= unreadable) + { + if(summary_mode && (size > 64)) + { + for(S32 i = 60; i < 63; i++) + value[i] = '.'; + value[63] = '\0'; + } + stream << value; + + delete[] value; + } + else + { + returned_hex = TRUE; + S32 end = (summary_mode && (size > 8)) ? 8 : size; + for(S32 i = 0; i < end; i++) + //stream << std::uppercase << std::hex << U32(value[i]) << " "; + stream << llformat("%02X ", (U8)value[i]); + if(summary_mode && (size > 8)) + stream << " ... "; + } + } + break; + } + + return stream.str(); +} +LLMessageLogFilter::LLMessageLogFilter() +{ +} +LLMessageLogFilter::~LLMessageLogFilter() +{ +} +BOOL LLMessageLogFilter::set(std::string filter) +{ + mPositiveNames.clear(); + mNegativeNames.clear(); + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(" ","",boost::keep_empty_tokens); + boost::tokenizer<boost::char_separator<char> > tokens(filter, sep); + boost::tokenizer<boost::char_separator<char> >::iterator end = tokens.end(); + for(boost::tokenizer<boost::char_separator<char> >::iterator iter = tokens.begin(); iter != end; ++iter) + { + std::string token = (*iter); + LLStringUtil::trim(token); + LLStringUtil::toLower(token); + BOOL negative = token.find("!") == 0; + if(negative) + { + token = token.substr(1); + mNegativeNames.push_back(token); + } + else + mPositiveNames.push_back(token); + } + return TRUE; +} +//////////////////////////////// +// LLMessageLogFilterApply +//////////////////////////////// +LLMessageLogFilterApply::LLMessageLogFilterApply() +: LLEventTimer(0.1f), + mFinished(FALSE), + mProgress(0) +{ + mIter = LLFloaterMessageLog::sMessageLogEntries.begin(); +} +void LLMessageLogFilterApply::cancel() +{ + mFinished = TRUE; +} +BOOL LLMessageLogFilterApply::tick() +{ + std::deque<LLMessageLogEntry>::iterator end = LLFloaterMessageLog::sMessageLogEntries.end(); + if(mIter == end || !LLFloaterMessageLog::sInstance) + { + mFinished = TRUE; + if(LLFloaterMessageLog::sInstance) + { + if(LLFloaterMessageLog::sInstance->mMessageLogFilterApply == this) + { + LLFloaterMessageLog::sInstance->stopApplyingFilter(); + } + } + return TRUE; + } + for(S32 i = 0; i < 256; i++) + { + if(mIter == end) + { + mFinished = TRUE; + if(LLFloaterMessageLog::sInstance) + { + if(LLFloaterMessageLog::sInstance->mMessageLogFilterApply == this) + { + LLFloaterMessageLog::sInstance->stopApplyingFilter(); + + //we're done messing with the deque, push all queued items to the main deque + std::deque<LLMessageLogEntry>::iterator queueIter = mQueuedMessages.begin(); + std::deque<LLMessageLogEntry>::iterator queueEnd = mQueuedMessages.end(); + + while(queueIter != queueEnd) + { + LLFloaterMessageLog::sInstance->conditionalLog(LLFloaterMessageLogItem((*queueIter))); + ++queueIter; + } + + mQueuedMessages.clear(); + } + } + + return TRUE; + } + + LLFloaterMessageLog::sInstance->conditionalLog(LLFloaterMessageLogItem((*mIter))); + + mIter++; + mProgress++; + } + LLFloaterMessageLog::sInstance->updateFilterStatus(); + return FALSE; +} +//////////////////////////////// +// LLFloaterMessageLog +//////////////////////////////// +LLFloaterMessageLog* LLFloaterMessageLog::sInstance; +std::list<LLNetListItem*> LLFloaterMessageLog::sNetListItems; +std::deque<LLMessageLogEntry> LLFloaterMessageLog::sMessageLogEntries; +std::vector<LLFloaterMessageLogItem> LLFloaterMessageLog::sFloaterMessageLogItems; +LLMessageLogFilter LLFloaterMessageLog::sMessageLogFilter = LLMessageLogFilter(); +std::string LLFloaterMessageLog::sMessageLogFilterString("!StartPingCheck !CompletePingCheck !PacketAck !SimulatorViewerTimeMessage !SimStats !AgentUpdate !AgentAnimation !AvatarAnimation !ViewerEffect !CoarseLocationUpdate !LayerData !CameraConstraint !ObjectUpdateCached !RequestMultipleObjects !ObjectUpdate !ObjectUpdateCompressed !ImprovedTerseObjectUpdate !KillObject !ImagePacket !SendXferPacket !ConfirmXferPacket !TransferPacket !SoundTrigger !AttachedSound !PreloadSound"); +BOOL LLFloaterMessageLog::sBusyApplyingFilter = FALSE; +LLFloaterMessageLog::LLFloaterMessageLog() +: LLFloater(), + LLEventTimer(1.0f), + mNetInfoMode(NI_NET), + mMessageLogFilterApply(NULL) +{ + sInstance = this; + LLMessageLog::setCallback(onLog); + sMessageLogEntries = LLMessageLog::getDeque(); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_message_log.xml"); +} +LLFloaterMessageLog::~LLFloaterMessageLog() +{ + LLMessageLog::setCallback(NULL); + stopApplyingFilter(); + sInstance = NULL; + sNetListItems.clear(); + sMessageLogEntries.clear(); + sFloaterMessageLogItems.clear(); +} +// static +void LLFloaterMessageLog::show() +{ + if(!sInstance) sInstance = new LLFloaterMessageLog(); + sInstance->open(); +} +BOOL LLFloaterMessageLog::postBuild() +{ + childSetCommitCallback("net_list", onCommitNetList, this); + childSetCommitCallback("message_log", onCommitMessageLog, this); + childSetAction("filter_choice_btn", onClickFilterChoice, this); + childSetAction("filter_apply_btn", onClickFilterApply, this); + childSetCommitCallback("filter_edit", onCommitFilter, this); + childSetAction("clear_log_btn", onClickClearLog, this); + childSetAction("send_to_message_builder_btn", onClickSendToMessageBuilder, this); + childSetText("filter_edit", sMessageLogFilterString); + refreshNetList(); + refreshNetInfo(TRUE); + startApplyingFilter(sMessageLogFilterString, TRUE); + return TRUE; +} +BOOL LLFloaterMessageLog::tick() +{ + refreshNetList(); + refreshNetInfo(FALSE); + return FALSE; +} +LLNetListItem* LLFloaterMessageLog::findNetListItem(LLHost host) +{ + std::list<LLNetListItem*>::iterator end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) + if((*iter)->mCircuitData && (*iter)->mCircuitData->getHost() == host) + return (*iter); + return NULL; +} +LLNetListItem* LLFloaterMessageLog::findNetListItem(LLUUID id) +{ + std::list<LLNetListItem*>::iterator end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) + if((*iter)->mID == id) + return (*iter); + return NULL; +} +void LLFloaterMessageLog::refreshNetList() +{ + LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list"); + // Update circuit data of net list items + std::vector<LLCircuitData*> circuits = gMessageSystem->getCircuit()->getCircuitDataList(); + std::vector<LLCircuitData*>::iterator circuits_end = circuits.end(); + for(std::vector<LLCircuitData*>::iterator iter = circuits.begin(); iter != circuits_end; ++iter) + { + LLNetListItem* itemp = findNetListItem((*iter)->getHost()); + if(!itemp) + { + LLUUID id; id.generate(); + itemp = new LLNetListItem(id); + sNetListItems.push_back(itemp); + } + itemp->mCircuitData = (*iter); + } + // Clear circuit data of items whose circuits are gone + std::list<LLNetListItem*>::iterator items_end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) + { + if(std::find(circuits.begin(), circuits.end(), (*iter)->mCircuitData) == circuits.end()) + (*iter)->mCircuitData = NULL; + } + // Remove net list items that are totally useless now + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != sNetListItems.end();) + { + if((*iter)->mCircuitData == NULL) + iter = sNetListItems.erase(iter); + else ++iter; + } + // Update names of net list items + items_end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) + { + LLNetListItem* itemp = (*iter); + if(itemp->mAutoName) + { + if(itemp->mCircuitData) + { + LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(itemp->mCircuitData->getHost()); + if(regionp) + { + std::string name = regionp->getName(); + if(name == "") name = llformat("%s (awaiting region name)", itemp->mCircuitData->getHost().getString().c_str()); + itemp->mName = name; + itemp->mPreviousRegionName = name; + } + else + { + itemp->mName = itemp->mCircuitData->getHost().getString(); + if(itemp->mPreviousRegionName != "") + itemp->mName.append(llformat(" (was %s)", itemp->mPreviousRegionName.c_str())); + } + } + else + { + // an item just for an event queue, not handled yet + itemp->mName = "Something else"; + } + } + } + // Rebuild scroll list from scratch + LLUUID selected_id = scrollp->getFirstSelected() ? scrollp->getFirstSelected()->getUUID() : LLUUID::null; + S32 scroll_pos = scrollp->getScrollPos(); + scrollp->clearRows(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != items_end; ++iter) + { + LLNetListItem* itemp = (*iter); + LLSD element; + element["id"] = itemp->mID; + LLSD& text_column = element["columns"][0]; + text_column["column"] = "text"; + text_column["value"] = itemp->mName + (itemp->mCircuitData->getHost() == gAgent.getRegionHost() ? " (main)" : ""); + for(int i = 0; i < 2; i++) + { + LLSD& icon_column = element["columns"][i + 1]; + icon_column["column"] = llformat("icon%d", i); + icon_column["type"] = "icon"; + icon_column["value"] = ""; + } + LLScrollListItem* scroll_itemp = scrollp->addElement(element); + BOOL has_live_circuit = itemp->mCircuitData && itemp->mCircuitData->isAlive(); + if(has_live_circuit) + { + LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); + icon->setValue("icon_net_close_circuit.tga"); + icon->setClickCallback(onClickCloseCircuit, itemp); + } + else + { + LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(1); + icon->setValue("icon_net_close_circuit_gray.tga"); + icon->setClickCallback(NULL, NULL); + } + // Event queue isn't even supported yet... FIXME + LLScrollListIcon* icon = (LLScrollListIcon*)scroll_itemp->getColumn(2); + icon->setValue("icon_net_close_eventpoll_gray.tga"); + icon->setClickCallback(NULL, NULL); + } + if(selected_id.notNull()) scrollp->selectByID(selected_id); + if(scroll_pos < scrollp->getItemCount()) scrollp->setScrollPos(scroll_pos); +} +void LLFloaterMessageLog::refreshNetInfo(BOOL force) +{ + if(mNetInfoMode != NI_NET) return; + LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list"); + LLScrollListItem* selected_itemp = scrollp->getFirstSelected(); + if(selected_itemp) + { + if(!force) if(getChild<LLTextEditor>("net_info")->hasSelection()) return; + LLNetListItem* itemp = findNetListItem(selected_itemp->getUUID()); + if(itemp) + { + std::string info(llformat("%s\n--------------------------------\n\n", itemp->mName.c_str())); + if(itemp->mCircuitData) + { + LLCircuitData* cdp = itemp->mCircuitData; + info.append("Circuit\n--------------------------------\n"); + info.append(llformat(" * Host: %s\n", cdp->getHost().getString().c_str())); + S32 seconds = (S32)cdp->getAgeInSeconds(); + S32 minutes = seconds / 60; + seconds = seconds % 60; + S32 hours = minutes / 60; + minutes = minutes % 60; + info.append(llformat(" * Age: %dh %dm %ds\n", hours, minutes, seconds)); + info.append(llformat(" * Alive: %s\n", cdp->isAlive() ? "yes" : "no")); + info.append(llformat(" * Blocked: %s\n", cdp->isBlocked() ? "yes" : "no")); + info.append(llformat(" * Allow timeout: %s\n", cdp->getAllowTimeout() ? "yes" : "no")); + info.append(llformat(" * Trusted: %s\n", cdp->getTrusted() ? "yes" : "no")); + info.append(llformat(" * Ping delay: %d\n", cdp->getPingDelay())); + info.append(llformat(" * Packets out: %d\n", cdp->getPacketsOut())); + info.append(llformat(" * Bytes out: %d\n", cdp->getBytesOut())); + info.append(llformat(" * Packets in: %d\n", cdp->getPacketsIn())); + info.append(llformat(" * Bytes in: %d\n", cdp->getBytesIn())); + info.append(llformat(" * Endpoint ID: %s\n", cdp->getLocalEndPointID().asString().c_str())); + info.append(llformat(" * Remote ID: %s\n", cdp->getRemoteID().asString().c_str())); + info.append(llformat(" * Remote session ID: %s\n", cdp->getRemoteSessionID().asString().c_str())); + } + childSetText("net_info", info); + } + else childSetText("net_info", std::string("")); + } + else childSetText("net_info", std::string("")); +} +void LLFloaterMessageLog::setNetInfoMode(ENetInfoMode mode) +{ + mNetInfoMode = mode; + if(mNetInfoMode == NI_NET) + refreshNetInfo(TRUE); + childSetEnabled("send_to_message_builder_btn", mNetInfoMode == NI_LOG); +} +// static +void LLFloaterMessageLog::onLog(LLMessageLogEntry entry) +{ + //don't mess with the queue while a filter's being applied, or face invalid iterators + if(!sBusyApplyingFilter) + { + sMessageLogEntries.push_back(entry); + conditionalLog(LLFloaterMessageLogItem(entry)); + } +} +// static +void LLFloaterMessageLog::conditionalLog(LLFloaterMessageLogItem item) +{ + if(!sBusyApplyingFilter) + sInstance->childSetText("log_status_text", llformat("Showing %d messages from %d", sFloaterMessageLogItems.size(), sMessageLogEntries.size())); + std::string find_name = item.mName; + LLStringUtil::toLower(find_name); + if(sMessageLogFilter.mPositiveNames.size()) + if(std::find(sMessageLogFilter.mPositiveNames.begin(), sMessageLogFilter.mPositiveNames.end(), find_name) == sMessageLogFilter.mPositiveNames.end()) + return; + if(std::find(sMessageLogFilter.mNegativeNames.begin(), sMessageLogFilter.mNegativeNames.end(), find_name) != sMessageLogFilter.mNegativeNames.end()) + return; + sFloaterMessageLogItems.push_back(item); // moved from beginning... + BOOL outgoing = item.isOutgoing(); + std::string net_name("\?\?\?"); + if(item.mType == LLFloaterMessageLogItem::TEMPLATE) + { + LLHost find_host = outgoing ? item.mToHost : item.mFromHost; + net_name = find_host.getIPandPort(); + std::list<LLNetListItem*>::iterator end = sNetListItems.end(); + for(std::list<LLNetListItem*>::iterator iter = sNetListItems.begin(); iter != end; ++iter) + { + if((*iter)->mCircuitData->getHost() == find_host) + { + net_name = (*iter)->mName; + break; + } + } + } + LLSD element; + element["id"] = item.mID; + LLSD& sequence_column = element["columns"][0]; + sequence_column["column"] = "sequence"; + sequence_column["value"] = llformat("%u", item.mSequenceID); + LLSD& type_column = element["columns"][1]; + type_column["column"] = "type"; + type_column["value"] = item.mType == LLFloaterMessageLogItem::TEMPLATE ? "UDP" : "\?\?\?"; + LLSD& direction_column = element["columns"][2]; + direction_column["column"] = "direction"; + direction_column["value"] = outgoing ? "to" : "from"; + LLSD& net_column = element["columns"][3]; + net_column["column"] = "net"; + net_column["value"] = net_name; + LLSD& name_column = element["columns"][4]; + name_column["column"] = "name"; + name_column["value"] = item.mName; + /* + LLSD& zer_column = element["columns"][5]; + zer_column["column"] = "flag_zer"; + zer_column["type"] = "icon"; + zer_column["value"] = (item.mFlags & LL_ZERO_CODE_FLAG) ? "flag_zer.tga" : ""; + LLSD& rel_column = element["columns"][6]; + rel_column["column"] = "flag_rel"; + rel_column["type"] = "icon"; + rel_column["value"] = (item.mFlags & LL_RELIABLE_FLAG) ? "flag_rel.tga" : ""; + LLSD& rsd_column = element["columns"][7]; + rsd_column["column"] = "flag_rsd"; + rsd_column["type"] = "icon"; + rsd_column["value"] = (item.mFlags & LL_RESENT_FLAG) ? "flag_rsd.tga" : ""; + LLSD& ack_column = element["columns"][8]; + ack_column["column"] = "flag_ack"; + ack_column["type"] = "icon"; + ack_column["value"] = (item.mFlags & LL_ACK_FLAG) ? "flag_ack.tga" : ""; + */ + LLSD& summary_column = element["columns"][5]; + summary_column["column"] = "summary"; + summary_column["value"] = item.mSummary; + LLScrollListCtrl* scrollp = sInstance->getChild<LLScrollListCtrl>("message_log"); + S32 scroll_pos = scrollp->getScrollPos(); + scrollp->addElement(element); + if(scroll_pos > scrollp->getItemCount() - scrollp->getPageLines() - 4) + scrollp->setScrollPos(scrollp->getItemCount()); +} +// static +void LLFloaterMessageLog::onCommitNetList(LLUICtrl* ctrl, void* user_data) +{ + LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; + floaterp->setNetInfoMode(NI_NET); + floaterp->refreshNetInfo(TRUE); +} +// static +void LLFloaterMessageLog::onCommitMessageLog(LLUICtrl* ctrl, void* user_data) +{ + LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; + LLScrollListCtrl* scrollp = floaterp->getChild<LLScrollListCtrl>("message_log"); + LLScrollListItem* selected_itemp = scrollp->getFirstSelected(); + if(!selected_itemp) return; + LLUUID id = selected_itemp->getUUID(); + std::vector<LLFloaterMessageLogItem>::iterator end = sFloaterMessageLogItems.end(); + for(std::vector<LLFloaterMessageLogItem>::iterator iter = sFloaterMessageLogItems.begin(); iter != end; ++iter) + { + if(iter->mID == id) + { + floaterp->setNetInfoMode(NI_LOG); + floaterp->childSetText("net_info", iter->getFull(FALSE)); + break; + } + } +} +// static +BOOL LLFloaterMessageLog::onClickCloseCircuit(void* user_data) +{ + LLNetListItem* itemp = (LLNetListItem*)user_data; + LLCircuitData* cdp = (LLCircuitData*)itemp->mCircuitData; + if(!cdp) return FALSE; + LLHost myhost = cdp->getHost(); + LLSD args; + args["MESSAGE"] = "This will delete local circuit data.\nDo you want to tell the remote host to close the circuit too?"; + LLSD payload; + payload["circuittoclose"] = myhost.getString(); + LLNotifications::instance().add("GenericAlertYesCancel", args, payload, onConfirmCloseCircuit); + return TRUE; +} +// static +bool LLFloaterMessageLog::onConfirmCloseCircuit(const LLSD& notification, const LLSD& response ) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + LLCircuitData* cdp = gMessageSystem->mCircuitInfo.findCircuit(LLHost(notification["payload"]["circuittoclose"].asString())); + if(!cdp) return false; + LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(cdp->getHost()); + switch(option) + { + case 0: // yes + gMessageSystem->newMessageFast(_PREHASH_CloseCircuit); + gMessageSystem->sendReliable(cdp->getHost()); + break; + case 2: // cancel + return false; + break; + case 1: // no + default: + break; + } + if(gMessageSystem->findCircuitCode(cdp->getHost())) + gMessageSystem->disableCircuit(cdp->getHost()); + else + gMessageSystem->getCircuit()->removeCircuitData(cdp->getHost()); + if(regionp) + { + LLHost myhost = regionp->getHost(); + LLSD args; + args["MESSAGE"] = "That host had a region associated with it.\nDo you want to clean that up?"; + LLSD payload; + payload["regionhost"] = myhost.getString(); + LLNotifications::instance().add("GenericAlertYesCancel", args, payload, onConfirmRemoveRegion); + } + return false; +} +// static +bool LLFloaterMessageLog::onConfirmRemoveRegion(const LLSD& notification, const LLSD& response ) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if(option == 0) // yes + LLWorld::getInstance()->removeRegion(LLHost(notification["payload"]["regionhost"].asString())); + return false; +} +// static +void LLFloaterMessageLog::onClickFilterApply(void* user_data) +{ + LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; + floaterp->startApplyingFilter(floaterp->childGetValue("filter_edit"), FALSE); +} +void LLFloaterMessageLog::startApplyingFilter(std::string filter, BOOL force) +{ + LLMessageLogFilter new_filter = LLMessageLogFilter(); + sMessageLogFilterString = filter; + new_filter.set(sMessageLogFilterString); + if(!filter.length() || filter.at(filter.length()-1) != ' ') + childSetText("filter_edit", filter + " "); + if(force + || (new_filter.mNegativeNames != sMessageLogFilter.mNegativeNames) + || (new_filter.mPositiveNames != sMessageLogFilter.mPositiveNames)) + { + stopApplyingFilter(); + sMessageLogFilter = new_filter; + sFloaterMessageLogItems.clear(); + getChild<LLScrollListCtrl>("message_log")->clearRows(); + sBusyApplyingFilter = TRUE; + childSetVisible("message_log", false); + //childSetVisible("log_status_text", true); + mMessageLogFilterApply = new LLMessageLogFilterApply(); + } +} +void LLFloaterMessageLog::stopApplyingFilter() +{ + if(mMessageLogFilterApply) + { + if(!(mMessageLogFilterApply->mFinished)) + mMessageLogFilterApply->cancel(); + //delete mMessageLogFilterApply; + sBusyApplyingFilter = FALSE; + //childSetVisible("log_status_text", false); + childSetVisible("message_log", true); + childSetText("log_status_text", llformat("Showing %d messages from %d", sFloaterMessageLogItems.size(), sMessageLogEntries.size())); + } +} +void LLFloaterMessageLog::updateFilterStatus() +{ + if(!mMessageLogFilterApply || !sBusyApplyingFilter) return; + S32 progress = mMessageLogFilterApply->mProgress; + S32 packets = sMessageLogEntries.size(); + S32 matches = sFloaterMessageLogItems.size(); + std::string text = llformat("Applying filter ( %d / %d ), %d matches ...", progress, packets, matches); + childSetText("log_status_text", text); +} +// static +void LLFloaterMessageLog::onCommitFilter(LLUICtrl* ctrl, void* user_data) +{ + LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; + floaterp->startApplyingFilter(floaterp->childGetValue("filter_edit"), FALSE); +} +// static +void LLFloaterMessageLog::onClickClearLog(void* user_data) +{ + LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; + floaterp->stopApplyingFilter(); + floaterp->getChild<LLScrollListCtrl>("message_log")->clearRows(); + floaterp->setNetInfoMode(NI_NET); + sMessageLogEntries.clear(); + sFloaterMessageLogItems.clear(); +} +// static +void LLFloaterMessageLog::onClickFilterChoice(void* user_data) +{ + LLMenuGL* menu = new LLMenuGL(LLStringUtil::null); + menu->append(new LLMenuItemCallGL("No filter", onClickFilterMenu, NULL, (void*)"")); + menu->append(new LLMenuItemCallGL("Fewer spammy messages", onClickFilterMenu, NULL, (void*)"!StartPingCheck !CompletePingCheck !PacketAck !SimulatorViewerTimeMessage !SimStats !AgentUpdate !AgentAnimation !AvatarAnimation !ViewerEffect !CoarseLocationUpdate !LayerData !CameraConstraint !ObjectUpdateCached !RequestMultipleObjects !ObjectUpdate !ObjectUpdateCompressed !ImprovedTerseObjectUpdate !KillObject !ImagePacket !SendXferPacket !ConfirmXferPacket !TransferPacket")); + menu->append(new LLMenuItemCallGL("Fewer spammy messages (minus sound crap)", onClickFilterMenu, NULL, (void*)"!StartPingCheck !CompletePingCheck !PacketAck !SimulatorViewerTimeMessage !SimStats !AgentUpdate !AgentAnimation !AvatarAnimation !ViewerEffect !CoarseLocationUpdate !LayerData !CameraConstraint !ObjectUpdateCached !RequestMultipleObjects !ObjectUpdate !ObjectUpdateCompressed !ImprovedTerseObjectUpdate !KillObject !ImagePacket !SendXferPacket !ConfirmXferPacket !TransferPacket !SoundTrigger !AttachedSound !PreloadSound")); + menu->append(new LLMenuItemCallGL("Object updates", onClickFilterMenu, NULL, (void*)"ObjectUpdateCached ObjectUpdate ObjectUpdateCompressed ImprovedTerseObjectUpdate KillObject RequestMultipleObjects")); + menu->append(new LLMenuItemCallGL("Abnormal", onClickFilterMenu, NULL, (void*)"Invalid TestMessage AddCircuitCode NeighborList AvatarTextureUpdate SimulatorMapUpdate SimulatorSetMap SubscribeLoad UnsubscribeLoad SimulatorReady SimulatorPresentAtLocation SimulatorLoad SimulatorShutdownRequest RegionPresenceRequestByRegionID RegionPresenceRequestByHandle RegionPresenceResponse UpdateSimulator LogDwellTime FeatureDisabled LogFailedMoneyTransaction UserReportInternal SetSimStatusInDatabase SetSimPresenceInDatabase OpenCircuit CloseCircuit DirFindQueryBackend DirPlacesQueryBackend DirClassifiedQueryBackend DirLandQueryBackend DirPopularQueryBackend GroupNoticeAdd DataHomeLocationRequest DataHomeLocationReply DerezContainer ObjectCategory ObjectExportSelected StateSave ReportAutosaveCrash AgentAlertMessage NearestLandingRegionRequest NearestLandingRegionReply NearestLandingRegionUpdated TeleportLandingStatusChanged ConfirmEnableSimulator KickUserAck SystemKickUser AvatarPropertiesRequestBackend UpdateParcel RemoveParcel MergeParcel LogParcelChanges CheckParcelSales ParcelSales StartAuction ConfirmAuctionStart CompleteAuction CancelAuction CheckParcelAuctions ParcelAuctions ChatPass EdgeDataPacket SimStatus ChildAgentUpdate ChildAgentAlive ChildAgentPositionUpdate ChildAgentDying ChildAgentUnknown AtomicPassObject KillChildAgents ScriptSensorRequest ScriptSensorReply DataServerLogout RequestInventoryAsset InventoryAssetResponse TransferInventory TransferInventoryAck EventLocationRequest EventLocationReply MoneyTransferBackend RoutedMoneyBalanceReply SetStartLocation NetTest SetCPURatio SimCrashed NameValuePair RemoveNameValuePair UpdateAttachment RemoveAttachment EmailMessageRequest EmailMessageReply InternalScriptMail ScriptDataRequest ScriptDataReply InviteGroupResponse TallyVotes LiveHelpGroupRequest LiveHelpGroupReply GroupDataUpdate LogTextMessage CreateTrustedCircuit ParcelRename SystemMessage RpcChannelRequest RpcChannelReply RpcScriptRequestInbound RpcScriptRequestInboundForward RpcScriptReplyInbound ScriptMailRegistration Error")); + menu->updateParent(LLMenuGL::sMenuContainer); + menu->setCanTearOff(FALSE); + LLView* buttonp = sInstance->getChild<LLView>("filter_choice_btn"); + S32 x = buttonp->getRect().mLeft; + S32 y = buttonp->getRect().mBottom; + LLMenuGL::showPopup(sInstance, menu, x, y); +} +// static +void LLFloaterMessageLog::onClickFilterMenu(void* user_data) +{ + std::string filter = std::string((char*)user_data); + sInstance->childSetText("filter_edit", filter); + sInstance->startApplyingFilter(filter, FALSE); +} +// static +void LLFloaterMessageLog::onClickSendToMessageBuilder(void* user_data) +{ + LLFloaterMessageLog* floaterp = (LLFloaterMessageLog*)user_data; + LLScrollListCtrl* scrollp = floaterp->getChild<LLScrollListCtrl>("message_log"); + LLScrollListItem* selected_itemp = scrollp->getFirstSelected(); + if(!selected_itemp) return; + LLUUID id = selected_itemp->getUUID(); + std::vector<LLFloaterMessageLogItem>::iterator end = sFloaterMessageLogItems.end(); + for(std::vector<LLFloaterMessageLogItem>::iterator iter = sFloaterMessageLogItems.begin(); iter != end; ++iter) + { + if(iter->mID == id) + { + std::string message_text = iter->getFull(FALSE); + LLFloaterMessageBuilder::show(message_text); + break; + } + } +} +// </edit> diff --git a/linden/indra/newview/llfloatermessagelog.h b/linden/indra/newview/llfloatermessagelog.h new file mode 100644 index 000000000..ebc4f2aa6 --- /dev/null +++ b/linden/indra/newview/llfloatermessagelog.h @@ -0,0 +1,84 @@ +// <edit> +#include "llfloater.h" +#include "llmessagelog.h" +#include "lltemplatemessagereader.h" +#include "llfloatermessagebuilder.h" + +class LLFloaterMessageLogItem : public LLMessageLogEntry +{ +public: + LLFloaterMessageLogItem(LLMessageLogEntry entry); + ~LLFloaterMessageLogItem(); + LLUUID mID; + U32 mSequenceID; + std::string mName; + std::string mSummary; + U32 mFlags; + std::string getFull(BOOL show_header = TRUE); + BOOL isOutgoing(); +private: + static LLTemplateMessageReader* sTemplateMessageReader; + static std::string getString(LLTemplateMessageReader* readerp, const char* block_name, S32 block_num, const char* var_name, e_message_variable_type var_type, BOOL &returned_hex, BOOL summary_mode = FALSE); +}; +class LLMessageLogFilter +{ +public: + LLMessageLogFilter(); + ~LLMessageLogFilter(); + BOOL set(std::string filter); + std::list<std::string> mPositiveNames; + std::list<std::string> mNegativeNames; +}; +class LLMessageLogFilterApply : public LLEventTimer +{ +public: + LLMessageLogFilterApply(); + void cancel(); + BOOL tick(); + S32 mProgress; + BOOL mFinished; +private: + std::deque<LLMessageLogEntry> mQueuedMessages; + std::deque<LLMessageLogEntry>::iterator mIter; +}; +class LLFloaterMessageLog : public LLFloater, public LLEventTimer +{ +public: + LLFloaterMessageLog(); + ~LLFloaterMessageLog(); + static void show(); + BOOL postBuild(); + BOOL tick(); + LLNetListItem* findNetListItem(LLHost host); + LLNetListItem* findNetListItem(LLUUID id); + void refreshNetList(); + void refreshNetInfo(BOOL force); + enum ENetInfoMode { NI_NET, NI_LOG }; + void setNetInfoMode(ENetInfoMode mode); + static void onLog(LLMessageLogEntry entry); + static void conditionalLog(LLFloaterMessageLogItem item); + static void onCommitNetList(LLUICtrl* ctrl, void* user_data); + static void onCommitMessageLog(LLUICtrl* ctrl, void* user_data); + static void onCommitFilter(LLUICtrl* ctrl, void* user_data); + static BOOL onClickCloseCircuit(void* user_data); + static bool onConfirmCloseCircuit(const LLSD& notification, const LLSD& response ); + static bool onConfirmRemoveRegion(const LLSD& notification, const LLSD& response ); + static void onClickFilterApply(void* user_data); + void startApplyingFilter(std::string filter, BOOL force); + void stopApplyingFilter(); + void updateFilterStatus(); + static BOOL sBusyApplyingFilter; + LLMessageLogFilterApply* mMessageLogFilterApply; + static void onClickClearLog(void* user_data); + static LLFloaterMessageLog* sInstance; + static std::list<LLNetListItem*> sNetListItems; + static std::deque<LLMessageLogEntry> sMessageLogEntries; + static std::vector<LLFloaterMessageLogItem> sFloaterMessageLogItems; + static LLMessageLogFilter sMessageLogFilter; + static std::string sMessageLogFilterString; + ENetInfoMode mNetInfoMode; + static void onClickFilterChoice(void* user_data); + static void onClickFilterMenu(void* user_data); + static void onClickSendToMessageBuilder(void* user_data); +}; +// </edit> diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 524654a28..3e502c0f6 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -121,6 +121,8 @@ #include "llfloaterland.h" #include "llfloaterlandholdings.h" #include "llfloatermap.h" +#include "llfloatermessagebuilder.h" +#include "llfloatermessagelog.h" #include "llfloatermute.h" #include "llfloateropenobject.h" #include "llfloaterpermissionsmgr.h" @@ -394,6 +396,8 @@ void handle_god_mode(void*); // God menu void handle_leave_god_mode(void*); +void handle_open_message_log(void*); +void handle_open_message_builder(void*); BOOL is_inventory_visible( void* user_data ); void handle_reset_view(); @@ -776,6 +780,11 @@ void init_client_menu(LLMenuGL* menu) &handle_show_notifications_console, NULL, NULL, '5', MASK_CONTROL|MASK_SHIFT )); + sub->appendSeparator(); + + sub->append(new LLMenuItemCallGL( "Message Log", &handle_open_message_log, NULL)); + sub->append(new LLMenuItemCallGL( "Message Builder", &handle_open_message_builder, NULL)); + sub->appendSeparator(); sub->append(new LLMenuItemCallGL("Region Info to Debug Console", @@ -3280,6 +3289,16 @@ void process_grant_godlike_powers(LLMessageSystem* msg, void**) } } + +void handle_open_message_log(void*) +{ + LLFloaterMessageLog::show(); +} + +void handle_open_message_builder(void*) +{ + LLFloaterMessageBuilder::show(""); +} /* class LLHaveCallingcard : public LLInventoryCollectFunctor { @@ -8672,6 +8691,30 @@ class LLAdvancedDumpInfoToConsole : public view_listener_t +///////////////////////// +// MESSAGE LOG/BUILDER // +///////////////////////// + + +class LLMessageLogBuilder : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + std::string info_type = userdata.asString(); + if ("MessageLog" == info_type) + { + handle_open_message_log(NULL); + } + else if ("MessageBuilder" == info_type) + { + handle_open_message_builder(NULL); + } + return true; + } +}; + + + /////////////////////////////// // RELOAD SETTINGS OVERRIDES // /////////////////////////////// @@ -11260,6 +11303,8 @@ void initialize_menus() addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole"); addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); + addMenu(new LLMessageLogBuilder(), "Advanced.MessageLog"); + addMenu(new LLMessageLogBuilder(), "Advanced.MessageBuilder"); addMenu(new LLAdvancedReloadSettingsOverrides(), "Advanced.ReloadSettingsOverrides"); addMenu(new LLAdvancedToggleSit(), "Advanced.ToggleSit"); addMenu(new LLAdvancedCheckSit(), "Advanced.CheckSit"); diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml index c85dd4727..53e9e2d02 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -908,6 +908,15 @@ userdata="notifications" /> </menu_item_call> <menu_item_separator /> + <menu_item_call name="Message Log" label="Message Log"> + <on_click function="Advanced.MessageLog" + userdata="MessageLog" /> + </menu_item_call> + <menu_item_call name="Message Builder" label="Message Builder"> + <on_click function="Advanced.MessageBuilder" + userdata="MessageBuilder" /> + </menu_item_call> + <menu_item_separator /> <menu_item_call name="Region Info to Debug Console" label="Region Info to Debug Console"> <on_click function="Advanced.DumpInfoToConsole" From 8f9e76c53c662fd06b1a88288cc84f54e465be8e Mon Sep 17 00:00:00 2001 From: RevolutionSmythe <asdfisbetterthanjkl@gmail.com> Date: Tue, 26 Oct 2010 16:08:09 -0500 Subject: [PATCH 109/239] Bug fixes for earlier commits. Adds cut to the inventory panel along with copy and paste. --- linden/indra/newview/hippoLimits.cpp | 24 +++++++-- linden/indra/newview/hippoLimits.h | 3 +- linden/indra/newview/llfloatertools.cpp | 2 +- linden/indra/newview/llinventoryactions.cpp | 5 ++ linden/indra/newview/llinventorybridge.cpp | 49 +++++++++++++++++++ linden/indra/newview/llinventorybridge.h | 1 + linden/indra/newview/llinventoryclipboard.cpp | 18 ++++++- linden/indra/newview/llinventoryclipboard.h | 7 +++ linden/indra/newview/llmaniptranslate.cpp | 15 +++--- .../default/xui/en-us/menu_inventory.xml | 12 +++-- linden/indra/newview/wlsettingsmanager.cpp | 4 +- 11 files changed, 119 insertions(+), 21 deletions(-) diff --git a/linden/indra/newview/hippoLimits.cpp b/linden/indra/newview/hippoLimits.cpp index 88b86a9dc..78a5856bc 100644 --- a/linden/indra/newview/hippoLimits.cpp +++ b/linden/indra/newview/hippoLimits.cpp @@ -173,7 +173,7 @@ F32 HippoLimits::getMinPrimXPos() const { if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) { - return FLT_MAX; + return FLT_MIN; } else { @@ -185,7 +185,7 @@ F32 HippoLimits::getMinPrimYPos() const { if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) { - return FLT_MAX; + return FLT_MIN; } else { @@ -197,10 +197,28 @@ F32 HippoLimits::getMinPrimZPos() const { if (gSavedSettings.getBOOL("DisableMaxBuildConstraints") && !mEnforceMaxBuild) { - return FLT_MAX; + return FLT_MIN; } else { return mMinPrimZPos; } } + +F32 HippoLimits::getMaxDragDistance() const +{ + if (mMaxDragDistance == 0) + { + return FLT_MAX; + } + else + { + F32 max_drag_distance = gSavedSettings.getBOOL("LimitDragDistance") ? gSavedSettings.getF32("MaxDragDistance") : FLT_MAX; + + if(max_drag_distance > gHippoLimits->getMaxDragDistance()) //Chose the more restrictive + { + max_drag_distance = gHippoLimits->getMaxDragDistance(); + } + return max_drag_distance; + } +} \ No newline at end of file diff --git a/linden/indra/newview/hippoLimits.h b/linden/indra/newview/hippoLimits.h index a5493eb2d..7792a2c30 100644 --- a/linden/indra/newview/hippoLimits.h +++ b/linden/indra/newview/hippoLimits.h @@ -12,7 +12,6 @@ class HippoLimits const F32& getMinHoleSize() const { return mMinHoleSize; } const F32& getMaxHollow() const { return mMaxHollow; } const S32& getMaxLinkedPrims() const { return mMaxLinkedPrims; } - const F32& getMaxDragDistance() const { return mMaxDragDistance; } const S32& getMaxPhysLinkedPrims() const { return mMaxPhysLinkedPrims; } const F32& getMaxInventoryItemsTransfer() const { return mMaxInventoryItemsTransfer; } @@ -21,6 +20,8 @@ class HippoLimits F32 getMinPrimScale() const; F32 getMaxPrimScale() const; + F32 getMaxDragDistance() const; + F32 getMinPrimXPos() const; F32 getMinPrimYPos() const; F32 getMinPrimZPos() const; diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index c092f5a63..2f02f1ef3 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -195,7 +195,7 @@ void LLFloaterTools::updateToolsSizeLimits() getChild<LLSpinCtrl>("Pos X")->setMaxValue(gHippoLimits->getMaxPrimXPos()); getChild<LLSpinCtrl>("Pos Y")->setMaxValue(gHippoLimits->getMaxPrimYPos()); - getChild<LLSpinCtrl>("Pos Z")->setMaxValue(gHippoLimits->getMinPrimZPos()); + getChild<LLSpinCtrl>("Pos Z")->setMaxValue(gHippoLimits->getMaxPrimZPos()); getChild<LLCheckBoxCtrl>("Physical Checkbox Ctrl")->setEnabled(gHippoLimits->mAllowPhysicalPrims); } diff --git a/linden/indra/newview/llinventoryactions.cpp b/linden/indra/newview/llinventoryactions.cpp index 7ae96ad57..25a4a4bfc 100644 --- a/linden/indra/newview/llinventoryactions.cpp +++ b/linden/indra/newview/llinventoryactions.cpp @@ -119,6 +119,11 @@ bool doToSelected(LLFolderView* folder, std::string action) LLInventoryClipboard::instance().reset(); } + if ("cut" == action) + { + LLInventoryClipboard::instance().reset(); + } + std::set<LLUUID> selected_items; folder->getSelectionList(selected_items); diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index b1627b523..f71df2d2d 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp @@ -463,6 +463,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, std::vector<std::str items.push_back(std::string("Copy Separator")); + items.push_back(std::string("Cut")); + if (!isItemCopyable()) + { + disabled_items.push_back(std::string("Cut")); + } + items.push_back(std::string("Copy")); if (!isItemCopyable()) { @@ -813,6 +819,11 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, copyToClipboard(); return; } + else if ("cut" == action) + { + cutToClipboard(); + return; + } else if ("paste" == action) { // Single item only @@ -1086,6 +1097,15 @@ BOOL LLItemBridge::copyToClipboard() const } return FALSE; } +BOOL LLItemBridge::cutToClipboard() const +{ + if(isItemCopyable()) + { + LLInventoryClipboard::instance().addCut(mUUID); + return TRUE; + } + return FALSE; +} LLViewerInventoryItem* LLItemBridge::getItem() const { @@ -1890,6 +1910,35 @@ void LLFolderBridge::pasteFromClipboard() LLPointer<LLInventoryCallback>(NULL)); } } + //Do cuts as well + LLInventoryClipboard::instance().retrieveCuts(objects); + count = objects.count(); + parent_id = mUUID; + for(S32 i = 0; i < count; i++) + { + item = model->getItem(objects.get(i)); + if (item) + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + parent_id, + std::string(), + LLPointer<LLInventoryCallback>(NULL)); + LLInventoryCategory* cat = model->getCategory(item->getUUID()); + if(cat) + { + model->purgeDescendentsOf(mUUID); + } + LLInventoryObject* obj = model->getObject(item->getUUID()); + if(!obj) return; + obj->removeFromServer(); + LLPreview::hide(item->getUUID()); + model->deleteObject(item->getUUID()); + model->notifyObservers(); + } + } } } diff --git a/linden/indra/newview/llinventorybridge.h b/linden/indra/newview/llinventorybridge.h index 45486ed74..2004678f7 100644 --- a/linden/indra/newview/llinventorybridge.h +++ b/linden/indra/newview/llinventorybridge.h @@ -297,6 +297,7 @@ class LLItemBridge : public LLInvFVBridge virtual BOOL removeItem(); virtual BOOL isItemCopyable() const; virtual BOOL copyToClipboard() const; + virtual BOOL cutToClipboard() const; virtual BOOL hasChildren() const { return FALSE; } virtual BOOL isUpToDate() const { return TRUE; } diff --git a/linden/indra/newview/llinventoryclipboard.cpp b/linden/indra/newview/llinventoryclipboard.cpp index 94ffcbd45..95c22aa6f 100644 --- a/linden/indra/newview/llinventoryclipboard.cpp +++ b/linden/indra/newview/llinventoryclipboard.cpp @@ -60,6 +60,11 @@ void LLInventoryClipboard::add(const LLUUID& object) mObjects.put(object); } +void LLInventoryClipboard::addCut(const LLUUID& object) +{ + mCutObjects.put(object); +} + // this stores a single inventory object void LLInventoryClipboard::store(const LLUUID& object) { @@ -87,15 +92,26 @@ void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const } } +void LLInventoryClipboard::retrieveCuts(LLDynamicArray<LLUUID>& inv_objects) const +{ + inv_objects.reset(); + S32 count = mCutObjects.count(); + for(S32 i = 0; i < count; i++) + { + inv_objects.put(mCutObjects[i]); + } +} + void LLInventoryClipboard::reset() { mObjects.reset(); + mCutObjects.reset(); } // returns true if the clipboard has something pasteable in it. BOOL LLInventoryClipboard::hasContents() const { - return (mObjects.count() > 0); + return (mObjects.count() > 0) || (mCutObjects.count() > 0); } diff --git a/linden/indra/newview/llinventoryclipboard.h b/linden/indra/newview/llinventoryclipboard.h index 7a2cf15d6..99e84505a 100644 --- a/linden/indra/newview/llinventoryclipboard.h +++ b/linden/indra/newview/llinventoryclipboard.h @@ -54,6 +54,8 @@ class LLInventoryClipboard // this method adds to the current list. void add(const LLUUID& object); + void addCut(const LLUUID& object); + // this stores a single inventory object void store(const LLUUID& object); @@ -64,6 +66,10 @@ class LLInventoryClipboard // into the array provided. void retrieve(LLDynamicArray<LLUUID>& inventory_objects) const; + // this method gets the objects in the clipboard by copying them + // into the array provided. + void retrieveCuts(LLDynamicArray<LLUUID>& inventory_objects) const; + // this method empties out the clipboard void reset(); @@ -74,6 +80,7 @@ class LLInventoryClipboard static LLInventoryClipboard sInstance; LLDynamicArray<LLUUID> mObjects; + LLDynamicArray<LLUUID> mCutObjects; public: // please don't actually call these diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp index aada65889..cc14b277d 100644 --- a/linden/indra/newview/llmaniptranslate.cpp +++ b/linden/indra/newview/llmaniptranslate.cpp @@ -529,16 +529,13 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask) relative_move -= mDragCursorStartGlobal; // You can't move more than some distance from your original mousedown point. - if (gSavedSettings.getBOOL("LimitDragDistance")) - { - F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance"); + F32 max_drag_distance = gHippoLimits->getMaxDragDistance(); - if(max_drag_distance < gHippoLimits->getMaxDragDistance()) max_drag_distance = gHippoLimits->getMaxDragDistance(); //Take the more restrictive if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance) - { - lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (too far)" << llendl; - gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); - return TRUE; - } + if (max_drag_distance != FLT_MAX && relative_move.magVecSquared() > max_drag_distance * max_drag_distance) + { + lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (too far)" << llendl; + gViewerWindow->setCursor(UI_CURSOR_NOLOCKED); + return TRUE; } F64 axis_magnitude = relative_move * axis_d; // dot product diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml b/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml index 1ae746590..86dc5c737 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_inventory.xml @@ -166,11 +166,15 @@ <on_click filter="" function="Inventory.DoToSelected" userdata="copy_uuid" /> </menu_item_call> <menu_item_separator name="Copy Separator" /> - <menu_item_call bottom_delta="-18" height="18" label="Copy" left="0" mouse_opaque="true" + <menu_item_call bottom_delta="-18" height="18" label="Cut" left="0" mouse_opaque="true" + name="Cut" width="128"> + <on_click filter="" function="Inventory.DoToSelected" userdata="cut" /> + </menu_item_call> + <menu_item_call bottom_delta="-18" height="18" label="Copy" left="0" mouse_opaque="true" name="Copy" width="128"> - <on_click filter="" function="Inventory.DoToSelected" userdata="copy" /> - </menu_item_call> - <menu_item_call bottom_delta="-18" height="18" label="Paste" left="0" mouse_opaque="true" + <on_click filter="" function="Inventory.DoToSelected" userdata="copy" /> + </menu_item_call> + <menu_item_call bottom_delta="-18" height="18" label="Paste" left="0" mouse_opaque="true" name="Paste" width="128"> <on_click filter="" function="Inventory.DoToSelected" userdata="paste" /> </menu_item_call> diff --git a/linden/indra/newview/wlsettingsmanager.cpp b/linden/indra/newview/wlsettingsmanager.cpp index 78516df42..ea37f6171 100644 --- a/linden/indra/newview/wlsettingsmanager.cpp +++ b/linden/indra/newview/wlsettingsmanager.cpp @@ -178,7 +178,7 @@ void WLSettingsManager::Apply() fade = mSky->getFloat("fade", error); mWater->mName = wlWaterPresetName; - if(fade != 0) + if(fade != 0 && water_mgr->mCurParams.mName == wlWaterPresetName)//Load the settings forcefully the first time { LLWaterParamSet oldWset = water_mgr->mCurParams; //This still needs done so that we update right, but load it to the old @@ -201,7 +201,7 @@ void WLSettingsManager::Apply() } mSky->mName = wlSkyPresetName; - if(fade != 0) + if(fade != 0 && sky_mgr->mCurParams.mName == wlSkyPresetName)//Load the settings forcefully the first time { LLWLParamSet oldset = sky_mgr->mCurParams; //This still needs done so that we update right, but load it to the old From b94ba21f2eeb3ff3f59a0c86e9eace89c1db0576 Mon Sep 17 00:00:00 2001 From: elektrahesse <sl@ircsystem.net> Date: Tue, 2 Nov 2010 01:04:47 +0100 Subject: [PATCH 110/239] Fixed a bunch of problems with images uploads on mac, including transparent pngs and tgas not rendering correctly. --- linden/indra/llwindow/llwindowmacosx-objc.h | 2 +- linden/indra/llwindow/llwindowmacosx-objc.mm | 37 +++++++------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/linden/indra/llwindow/llwindowmacosx-objc.h b/linden/indra/llwindow/llwindowmacosx-objc.h index 14c9c928f..a96246e62 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.h +++ b/linden/indra/llwindow/llwindowmacosx-objc.h @@ -49,4 +49,4 @@ CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); OSErr releaseImageCursor(CursorRef ref); OSErr setImageCursor(CursorRef ref); BOOL decodeImageQuartz(std::string filename, LLImageRaw *raw_image); -BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image); +BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image, std::string ext); diff --git a/linden/indra/llwindow/llwindowmacosx-objc.mm b/linden/indra/llwindow/llwindowmacosx-objc.mm index abe8c5d9f..80ad0871e 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.mm +++ b/linden/indra/llwindow/llwindowmacosx-objc.mm @@ -43,12 +43,15 @@ */ #include "llwindowmacosx-objc.h" +#include "lldir.h" -BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) +BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image, std::string ext) { CFDataRef theData = CFDataCreate(kCFAllocatorDefault, data, len); + CGImageSourceRef srcRef = CGImageSourceCreateWithData(theData, NULL); CGImageRef image_ref = CGImageSourceCreateImageAtIndex(srcRef, 0, NULL); + CFRelease(srcRef); size_t width = CGImageGetWidth(image_ref); size_t height = CGImageGetHeight(image_ref); @@ -58,7 +61,7 @@ BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) UInt8* bitmap = (UInt8*)CFDataGetBytePtr(result); CGImageAlphaInfo format = CGImageGetAlphaInfo(image_ref); - if (format != kCGImageAlphaNone) + if (comps == 4) { vImage_Buffer vb; vb.data = bitmap; @@ -68,29 +71,13 @@ BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) if (format & kCGImageAlphaPremultipliedFirst) { - // Ele: ARGB -> BGRA on Intel, need to first reorder the bytes, then unpremultiply as RGBA :) - llinfos << "Unpremultiplying BGRA8888" << llendl; - - for (int i=0; i<height; i++) - { - for (int j=0; j<bytes_per_row; j+=4) - { - unsigned char tmp[4]; - - tmp[0] = bitmap[j*height+3]; - tmp[1] = bitmap[j*height+2]; - tmp[2] = bitmap[j*height+1]; - tmp[3] = bitmap[j*height]; - - memcpy(&bitmap[j*height], &tmp, 4); - } - } - - vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0); + // Ele: Skip unpremultiplication for PSD, PNG and TGA files + if (ext != std::string("psd") && ext != std::string("tga") && ext != std::string("png")) + vImageUnpremultiplyData_ARGB8888(&vb, &vb, 0); } else if (format & kCGImageAlphaPremultipliedLast) { - llinfos << "Unpremultiplying RGBA8888" << llendl; + // Ele: Photoshop Native Transparency needs unmultiplication vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0); } } @@ -100,7 +87,6 @@ BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) raw_image->verticalFlip(); CFRelease(theData); - CFRelease(srcRef); CGImageRelease(image_ref); CFRelease(result); @@ -112,7 +98,10 @@ BOOL decodeImageQuartz(std::string filename, LLImageRaw *raw_image) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSURL *url = [[NSURL alloc] initFileURLWithPath:[NSString stringWithCString:filename.c_str()]]; NSData *data = [NSData dataWithContentsOfURL:url]; - BOOL result = decodeImageQuartz((UInt8*)[data bytes], [data length], raw_image); + + std::string ext = gDirUtilp->getExtension(filename); + + BOOL result = decodeImageQuartz((UInt8*)[data bytes], [data length], raw_image, ext); [pool release]; return result; } From 1851199361cf6757c767f8117658336751089c44 Mon Sep 17 00:00:00 2001 From: RevolutionSmythe <asdfisbetterthanjkl@gmail.com> Date: Sat, 30 Oct 2010 16:30:31 -0500 Subject: [PATCH 111/239] Fixes a missing help button, adds ability to edit trees like normal objects. Adds more places to rebuild clouds so that they will not stick in the incorrect place. --- linden/indra/newview/hippoLimits.cpp | 4 ++-- linden/indra/newview/llcloud.cpp | 2 +- linden/indra/newview/llhudeffectlookat.cpp | 3 ++- linden/indra/newview/llselectmgr.cpp | 2 +- linden/indra/newview/llviewermenu.h | 2 ++ .../newview/skins/default/xui/en-us/notifications.xml | 10 ++++++++++ linden/indra/newview/wlsettingsmanager.cpp | 4 ++++ 7 files changed, 22 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/hippoLimits.cpp b/linden/indra/newview/hippoLimits.cpp index 78a5856bc..a5d6ee6ad 100644 --- a/linden/indra/newview/hippoLimits.cpp +++ b/linden/indra/newview/hippoLimits.cpp @@ -215,9 +215,9 @@ F32 HippoLimits::getMaxDragDistance() const { F32 max_drag_distance = gSavedSettings.getBOOL("LimitDragDistance") ? gSavedSettings.getF32("MaxDragDistance") : FLT_MAX; - if(max_drag_distance > gHippoLimits->getMaxDragDistance()) //Chose the more restrictive + if(max_drag_distance > mMaxDragDistance) //Chose the more restrictive { - max_drag_distance = gHippoLimits->getMaxDragDistance(); + max_drag_distance = mMaxDragDistance; } return max_drag_distance; } diff --git a/linden/indra/newview/llcloud.cpp b/linden/indra/newview/llcloud.cpp index f4f5761b2..3e9b86a3b 100644 --- a/linden/indra/newview/llcloud.cpp +++ b/linden/indra/newview/llcloud.cpp @@ -336,10 +336,10 @@ void LLCloudLayer::destroy() mWindp = NULL; } - void LLCloudLayer::reset() { } + void LLCloudLayer::setWindPointer(LLWind *windp) { if (mWindp) diff --git a/linden/indra/newview/llhudeffectlookat.cpp b/linden/indra/newview/llhudeffectlookat.cpp index 75e2f30da..ccd723f18 100644 --- a/linden/indra/newview/llhudeffectlookat.cpp +++ b/linden/indra/newview/llhudeffectlookat.cpp @@ -53,6 +53,7 @@ // [/RLVa:KB] #include "llxmltree.h" +#include "hippolimits.h" BOOL LLHUDEffectLookAt::sDebugLookAt = FALSE; @@ -553,7 +554,7 @@ void LLHUDEffectLookAt::setSourceObject(LLViewerObject* objectp) //----------------------------------------------------------------------------- void LLHUDEffectLookAt::render() { - if (sDebugLookAt && mSourceObject.notNull()) + if (sDebugLookAt && mSourceObject.notNull() && gHippoLimits->mAllowMinimap) //Has to have allow minimap as well, otherwise it defeats the purpose of no minimap { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index 5a10e98e7..5a5535171 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -1861,7 +1861,7 @@ BOOL LLSelectMgr::selectionAllPCode(LLPCode code) f(const LLPCode& t) : mCode(t) {} virtual bool apply(LLViewerObject* object) { - if (object->getPCode() != mCode) + if (object->getPCode() != mCode && !gSavedSettings.getBOOL("AllowEditingOfTrees")) { return FALSE; } diff --git a/linden/indra/newview/llviewermenu.h b/linden/indra/newview/llviewermenu.h index 632f783d5..f33c20172 100644 --- a/linden/indra/newview/llviewermenu.h +++ b/linden/indra/newview/llviewermenu.h @@ -110,6 +110,8 @@ bool handle_give_money_dialog(); bool handle_object_open(); bool handle_go_to_confirm(); bool handle_go_to(); +void handle_open_message_log(void*); +void handle_open_message_builder(void*); // Export to XML or Collada void handle_export_selected( void * ); diff --git a/linden/indra/newview/skins/default/xui/en-us/notifications.xml b/linden/indra/newview/skins/default/xui/en-us/notifications.xml index b98ff7cc4..3680ca95c 100644 --- a/linden/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/linden/indra/newview/skins/default/xui/en-us/notifications.xml @@ -3651,6 +3651,16 @@ If this box is checked, land owners will not be able to terraform their land reg Default: off </notification> +<notification + icon="alertmodal.tga" + label="Minimum Age" + name="HelpRegionMinimumAge" + type="alertmodal"> +This sets the minimum age (in days) that users entering this sim have to be to enter. + +Default: 0 (disabled) +</notification> + <notification icon="alertmodal.tga" label="Block Fly" diff --git a/linden/indra/newview/wlsettingsmanager.cpp b/linden/indra/newview/wlsettingsmanager.cpp index ea37f6171..853d14f9a 100644 --- a/linden/indra/newview/wlsettingsmanager.cpp +++ b/linden/indra/newview/wlsettingsmanager.cpp @@ -74,6 +74,7 @@ #include "llviewercontrol.h" #include "message.h" #include "meta7windlight.h" +#include "llworld.h" #undef max @@ -223,6 +224,8 @@ void WLSettingsManager::Apply() sky_mgr->loadPreset( wlSkyPresetName, true ); } + LLWorld::getInstance()->rebuildClouds(gAgent.getRegion()); + mSky = NULL; mWater = NULL; mWaterNormal = NULL; @@ -232,6 +235,7 @@ void WLSettingsManager::Apply() void WLSettingsManager::wlresetRegion() { wlIgnoreRegion = false; + LLWorld::getInstance()->rebuildClouds(gAgent.getRegion()); } // static From ff9351cae98c918899c55f0b188ba9fb49510fde Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 1 Nov 2010 18:02:09 -0700 Subject: [PATCH 112/239] Fixed message builder files missing from CMake --- linden/indra/llmessage/CMakeLists.txt | 2 ++ linden/indra/newview/CMakeLists.txt | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/linden/indra/llmessage/CMakeLists.txt b/linden/indra/llmessage/CMakeLists.txt index a48458074..472328180 100644 --- a/linden/indra/llmessage/CMakeLists.txt +++ b/linden/indra/llmessage/CMakeLists.txt @@ -48,6 +48,7 @@ set(llmessage_SOURCE_FILES llmail.cpp llmessagebuilder.cpp llmessageconfig.cpp + llmessagelog.cpp llmessagereader.cpp llmessagetemplate.cpp llmessagetemplateparser.cpp @@ -138,6 +139,7 @@ set(llmessage_HEADER_FILES llmail.h llmessagebuilder.h llmessageconfig.h + llmessagelog.h llmessagereader.h llmessagetemplate.h llmessagetemplateparser.h diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index c3c656666..598af5e93 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -200,6 +200,8 @@ set(viewer_SOURCE_FILES llfloaterlandmark.cpp llfloatermap.cpp llfloatermemleak.cpp + llfloatermessagebuilder.cpp + llfloatermessagelog.cpp llfloatermute.cpp llfloaternamedesc.cpp llfloaternewim.cpp @@ -652,6 +654,8 @@ set(viewer_HEADER_FILES llfloaterlandmark.h llfloatermap.h llfloatermemleak.h + llfloatermessagebuilder.h + llfloatermessagelog.h llfloatermute.h llfloaternamedesc.h llfloaternewim.h From 8905d32b2b7edac96db303fbfae3b992a5adc4df Mon Sep 17 00:00:00 2001 From: RevolutionSmythe <asdfisbetterthanjkl@gmail.com> Date: Mon, 1 Nov 2010 20:21:06 -0500 Subject: [PATCH 113/239] Adds missing .xml files. --- .../xui/en-us/floater_message_builder.xml | 15 +++++++++ .../default/xui/en-us/floater_message_log.xml | 31 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_message_builder.xml create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_message_log.xml diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_message_builder.xml b/linden/indra/newview/skins/default/xui/en-us/floater_message_builder.xml new file mode 100644 index 000000000..c7c49d839 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_message_builder.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="Message Builder" title="Message Builder" width="400" min_width="400" height="600" min_height="600" can_close="true" can_resize="true" can_minimize="true"> + <scroll_list column_padding="0" draw_heading="false" follows="left|top|right" left="10" top="-25" + name="net_list" search_column="0" right="-10" bottom="450"> + <column dynamicwidth="true" name="text" label="text" /> + <column name="state" label="state" width="24" /> + </scroll_list> + <combo_box name="untrusted_message_combo" allow_text_entry="false" follows="left|top" left="10" top="-150" right="-370" bottom="433" tool_tip="No trust"> + </combo_box> + <combo_box name="trusted_message_combo" allow_text_entry="false" follows="left|top" left="30" top="-150" right="-350" bottom="433" tool_tip="Trust"> + </combo_box> + <text_editor name="message_edit" follows="left|top|right|bottom" left="10" top="-168" bottom="30" right="-10" max_length="65535"> + </text_editor> + <button name="send_btn" follows="right|bottom" left="310" top="-570" right="-10" bottom="10" label="Send" tool_tip="Send (Ctrl+Enter)"/> +</floater> diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_message_log.xml b/linden/indra/newview/skins/default/xui/en-us/floater_message_log.xml new file mode 100644 index 000000000..e1ebfe2f1 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_message_log.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="Message Log" title="Message Log" width="400" min_width="400" height="600" min_height="600" can_close="true" can_resize="true" can_minimize="true"> + <scroll_list column_padding="0" draw_heading="false" follows="left|top|right" left="10" top="-25" + name="net_list" search_column="0" right="-10" bottom="450"> + <column dynamicwidth="true" name="text" label="text" /> + <column name="icon0" label="icon0" width="24" /> + <column name="icon1" label="icon1" width="24" /> + </scroll_list> + <button name="filter_choice_btn" follows="left|top" left="10" top="-150" right="-370" bottom="430" label="…"/> + <line_editor name="filter_edit" follows="left|top|right" left="30" top="-149" right="-28" bottom="430" max_length="65535"/> + <button name="filter_apply_btn" follows="top|right" left="370" top="-150" right="-9" bottom="430" label="✔"/> + <button name="clear_log_btn" follows="top|right" left="370" top="-170" right="-9" bottom="410" label="C"/> + <scroll_list column_padding="0" draw_heading="false" follows="left|top|right" left="10" top="-190" + name="message_log" search_column="0" right="-10" bottom="200"> + <column name="sequence" label="sequence" width="48"/> + <column name="type" label="type" width="32"/> + <column name="direction" label="direction" width="32"/> + <column name="net" label="net" width="100"/> + <column name="name" label="name" width="128"/> + <!--<column name="flag_zer" label="zer" width="8"/> + <column name="flag_rel" label="rel" width="8"/> + <column name="flag_rsd" label="rsd" width="8"/> + <column name="flag_ack" label="ack" width="8"/>--> + <column name="summary" label="summary" dynamicwidth="true"/> + </scroll_list> + <text name="log_status_text" follows="left|top|right" left="10" top="-172" right="-10" height="20"> + </text> + <text_editor name="net_info" follows="left|top|right|bottom" left="10" top="-400" bottom="30" right="-10" enabled="false" max_length="65535"> + </text_editor> + <button name="send_to_message_builder_btn" follows="right|bottom" left="210" top="-570" right="-10" bottom="10" label="Send to Message Builder" enabled="false"/> +</floater> From 3875eba69bf41ebcec16168a813c7a6d4a779262 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 1 Nov 2010 19:57:36 -0700 Subject: [PATCH 114/239] Don't show the open region settings panel in the Estate window when the OpenRegionSettings capability isn't found (i.e. we're not on Aurora) --- linden/indra/newview/llfloaterregioninfo.cpp | 13 +++++++++---- linden/indra/newview/llviewerregion.cpp | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index c7f1c38fa..aca8db733 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -182,10 +182,15 @@ BOOL LLFloaterRegionInfo::postBuild() LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_general.xml"); mTab->addTabPanel(panel, panel->getLabel(), TRUE); - panel = new LLPanelRegionOpenSettingsInfo; - mInfoPanels.push_back(panel); - LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_open_region_settings.xml"); - mTab->addTabPanel(panel, panel->getLabel(), FALSE); + // We only use this panel on Aurora-based sims -- MC + std::string url = gAgent.getRegion()->getCapability("OpenRegionSettings"); + if (!url.empty()) + { + panel = new LLPanelRegionOpenSettingsInfo; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_open_region_settings.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + } panel = new LLPanelRegionDebugInfo; mInfoPanels.push_back(panel); diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index b63914c42..cf2e3a461 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp @@ -1436,6 +1436,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); + // Aurora settings -- MC + capabilityNames.append("OpenRegionSettings"); capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); From a6854eccc53030d67c653d961a8c0eea64bd2715 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 1 Nov 2010 19:58:12 -0700 Subject: [PATCH 115/239] Added missing cloud settings to settings.xml --- .../indra/newview/app_settings/settings.xml | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 576a5535a..e668782fd 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -195,6 +195,94 @@ <key>Value</key> <real>20</real> </map> + <key>ClassicCloudHeight</key> + <map> + <key>Comment</key> + <string>Height for classic particle clouds</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>192</integer> + </map> + <key>ClassicCloudRange</key> + <map> + <key>Comment</key> + <string>Height range for classic particle clouds</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>48</integer> + </map> + <key>CloudCountMax</key> + <map> + <key>Comment</key> + <string>Max amount of particle clouds</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>20</integer> + </map> + <key>CloudVelocityScale</key> + <map> + <key>Comment</key> + <string>Particle cloud velocity</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>CloudDecayRate</key> + <map> + <key>Comment</key> + <string>Particle cloud decay rate</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>-5</integer> + </map> + <key>CloudGrowRate</key> + <map> + <key>Comment</key> + <string>Particle cloud grow rate</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>5</integer> + </map> + <key>CloudUpdateRate</key> + <map> + <key>Comment</key> + <string>Particle cloud update rate</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>CloudDensity</key> + <map> + <key>Comment</key> + <string>Particle cloud density</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>25</integer> + </map> <key>ConnectingToRegionTimeout</key> <map> <key>Comment</key> From 037d0e34027db6fb4c94c6bba7d70cd56b1b4077 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 1 Nov 2010 20:20:52 -0700 Subject: [PATCH 116/239] Load default grid list url from new GridUpdateList setting --- linden/indra/newview/app_settings/settings.xml | 11 +++++++++++ linden/indra/newview/hippoGridManager.cpp | 4 ++-- linden/indra/newview/hippoGridManager.h | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index e668782fd..916abcb33 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -506,6 +506,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>GridUpdateList</key> + <map> + <key>Comment</key> + <string>Location to download default grid options.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>http://imprudenceviewer.org/app/grids/</string> + </map> <key>GoAction</key> <map> <key>Comment</key> diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippoGridManager.cpp index 5a229fda7..dd0fa3518 100644 --- a/linden/indra/newview/hippoGridManager.cpp +++ b/linden/indra/newview/hippoGridManager.cpp @@ -799,7 +799,7 @@ void HippoGridManager::loadFromFile() parseFile(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml"), !mGridInfo.empty()); // merge grid info from web site, if newer. Force load, if list of grids is empty. if (gSavedSettings.getBOOL("CheckForGridUpdates")) - parseUrl("http://imprudenceviewer.org/app/grids/", !mGridInfo.empty()); + parseUrl(gSavedSettings.getString("GridUpdateList"), !mGridInfo.empty()); std::string last_grid = gSavedSettings.getString("LastSelectedGrid"); if (last_grid.empty()) last_grid = gSavedSettings.getString("DefaultGrid"); @@ -808,7 +808,7 @@ void HippoGridManager::loadFromFile() } -void HippoGridManager::parseUrl(const char* url, bool mergeIfNewer) +void HippoGridManager::parseUrl(const std::string url, bool mergeIfNewer) { llinfos << "Loading grid info from '" << url << "'." << llendl; diff --git a/linden/indra/newview/hippoGridManager.h b/linden/indra/newview/hippoGridManager.h index bc19ff8af..8429dbaf6 100644 --- a/linden/indra/newview/hippoGridManager.h +++ b/linden/indra/newview/hippoGridManager.h @@ -172,7 +172,7 @@ class HippoGridManager void cleanup(); void loadFromFile(); void parseFile(const std::string& fileName, bool mergeIfNewer); - void parseUrl(const char* url, bool mergeIfNewer); + void parseUrl(const std::string url, bool mergeIfNewer); void parseData(LLSD &gridInfo, bool mergeIfNewer); }; From 5df80675e33f774a60b2021e41b77ffed574d523 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 1 Nov 2010 20:24:12 -0700 Subject: [PATCH 117/239] Don't allow setting draw distance below 0 in the openregionsettings --- linden/indra/newview/kowopenregionsettings.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/kowopenregionsettings.cpp b/linden/indra/newview/kowopenregionsettings.cpp index 3cceb0cb3..f5a845aa2 100644 --- a/linden/indra/newview/kowopenregionsettings.cpp +++ b/linden/indra/newview/kowopenregionsettings.cpp @@ -77,7 +77,11 @@ class OpenRegionInfoUpdate : public LLHTTPNode } if ( body.has("DrawDistance") ) { - gAgent.mDrawDistance = body["DrawDistance"].asReal(); + F32 distance = body["DrawDistance"].asReal(); + if (distance > 0) + { + gAgent.mDrawDistance = distance; + } } if ( body.has("ForceDrawDistance") ) { From b9867ca9e51b273bbd298d7a1ca5f893d5c3b219 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 1 Nov 2010 21:31:33 -0700 Subject: [PATCH 118/239] Fixed crash when logging into an Aurora sim without the region/estate window open --- linden/indra/newview/kowopenregionsettings.cpp | 7 +++---- linden/indra/newview/llfloaterregioninfo.cpp | 15 ++++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/linden/indra/newview/kowopenregionsettings.cpp b/linden/indra/newview/kowopenregionsettings.cpp index f5a845aa2..86a426c03 100644 --- a/linden/indra/newview/kowopenregionsettings.cpp +++ b/linden/indra/newview/kowopenregionsettings.cpp @@ -47,7 +47,7 @@ class OpenRegionInfoUpdate : public LLHTTPNode const LLSD& context, const LLSD& input) const { - if (!input.isMap() || !input.has("body")) + if (!input || !context || !input.isMap() || !input.has("body")) { llinfos << "malformed OpenRegionInfo update!" << llendl; return; @@ -205,10 +205,9 @@ class OpenRegionInfoUpdate : public LLHTTPNode gFloaterTools->updateToolsSizeLimits(); //Update the floater if its around - LLPanelRegionOpenSettingsInfo* floater; - floater = LLFloaterRegionInfo::getPanelOpenSettings(); + LLPanelRegionOpenSettingsInfo* floater = LLFloaterRegionInfo::getPanelOpenSettings(); - if(floater != NULL) + if (floater != NULL) { floater->refreshFromRegion(gAgent.getRegion()); } diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index aca8db733..76e6b0111 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -426,11 +426,16 @@ LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() LLPanelRegionOpenSettingsInfo* LLFloaterRegionInfo::getPanelOpenSettings() { LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); - if (!floater) return NULL; - LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); - LLPanelRegionOpenSettingsInfo* panel; - panel = (LLPanelRegionOpenSettingsInfo*)tab->getChild<LLPanel>("RegionSettings"); - return panel; + if (floater) + { + LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels"); + LLPanelRegionOpenSettingsInfo* panel = (LLPanelRegionOpenSettingsInfo*)tab->getChild<LLPanel>("RegionSettings", FALSE, FALSE); + if (panel) + { + return panel; + } + } + return NULL; } void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) From 0c4a202692432b32bb8f8157b8b51085bd56a21c Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Mon, 1 Nov 2010 21:39:24 -0700 Subject: [PATCH 119/239] Use the right name for the Aurora capability --- linden/indra/newview/llfloaterregioninfo.cpp | 2 +- linden/indra/newview/llviewerregion.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index 76e6b0111..9e6f32347 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -183,7 +183,7 @@ BOOL LLFloaterRegionInfo::postBuild() mTab->addTabPanel(panel, panel->getLabel(), TRUE); // We only use this panel on Aurora-based sims -- MC - std::string url = gAgent.getRegion()->getCapability("OpenRegionSettings"); + std::string url = gAgent.getRegion()->getCapability("DispatchOpenRegionSettings"); if (!url.empty()) { panel = new LLPanelRegionOpenSettingsInfo; diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index cf2e3a461..e62bd3c57 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp @@ -1422,6 +1422,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLSD capabilityNames = LLSD::emptyArray(); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); + // Aurora settings -- MC capabilityNames.append("DispatchOpenRegionSettings"); capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("DispatchWindLightSettings"); @@ -1436,8 +1437,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); - // Aurora settings -- MC - capabilityNames.append("OpenRegionSettings"); capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); From 76ef871eea3dd8274389e3bc671905e32083189a Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Tue, 2 Nov 2010 17:47:00 +0200 Subject: [PATCH 120/239] Revert "Fix Bug #671 (aka VWR-1603): Duckwalk is too fast" This reverts commit 694e64db099caa07ca7a1ef740f8dac524eb2479. It seems to not work for small avatars who depend on the fast default animation to make their walk look realistic. This is all different anyway in v2.2, so let's not thouch it for now. --- linden/indra/llcharacter/llkeyframewalkmotion.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/linden/indra/llcharacter/llkeyframewalkmotion.cpp b/linden/indra/llcharacter/llkeyframewalkmotion.cpp index 4aa9d2ae3..b5817e5bd 100644 --- a/linden/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/linden/indra/llcharacter/llkeyframewalkmotion.cpp @@ -50,7 +50,6 @@ const F32 MIN_WALK_SPEED = 0.1f; // minimum speed at which we use velocity for d const F32 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation const F32 SPEED_ADJUST_MAX = 2.5f; // maximum adjustment of walk animation playback speed const F32 SPEED_ADJUST_MAX_SEC = 3.f; // maximum adjustment to walk animation playback speed for a second -const F32 SPEED_FINAL_SCALING = 0.5f; // final scaling for walk animation const F32 DRIFT_COMP_MAX_TOTAL = 0.07f;//0.55f; // maximum drift compensation overall, in any direction const F32 DRIFT_COMP_MAX_SPEED = 4.f; // speed at which drift compensation total maxes out const F32 MAX_ROLL = 0.6f; @@ -315,7 +314,6 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask) } mAnimSpeed = (mAvgSpeed + mSpeedAdjust) * mRelativeDir; - mAnimSpeed = mAnimSpeed * SPEED_FINAL_SCALING; // char debug_text[64]; // sprintf(debug_text, "Foot slip vel: %.2f", footSlipVelocity); // mCharacter->addDebugText(debug_text); From f10af893916d543fb29f2740ecfc8039b0a31b73 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 30 Oct 2010 14:16:00 -0700 Subject: [PATCH 121/239] Added conversion function for plugin EState to string info --- .../indra/llplugin/llpluginprocessparent.cpp | 52 ++++++++++++++++++- linden/indra/llplugin/llpluginprocessparent.h | 1 + 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp index 8db6046e2..8fd18ef05 100755 --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp @@ -1084,7 +1084,7 @@ std::string LLPluginProcessParent::getPluginVersion(void) void LLPluginProcessParent::setState(EState state) { - LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL; + LL_DEBUGS("Plugin") << "setting state to " << stateToString(state) << LL_ENDL; mState = state; }; @@ -1118,3 +1118,53 @@ bool LLPluginProcessParent::pluginLockedUp() return (mHeartbeat.getStarted() && mHeartbeat.hasExpired()); } +std::string LLPluginProcessParent::stateToString(EState state) +{ + std::string eng = "unknown plugin state"; + switch (state) + { + case STATE_UNINITIALIZED: + eng = "STATE_UNINITIALIZED"; + break; + case STATE_INITIALIZED: + eng = "STATE_INITIALIZED - init() has been called"; + break; + case STATE_LISTENING: + eng = "STATE_LISTENING - listening for incoming connection"; + break; + case STATE_LAUNCHED: + eng = "STATE_LAUNCHED - process has been launched"; + break; + case STATE_CONNECTED: + eng = "STATE_CONNECTED - process has connected"; + break; + case STATE_HELLO: + eng = "STATE_HELLO - first message from the plugin process has been received"; + break; + case STATE_LOADING: + eng = "STATE_LOADING - process has been asked to load the plugin"; + break; + case STATE_RUNNING: + eng = "STATE_RUNNING - plugin running"; + break; + case STATE_LAUNCH_FAILURE: + eng = "STATE_LAUNCH_FAILURE - failure before plugin loaded"; + break; + case STATE_ERROR: + eng = "STATE_ERROR - generic bailout state"; + break; + case STATE_CLEANUP: + eng = "STATE_CLEANUP - clean everything up"; + break; + case STATE_EXITING: + eng = "STATE_EXITING - tried to kill process, waiting for it to exit"; + break; + case STATE_DONE: + eng = "STATE_DONE - plugin done"; + break; + default: + break; + } + + return llformat("(%d) ", (S32)state) + eng; +} diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h index a8929b194..95f5f70c5 100755 --- a/linden/indra/llplugin/llpluginprocessparent.h +++ b/linden/indra/llplugin/llpluginprocessparent.h @@ -147,6 +147,7 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner }; EState mState; void setState(EState state); + std::string stateToString(EState state); bool pluginLockedUp(); bool pluginLockedUpOrQuit(); From c07d4360df2ba313fb8bd10f0cf2abccf5d485a9 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 29 Oct 2010 15:34:10 +0200 Subject: [PATCH 122/239] RED-595 was renamed to IMP-595 --- linden/indra/newview/llmediactrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llmediactrl.cpp b/linden/indra/newview/llmediactrl.cpp index c3bcf8516..8b60326d6 100644 --- a/linden/indra/newview/llmediactrl.cpp +++ b/linden/indra/newview/llmediactrl.cpp @@ -201,7 +201,7 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) // *HACK: media_plugin_webkit automatically takes focus on mouseup, // in addition to the onFocusReceived() call below. Undo this. JC - // RED-595: Is this really still the case for webkit? + // IMP-595: Is this really still the case for webkit? if (!mTakeFocusOnClick) { mMediaSource->focus(false); From 1fd8a0bf47b7131f7ffbcd96ab0c7ec32a56d3ab Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 29 Oct 2010 15:51:10 +0200 Subject: [PATCH 123/239] Delete piece of code that is redundant. --- linden/indra/media_plugins/webkit/media_plugin_webkit.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index 0fb64bb82..767090c39 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -337,14 +337,6 @@ class MediaPluginWebKit : // append details to agent string LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); -#if 0 // FIXME (webkit_plugins): this doesn't compile with latest version of llqtwebkit - // error: ‘class LLQtWebKit’ has no member named ‘setWindowOpenBehavior’ - // error: ‘WOB_SIMULATE_BLANK_HREF_CLICK’ is not a member of ‘LLQtWebKit’ - - // Set up window open behavior - LLQtWebKit::getInstance()->setWindowOpenBehavior(mBrowserWindowId, LLQtWebKit::WOB_SIMULATE_BLANK_HREF_CLICK); -#endif - #if !LL_QTWEBKIT_USES_PIXMAPS // don't flip bitmap LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); From 7e6a6ef92f15f4613acd6dcae9eab78f37866376 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sat, 30 Oct 2010 20:29:37 +0200 Subject: [PATCH 124/239] Make LLStringUtilBase<T>::null a constant. --- linden/indra/llcommon/llstring.h | 4 ++-- linden/indra/newview/llnamelistctrl.cpp | 2 +- linden/indra/newview/llnamelistctrl.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index 3c6cd43ec..bab89b12d 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -209,7 +209,7 @@ class LLStringUtilBase ///////////////////////////////////////////////////////////////////////////////////////// // Static Utility functions that operate on std::strings - static std::basic_string<T> null; + static std::basic_string<T> const null; typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t; static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map); @@ -299,7 +299,7 @@ class LLStringUtilBase }; -template<class T> std::basic_string<T> LLStringUtilBase<T>::null; +template<class T> std::basic_string<T> const LLStringUtilBase<T>::null; typedef LLStringUtilBase<char> LLStringUtil; typedef LLStringUtilBase<llwchar> LLWStringUtil; diff --git a/linden/indra/newview/llnamelistctrl.cpp b/linden/indra/newview/llnamelistctrl.cpp index 453cf7fab..e445df54c 100644 --- a/linden/indra/newview/llnamelistctrl.cpp +++ b/linden/indra/newview/llnamelistctrl.cpp @@ -72,7 +72,7 @@ LLNameListCtrl::~LLNameListCtrl() // public BOOL LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, - BOOL enabled, std::string& suffix) + BOOL enabled, const std::string& suffix) { //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; diff --git a/linden/indra/newview/llnamelistctrl.h b/linden/indra/newview/llnamelistctrl.h index 1b7795ddf..beb4ede83 100644 --- a/linden/indra/newview/llnamelistctrl.h +++ b/linden/indra/newview/llnamelistctrl.h @@ -58,7 +58,7 @@ class LLNameListCtrl // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. BOOL addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, - BOOL enabled = TRUE, std::string& suffix = LLStringUtil::null); + BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null); BOOL addNameItem(LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM); virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); From 27cd3784b870deec313678d28de65bb8d7fe4626 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 31 Oct 2010 15:47:04 +0100 Subject: [PATCH 125/239] Fix llqtwebkit version incompatibility. This patch has the minimum changes needed to be compatible with LLQTWEBKIT_API_VERSION 2. From llqtwebkit.h: Version 2: indra/media_plugins/webkit/media_plugin_webkit.cpp: * Changed the usage of the event parameters in onClickLinkHref and onClickLinkNoFollow events slightly. The clicked URI for both should now be retrieved with getEventUri() instead of getStringValue(). The "target" string in onClickLinkHref is now retrieved with getStringValue() instead of getStringValue2(). * The contents of getStringValue2() in the onClickLinkHref event is now a unique ID for the window proxy the click targets. all changed files: * Removed the "link target type" concept, since it doesn't really belong here. Note that not all changes have been taken into account, since we need a LOT of code changes for MoaP before that gets relevant; most notably: "target" and "uuid" aren't used anywhere. The new LLEmbeddedBrowserWindowObserver::onWindowGeometryChangeRequested and LLEmbeddedBrowserWindowObserver::onRequestFilePicker are still not implemented. Version 1 introduced LLEmbeddedBrowserWindowObserver::onWindowCloseRequested which is also still not implemented. --- linden/indra/llplugin/llpluginclassmedia.cpp | 28 ------------------- linden/indra/llplugin/llpluginclassmedia.h | 11 -------- .../webkit/media_plugin_webkit.cpp | 17 +++++++++-- 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/linden/indra/llplugin/llpluginclassmedia.cpp b/linden/indra/llplugin/llpluginclassmedia.cpp index 5dc0c4722..85241bec1 100755 --- a/linden/indra/llplugin/llpluginclassmedia.cpp +++ b/linden/indra/llplugin/llpluginclassmedia.cpp @@ -150,7 +150,6 @@ void LLPluginClassMedia::reset() mProgressPercent = 0; mClickURL.clear(); mClickTarget.clear(); - mClickTargetType = TARGET_NONE; // media_time class mCurrentTime = 0.0f; @@ -722,30 +721,6 @@ void LLPluginClassMedia::setJavascriptEnabled(const bool enabled) sendMessage(message); } -LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type) -{ - llassert(false); - return LLPluginClassMedia::TARGET_OTHER; -#if 0 - // convert a LinkTargetType value from llqtwebkit to an ETargetType - // so that we don't expose the llqtwebkit header in viewer code - switch (target_type) - { - case LLQtWebKit::LTT_TARGET_NONE: - return LLPluginClassMedia::TARGET_NONE; - - case LLQtWebKit::LTT_TARGET_BLANK: - return LLPluginClassMedia::TARGET_BLANK; - - case LLQtWebKit::LTT_TARGET_EXTERNAL: - return LLPluginClassMedia::TARGET_EXTERNAL; - - default: - return LLPluginClassMedia::TARGET_OTHER; - } -#endif -} - /* virtual */ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { @@ -998,15 +973,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mClickURL = message.getValue("uri"); mClickTarget = message.getValue("target"); - U32 target_type = message.getValueU32("target_type"); - mClickTargetType = ::getTargetTypeFromLLQtWebkit(target_type); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); } else if(message_name == "click_nofollow") { mClickURL = message.getValue("uri"); mClickTarget.clear(); - mClickTargetType = TARGET_NONE; mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); } else if(message_name == "cookie_set") diff --git a/linden/indra/llplugin/llpluginclassmedia.h b/linden/indra/llplugin/llpluginclassmedia.h index abb79268f..0004971c6 100755 --- a/linden/indra/llplugin/llpluginclassmedia.h +++ b/linden/indra/llplugin/llpluginclassmedia.h @@ -225,16 +225,6 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner // This is valid after MEDIA_EVENT_CLICK_LINK_HREF std::string getClickTarget() const { return mClickTarget; }; - typedef enum - { - TARGET_NONE, // empty href target string - TARGET_BLANK, // target to open link in user's preferred browser - TARGET_EXTERNAL, // target to open link in external browser - TARGET_OTHER // nonempty and unsupported target type - }ETargetType; - - // This is valid after MEDIA_EVENT_CLICK_LINK_HREF - ETargetType getClickTargetType() const { return mClickTargetType; }; std::string getMediaName() const { return mMediaName; }; std::string getMediaDescription() const { return mMediaDescription; }; @@ -366,7 +356,6 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner std::string mLocation; std::string mClickURL; std::string mClickTarget; - ETargetType mClickTargetType; ///////////////////////////////////////// // media_time class diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index 767090c39..eed59a24d 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -326,7 +326,11 @@ class MediaPluginWebKit : LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); // create single browser window +#if LLQTWEBKIT_API_VERSION >= 2 + mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow(mWidth, mHeight /*, mTarget*/ ); // We don't have mTarget yet. +#else mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight ); +#endif // tell LLQtWebKit about the size of the browser window LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); @@ -527,10 +531,14 @@ class MediaPluginWebKit : void onClickLinkHref(const EventType& event) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); +#if LLQTWEBKIT_API_VERSION >= 2 + message.setValue("uri", event.getEventUri()); + message.setValue("target", event.getStringValue()); + message.setValue("uuid", event.getStringValue2()); +#else + // This will work as long as we don't need "uuid", which will be needed for MoaP. message.setValue("uri", event.getStringValue()); message.setValue("target", event.getStringValue2()); -#if 0 // FIXME (webkit_plugins): error: ‘const class LLEmbeddedBrowserWindowEvent’ has no member named ‘getLinkType’ - message.setValueU32("target_type", event.getLinkType()); #endif sendMessage(message); } @@ -540,10 +548,13 @@ class MediaPluginWebKit : void onClickLinkNoFollow(const EventType& event) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); +#if LLQTWEBKIT_API_VERSION >= 2 + message.setValue("uri", event.getEventUri()); +#else message.setValue("uri", event.getStringValue()); +#endif sendMessage(message); } - //////////////////////////////////////////////////////////////////////////////// // virtual From 920cf3112be3f321d623c6d25fe67ded32f92627 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 31 Oct 2010 17:56:55 +0100 Subject: [PATCH 126/239] Install qtxmlpatterns4.dll on windows. --- linden/indra/newview/viewer_manifest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index ab889206a..d3ce9f2ec 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -282,6 +282,7 @@ def construct(self): self.path("qtnetwork4.dll") self.path("qtopengl4.dll") self.path("qtwebkit4.dll") + self.path("qtxmlpatterns4.dll") self.path("ssleay32.dll") self.end_prefix() From 166d8afffe8e0f6b9168f06e41100680c827d0af Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 31 Oct 2010 19:06:40 +0100 Subject: [PATCH 127/239] Add headers from libdbus-1-dev_1.2.1-5+lenny1_i386.deb to dbusglib linux 32 bit package. The dbusglib package contains headers from both, libdbus-1 as well as libdbus-glib-1, but only the shared object file of the latter. This isn't entirely consistent with how we do this for other packages that we want to use the system provided ones for: then we link against prebuilts, but just don't install them. However, if that is working then it's very likely that this method will work too for a C library, so I guess it's ok like this. This package now contains the shared library from libdbus-glib-1-2_0.76-1_i386.deb (plus symlinks) and the headers from libdbus-glib-1-dev_0.76-1_i386.deb AND libdbus-1-dev_1.2.1-5+lenny1_i386.deb. --- linden/install.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index 4a6cb23a4..4a5c827ab 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -306,9 +306,9 @@ <key>linux</key> <map> <key>md5sum</key> - <string>bfcff12c0d5cef53aa2e04fa53299b23</string> + <string>5bbf7e33dadc7d046dcf44883a9ec3d0</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/dbusglib-linux-20101012.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/dbusglib-linux-20101031.tar.bz2</uri> </map> <key>linux64</key> <map> From 99626354e858db12bba14b44db4568cad6e5b1df Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sun, 31 Oct 2010 14:47:04 -0700 Subject: [PATCH 128/239] Added missing qtxmlpatterns4.dll to CopyWinLibs.cmake --- linden/indra/cmake/CopyWinLibs.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linden/indra/cmake/CopyWinLibs.cmake b/linden/indra/cmake/CopyWinLibs.cmake index 44d35ed6c..a091a3177 100644 --- a/linden/indra/cmake/CopyWinLibs.cmake +++ b/linden/indra/cmake/CopyWinLibs.cmake @@ -48,6 +48,7 @@ set(plugintest_debug_files qtnetworkd4.dll qtopengld4.dll qtwebkitd4.dll + qtxmlpatternsd4.dll ssleay32.dll ) copy_if_different( @@ -93,6 +94,7 @@ set(plugintest_release_files qtnetwork4.dll qtopengl4.dll qtwebkit4.dll + qtxmlpatterns4.dll ssleay32.dll ) copy_if_different( @@ -162,6 +164,7 @@ set(plugins_debug_files qtnetworkd4.dll qtopengld4.dll qtwebkitd4.dll + qtxmlpatternsd4.dll ssleay32.dll ) copy_if_different( @@ -181,6 +184,7 @@ set(plugins_release_files qtnetwork4.dll qtopengl4.dll qtwebkit4.dll + qtxmlpatterns4.dll ssleay32.dll ) copy_if_different( From 7ed48e0084567483064f29d05e1d8d9c3cc74c72 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 2 Nov 2010 10:25:20 -0700 Subject: [PATCH 129/239] Deleted OPENAL.cmake.imp file --- linden/indra/cmake/OPENAL.cmake.imp | 115 ---------------------------- 1 file changed, 115 deletions(-) delete mode 100644 linden/indra/cmake/OPENAL.cmake.imp diff --git a/linden/indra/cmake/OPENAL.cmake.imp b/linden/indra/cmake/OPENAL.cmake.imp deleted file mode 100644 index 60abef360..000000000 --- a/linden/indra/cmake/OPENAL.cmake.imp +++ /dev/null @@ -1,115 +0,0 @@ -# -*- cmake -*- - -include(Variables) -include(Linking) - -set(OPENAL ON CACHE BOOL "Enable OpenAL") - - -if (OPENAL) - - # message(STATUS "Building with OpenAL audio support") - - # OPENAL_LIB - use_prebuilt_binary(openal) - - if (WINDOWS) - set(OPENAL_LIB - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/openal32.lib - debug ${ARCH_PREBUILT_DIRS_DEBUG}/openal32.lib - ) - - elseif (DARWIN) - # Look for for system's OpenAL.framework - find_library(OPENAL_LIB - NAMES openal.1 - PATHS ${ARCH_PREBUILT_DIRS_RELEASE} - NO_DEFAULT_PATH - ) - else (WINDOWS) - set(OPENAL_LIB openal) - endif (WINDOWS) - - if (NOT OPENAL_LIB) - message(FATAL_ERROR "OpenAL not found!") - else (NOT OPENAL_LIB) - # message(STATUS "OpenAL found: ${OPENAL_LIB}") - endif (NOT OPENAL_LIB) - - - - # OPENAL_INCLUDE_DIR - - if (DARWIN) - set(OPENAL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/AL) - else (DARWIN) - find_path(OPENAL_INCLUDE_DIR - NAMES al.h - PATHS ${LIBS_PREBUILT_DIR}/include/AL - ) - endif (DARWIN) - - if (NOT OPENAL_INCLUDE_DIR) - message(FATAL_ERROR "al.h not found!") - else (NOT OPENAL_INCLUDE_DIR) - # message(STATUS "al.h found in: ${OPENAL_INCLUDE_DIR}") - endif (NOT OPENAL_INCLUDE_DIR) - - - - # ALUT_LIB - - if (WINDOWS) - set(ALUT_LIB - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/alut.lib - debug ${ARCH_PREBUILT_DIRS_DEBUG}/alut.lib - ) - elseif (DARWIN) - find_library( ALUT_LIB - NAMES alut.0 - PATHS ${ARCH_PREBUILT_DIRS_RELEASE} - NO_DEFAULT_PATH - ) - else (WINDOWS) - set(ALUT_LIB alut) - endif (WINDOWS) - - if (NOT ALUT_LIB) - message(FATAL_ERROR "ALUT not found!") - else (NOT ALUT_LIB) - # message(STATUS "ALUT found: ${ALUT_LIB}") - endif (NOT ALUT_LIB) - - - - # ALUT_INCLUDE_DIR - - find_path(ALUT_INCLUDE_DIR - NAMES alut.h - PATHS ${OPENAL_INCLUDE_DIR} - ) - - if (NOT ALUT_INCLUDE_DIR) - message(FATAL_ERROR "alut.h not found!") - else (NOT ALUT_INCLUDE_DIR) - # message(STATUS "alut.h found in: ${ALUT_INCLUDE_DIR}") - endif (NOT ALUT_INCLUDE_DIR) - - - - set(OPENAL_LIBRARIES - ${OPENAL_LIB} - ${ALUT_LIB} - ) - - set(OPENAL_INCLUDE_DIRS - ${OPENAL_INCLUDE_DIR} - ${ALUT_INCLUDE_DIR} - ) - - - set(OPENAL_FOUND TRUE CACHE BOOL - "Found OpenAL and ALUT libraries successfully" - ) - -endif (OPENAL) From 24a25e5dd4633512bfadfa3f8c8687120306c2b9 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 2 Nov 2010 10:25:48 -0700 Subject: [PATCH 130/239] Fixed streaming video on Windows by updating mime_types_window.xml to the version used in Viewer 2 --- .../default/xui/en-us/mime_types_windows.xml | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml index abc7f1a85..61067da06 100644 --- a/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml +++ b/linden/indra/newview/skins/default/xui/en-us/mime_types_windows.xml @@ -120,7 +120,7 @@ none </widgettype> <impl> - media_plugin_quicktime + media_plugin_webkit </impl> </mimetype> <mimetype name="none/none"> @@ -130,6 +130,9 @@ <widgettype> none </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/*"> <label name="audio2_label"> @@ -138,6 +141,9 @@ <widgettype> audio </widgettype> + <impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="video/*"> <label name="video2_label"> @@ -146,6 +152,9 @@ <widgettype> movie </widgettype> + <impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="image/*"> <label name="image2_label"> @@ -154,10 +163,13 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> - Movie (gstreamer) + Movie (QuickTime) </label> <widgettype> movie @@ -173,6 +185,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/ogg"> <label name="application/ogg_label"> @@ -181,6 +196,9 @@ <widgettype> audio </widgettype> + <impl> + media_plugin_quicktime + </impl> </mimetype> <mimetype name="application/pdf"> <label name="application/pdf_label"> @@ -189,6 +207,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/postscript"> <label name="application/postscript_label"> @@ -197,6 +218,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/rtf"> <label name="application/rtf_label"> @@ -205,6 +229,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/smil"> <label name="application/smil_label"> @@ -214,7 +241,7 @@ movie </widgettype> <impl> - media_plugin_quicktime + media_plugin_webkit </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -224,6 +251,9 @@ <widgettype> web </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="application/x-director"> <label name="application/x-director_label"> @@ -232,6 +262,9 @@ <widgettype> image </widgettype> + <impl> + media_plugin_webkit + </impl> </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> @@ -398,9 +431,9 @@ media_plugin_quicktime </impl> </mimetype> - <mimetype menu="1" name="video/gstreamer"> - <label name="video/gstreamer_label"> - Movie (gstreamer) + <mimetype menu="1" name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) </label> <widgettype> movie From 14dc0680a2d0b6bb8695a4021551ed74f57cb23c Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 2 Nov 2010 16:55:27 -0700 Subject: [PATCH 131/239] Uploaded the linux64 libraries created by Aleric to imprudenceviewer.org --- linden/install.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index 4a5c827ab..a6a467012 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -181,7 +181,7 @@ <key>md5sum</key> <string>a2cde4f24bdcc260b661e139846b8acd</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/imprudence-artwork-20101026.tar.bz2</uri> + <uri>http://imprudenceviewer.org/download/libs/imprudence-artwork-20101026.tar.bz2</uri> </map> </map> </map> @@ -308,7 +308,7 @@ <key>md5sum</key> <string>5bbf7e33dadc7d046dcf44883a9ec3d0</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/dbusglib-linux-20101031.tar.bz2</uri> + <uri>http://imprudenceviewer.org/download/libs/dbusglib-linux-20101031.tar.bz2</uri> </map> <key>linux64</key> <map> @@ -797,7 +797,7 @@ cairo: Copyright © 2002 University of Southern California, Copyright © 2005 Re <key>md5sum</key> <string>8b5f413bdefec7cfe3d9ad2d69986bdc</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/jpeglib-6b-linux64-20101012.tar.bz2</uri> + <uri>http://imprudenceviewer.org/download/libs/jpeglib-6b-linux64-20101012.tar.bz2</uri> </map> <key>windows</key> <map> @@ -1052,7 +1052,7 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <key>md5sum</key> <string>863f7b31556b1d368651f85457f4e46d</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/llqtwebkit-linux64-20101012.1.tar.bz2</uri> + <uri>http://imprudenceviewer.org/download/libs/llqtwebkit-linux64-20101012.1.tar.bz2</uri> </map> <key>windows</key> <map> From 3f7f854bd1d75a3d22df931ff4e30fbb8b642a50 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 3 Nov 2010 17:53:55 +0100 Subject: [PATCH 132/239] Rename hippo* files to lower case (PART 1 OF 2) There was a problem with #include "hippolimits.h" because the file is called hippoLimits.h (with an uppercase L). After some discussion on IRC it was reluctantly decided that filenames should be lowercase, as is done for every Linden file. Moreover, hippolimits.h is about the class HippoLimits, with uppercase H, so even that doesn't match. Of course, then we immediately rename all hippo* files to lowercase. This patch ONLY renames the file, with no other changes. This is done in order to make sure that git won't get confused ;). All other necessary changes will be in the next commit. --- .../indra/newview/{hippoGridManager.cpp => hippogridmanager.cpp} | 0 linden/indra/newview/{hippoGridManager.h => hippogridmanager.h} | 0 linden/indra/newview/{hippoLimits.cpp => hippolimits.cpp} | 0 linden/indra/newview/{hippoLimits.h => hippolimits.h} | 0 .../indra/newview/{hippoRestRequest.cpp => hipporestrequest.cpp} | 0 linden/indra/newview/{hippoRestRequest.h => hipporestrequest.h} | 0 linden/indra/newview/{hippoUpdate.cpp => hippoupdate.cpp} | 0 linden/indra/newview/{hippoUpdate.h => hippoupdate.h} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename linden/indra/newview/{hippoGridManager.cpp => hippogridmanager.cpp} (100%) rename linden/indra/newview/{hippoGridManager.h => hippogridmanager.h} (100%) rename linden/indra/newview/{hippoLimits.cpp => hippolimits.cpp} (100%) rename linden/indra/newview/{hippoLimits.h => hippolimits.h} (100%) rename linden/indra/newview/{hippoRestRequest.cpp => hipporestrequest.cpp} (100%) rename linden/indra/newview/{hippoRestRequest.h => hipporestrequest.h} (100%) rename linden/indra/newview/{hippoUpdate.cpp => hippoupdate.cpp} (100%) rename linden/indra/newview/{hippoUpdate.h => hippoupdate.h} (100%) diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippogridmanager.cpp similarity index 100% rename from linden/indra/newview/hippoGridManager.cpp rename to linden/indra/newview/hippogridmanager.cpp diff --git a/linden/indra/newview/hippoGridManager.h b/linden/indra/newview/hippogridmanager.h similarity index 100% rename from linden/indra/newview/hippoGridManager.h rename to linden/indra/newview/hippogridmanager.h diff --git a/linden/indra/newview/hippoLimits.cpp b/linden/indra/newview/hippolimits.cpp similarity index 100% rename from linden/indra/newview/hippoLimits.cpp rename to linden/indra/newview/hippolimits.cpp diff --git a/linden/indra/newview/hippoLimits.h b/linden/indra/newview/hippolimits.h similarity index 100% rename from linden/indra/newview/hippoLimits.h rename to linden/indra/newview/hippolimits.h diff --git a/linden/indra/newview/hippoRestRequest.cpp b/linden/indra/newview/hipporestrequest.cpp similarity index 100% rename from linden/indra/newview/hippoRestRequest.cpp rename to linden/indra/newview/hipporestrequest.cpp diff --git a/linden/indra/newview/hippoRestRequest.h b/linden/indra/newview/hipporestrequest.h similarity index 100% rename from linden/indra/newview/hippoRestRequest.h rename to linden/indra/newview/hipporestrequest.h diff --git a/linden/indra/newview/hippoUpdate.cpp b/linden/indra/newview/hippoupdate.cpp similarity index 100% rename from linden/indra/newview/hippoUpdate.cpp rename to linden/indra/newview/hippoupdate.cpp diff --git a/linden/indra/newview/hippoUpdate.h b/linden/indra/newview/hippoupdate.h similarity index 100% rename from linden/indra/newview/hippoUpdate.h rename to linden/indra/newview/hippoupdate.h From 30cf280a26413ea950cd11f5dc7530633a7e2957 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 3 Nov 2010 17:58:09 +0100 Subject: [PATCH 133/239] Rename hippo* files to lower case (PART 2 OF 2) There was a problem with #include "hippolimits.h" because the file is called hippoLimits.h (with an uppercase L). After some discussion on IRC it was reluctantly decided that filenames should be lowercase, as is done for every Linden file. This is part 2 or 2 (the first part just renamed the files). This part changes all files to make the viewer compile again after the renaming. --- linden/indra/llinventory/lltransactionflags.cpp | 2 +- linden/indra/llui/llnotifications.cpp | 2 +- linden/indra/newview/CMakeLists.txt | 12 ++++++------ linden/indra/newview/chatbar_as_cmdline.cpp | 2 +- linden/indra/newview/floatercommandline.cpp | 2 +- linden/indra/newview/floatergriddefault.cpp | 2 +- linden/indra/newview/floatergridmanager.cpp | 2 +- linden/indra/newview/floaterlocalassetbrowse.cpp | 2 +- linden/indra/newview/hippogridmanager.cpp | 4 ++-- linden/indra/newview/hippolimits.cpp | 4 ++-- linden/indra/newview/hipporestrequest.cpp | 2 +- linden/indra/newview/hippoupdate.cpp | 2 +- linden/indra/newview/kowopenregionsettings.cpp | 2 +- linden/indra/newview/llappviewer.cpp | 6 +++--- linden/indra/newview/llassetuploadresponders.cpp | 2 +- linden/indra/newview/llcurrencyuimanager.cpp | 2 +- linden/indra/newview/llfirstuse.cpp | 2 +- linden/indra/newview/llfloaterabout.cpp | 2 +- linden/indra/newview/llfloateranimpreview.cpp | 2 +- linden/indra/newview/llfloaterbuy.cpp | 2 +- linden/indra/newview/llfloaterbuycontents.cpp | 2 +- linden/indra/newview/llfloaterbuycurrency.cpp | 2 +- linden/indra/newview/llfloaterbuyland.cpp | 2 +- linden/indra/newview/llfloatergodtools.cpp | 2 +- linden/indra/newview/llfloatergroups.cpp | 2 +- linden/indra/newview/llfloaterhtmlhelp.cpp | 2 +- linden/indra/newview/llfloaterimagepreview.cpp | 2 +- linden/indra/newview/llfloaterland.cpp | 2 +- linden/indra/newview/llfloatermap.cpp | 2 +- linden/indra/newview/llfloaternamedesc.cpp | 2 +- linden/indra/newview/llfloaterpostcard.cpp | 2 +- linden/indra/newview/llfloaterproperties.cpp | 2 +- linden/indra/newview/llfloaterregioninfo.cpp | 2 +- linden/indra/newview/llfloatersellland.cpp | 2 +- linden/indra/newview/llfloatersnapshot.cpp | 2 +- linden/indra/newview/llfloatertools.cpp | 2 +- linden/indra/newview/llfloatertos.cpp | 2 +- linden/indra/newview/llfloaterworldmap.cpp | 2 +- linden/indra/newview/llgivemoney.cpp | 2 +- linden/indra/newview/llhoverview.cpp | 2 +- linden/indra/newview/llmanipscale.cpp | 2 +- linden/indra/newview/llmaniptranslate.cpp | 2 +- linden/indra/newview/llnetmap.cpp | 2 +- linden/indra/newview/llnotify.cpp | 2 +- linden/indra/newview/llpanelaudioprefs.cpp | 2 +- linden/indra/newview/llpanelclassified.cpp | 2 +- linden/indra/newview/llpaneldirfind.cpp | 2 +- linden/indra/newview/llpaneldirland.cpp | 2 +- linden/indra/newview/llpanelgroupgeneral.cpp | 2 +- linden/indra/newview/llpanelgrouplandmoney.cpp | 2 +- linden/indra/newview/llpanelinventory.cpp | 2 +- linden/indra/newview/llpanelland.cpp | 2 +- linden/indra/newview/llpanellandmedia.cpp | 2 +- linden/indra/newview/llpanellogin.cpp | 4 ++-- linden/indra/newview/llpanelmsgs.cpp | 2 +- linden/indra/newview/llpanelobject.cpp | 2 +- linden/indra/newview/llpanelpermissions.cpp | 2 +- linden/indra/newview/llpanelplace.cpp | 2 +- linden/indra/newview/llpanelweb.cpp | 2 +- linden/indra/newview/llprefsim.cpp | 2 +- linden/indra/newview/llstartup.cpp | 4 ++-- linden/indra/newview/llstatusbar.cpp | 2 +- linden/indra/newview/lltexturefetch.cpp | 2 +- linden/indra/newview/lltooldraganddrop.cpp | 2 +- linden/indra/newview/lltoolgrab.cpp | 2 +- linden/indra/newview/llviewerdisplay.cpp | 2 +- linden/indra/newview/llviewermenu.cpp | 4 ++-- linden/indra/newview/llviewermessage.cpp | 4 ++-- linden/indra/newview/llviewernetwork.cpp | 2 +- linden/indra/newview/llviewerparcelmgr.cpp | 2 +- linden/indra/newview/llvoavatar.cpp | 2 +- linden/indra/newview/llworld.cpp | 2 +- linden/indra/newview/llworldmap.cpp | 2 +- linden/indra/newview/llxmlrpctransaction.cpp | 2 +- linden/indra/newview/primbackup.cpp | 2 +- linden/indra/newview/windlightsettingsupdate.cpp | 2 +- linden/indra/newview/wlfloatermanager.cpp | 2 +- linden/indra/newview/wlfloaterwindlightsend.cpp | 2 +- linden/indra/newview/wlretrievesettings.cpp | 2 +- linden/indra/newview/wlsettingsmanager.cpp | 2 +- 80 files changed, 93 insertions(+), 93 deletions(-) diff --git a/linden/indra/llinventory/lltransactionflags.cpp b/linden/indra/llinventory/lltransactionflags.cpp index aaea16158..fda8cad90 100644 --- a/linden/indra/llinventory/lltransactionflags.cpp +++ b/linden/indra/llinventory/lltransactionflags.cpp @@ -37,7 +37,7 @@ #include "lltransactionflags.h" #include "lltransactiontypes.h" -#include "../newview/hippoGridManager.h" +#include "../newview/hippogridmanager.h" const U8 TRANSACTION_FLAGS_NONE = 0; const U8 TRANSACTION_FLAG_SOURCE_GROUP = 1; diff --git a/linden/indra/llui/llnotifications.cpp b/linden/indra/llui/llnotifications.cpp index 4d3ff462d..77f2ff778 100644 --- a/linden/indra/llui/llnotifications.cpp +++ b/linden/indra/llui/llnotifications.cpp @@ -40,7 +40,7 @@ #include <algorithm> #include <boost/regex.hpp> -#include "../newview/hippoGridManager.h" +#include "../newview/hippogridmanager.h" const std::string NOTIFICATION_PERSIST_VERSION = "0.93"; diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 58c89eb5f..e3a1745af 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -82,9 +82,9 @@ set(viewer_SOURCE_FILES floaterlocalassetbrowse.cpp floatervoicelicense.cpp hbfloatergrouptitles.cpp - hippoGridManager.cpp - hippoLimits.cpp - hippoRestRequest.cpp + hippogridmanager.cpp + hippolimits.cpp + hipporestrequest.cpp impprefsfonts.cpp jcfloater_animation_list.cpp jcfloaterareasearch.cpp @@ -534,9 +534,9 @@ set(viewer_HEADER_FILES floaterlocalassetbrowse.h floatervoicelicense.h hbfloatergrouptitles.h - hippoGridManager.h - hippoLimits.h - hippoRestRequest.h + hippogridmanager.h + hippolimits.h + hipporestrequest.h impprefsfonts.h jcfloater_animation_list.h jcfloaterareasearch.h diff --git a/linden/indra/newview/chatbar_as_cmdline.cpp b/linden/indra/newview/chatbar_as_cmdline.cpp index 96787ada6..059309134 100644 --- a/linden/indra/newview/chatbar_as_cmdline.cpp +++ b/linden/indra/newview/chatbar_as_cmdline.cpp @@ -43,7 +43,7 @@ #include "lluuid.h" #include "llviewercontrol.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "material_codes.h" #include "llvolume.h" #include "object_flags.h" diff --git a/linden/indra/newview/floatercommandline.cpp b/linden/indra/newview/floatercommandline.cpp index c093a5828..6889696ca 100644 --- a/linden/indra/newview/floatercommandline.cpp +++ b/linden/indra/newview/floatercommandline.cpp @@ -32,7 +32,7 @@ #include "floatercommandline.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" diff --git a/linden/indra/newview/floatergriddefault.cpp b/linden/indra/newview/floatergriddefault.cpp index 2c31fb66e..6a2526dbb 100644 --- a/linden/indra/newview/floatergriddefault.cpp +++ b/linden/indra/newview/floatergriddefault.cpp @@ -32,7 +32,7 @@ #include "floatergriddefault.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llpanellogin.h" #include "llscrolllistctrl.h" #include "lluictrlfactory.h" diff --git a/linden/indra/newview/floatergridmanager.cpp b/linden/indra/newview/floatergridmanager.cpp index 3d4b17ff4..298fe3505 100644 --- a/linden/indra/newview/floatergridmanager.cpp +++ b/linden/indra/newview/floatergridmanager.cpp @@ -17,7 +17,7 @@ #include "llmd5.h" #include "llurlsimstring.h" #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewernetwork.h" #include "llpanellogin.h" diff --git a/linden/indra/newview/floaterlocalassetbrowse.cpp b/linden/indra/newview/floaterlocalassetbrowse.cpp index 991d2fd60..8ea13ccc3 100644 --- a/linden/indra/newview/floaterlocalassetbrowse.cpp +++ b/linden/indra/newview/floaterlocalassetbrowse.cpp @@ -53,7 +53,7 @@ this feature is still a work in progress. /* misc headers */ #include <time.h> #include <ctime> -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewerimagelist.h" #include "llviewerobjectlist.h" #include "llfilepicker.h" diff --git a/linden/indra/newview/hippogridmanager.cpp b/linden/indra/newview/hippogridmanager.cpp index dd0fa3518..d56214cc0 100644 --- a/linden/indra/newview/hippogridmanager.cpp +++ b/linden/indra/newview/hippogridmanager.cpp @@ -2,7 +2,7 @@ #include "llviewerprecompiledheaders.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include <cctype> @@ -17,7 +17,7 @@ #include "llviewercontrol.h" #include "llweb.h" -#include "hippoRestRequest.h" +#include "hipporestrequest.h" // ******************************************************************** diff --git a/linden/indra/newview/hippolimits.cpp b/linden/indra/newview/hippolimits.cpp index a5d6ee6ad..851e191ee 100644 --- a/linden/indra/newview/hippolimits.cpp +++ b/linden/indra/newview/hippolimits.cpp @@ -2,9 +2,9 @@ #include "llviewerprecompiledheaders.h" -#include "hippoLimits.h" +#include "hippolimits.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewercontrol.h" #include <llerror.h> diff --git a/linden/indra/newview/hipporestrequest.cpp b/linden/indra/newview/hipporestrequest.cpp index ed159074d..9d24aed4b 100644 --- a/linden/indra/newview/hipporestrequest.cpp +++ b/linden/indra/newview/hipporestrequest.cpp @@ -2,7 +2,7 @@ #include "llviewerprecompiledheaders.h" -#include "hippoRestRequest.h" +#include "hipporestrequest.h" #ifndef CURL_STATICLIB #define CURL_STATICLIB 1 diff --git a/linden/indra/newview/hippoupdate.cpp b/linden/indra/newview/hippoupdate.cpp index f6947ade4..192e3d74a 100644 --- a/linden/indra/newview/hippoupdate.cpp +++ b/linden/indra/newview/hippoupdate.cpp @@ -1,5 +1,5 @@ -#include "hippoUpdate.h" +#include "hippoupdate.h" #include <cstdio> #include <list> diff --git a/linden/indra/newview/kowopenregionsettings.cpp b/linden/indra/newview/kowopenregionsettings.cpp index 86a426c03..8aac87cac 100644 --- a/linden/indra/newview/kowopenregionsettings.cpp +++ b/linden/indra/newview/kowopenregionsettings.cpp @@ -27,7 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llhttpnode.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "llfloatertools.h" #include "llviewercontrol.h" #include "llagent.h" diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 3d8be5f91..38985d30c 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -176,9 +176,9 @@ #include "llcommandlineparser.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" -#include "hippoUpdate.h" +#include "hippogridmanager.h" +#include "hippolimits.h" +#include "hippoupdate.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llassetuploadresponders.cpp b/linden/indra/newview/llassetuploadresponders.cpp index b9ec9a026..d4a75f72c 100644 --- a/linden/indra/newview/llassetuploadresponders.cpp +++ b/linden/indra/newview/llassetuploadresponders.cpp @@ -63,7 +63,7 @@ #include "llscrolllistctrl.h" #include "llsdserialize.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // When uploading multiple files, don't display any of them when uploading more than this number. static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; diff --git a/linden/indra/newview/llcurrencyuimanager.cpp b/linden/indra/newview/llcurrencyuimanager.cpp index 99d043053..07b1287e8 100644 --- a/linden/indra/newview/llcurrencyuimanager.cpp +++ b/linden/indra/newview/llcurrencyuimanager.cpp @@ -47,7 +47,7 @@ #include "llxmlrpctransaction.h" #include "llviewernetwork.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0; // how long of a pause in typing a currency buy amount before an diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp index 0b777ea45..18efa9ea8 100644 --- a/linden/indra/newview/llfirstuse.cpp +++ b/linden/indra/newview/llfirstuse.cpp @@ -47,7 +47,7 @@ #include "floatergriddefault.h" #include "floatervoicelicense.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llstartup.h" #include "llvoavatar.h" diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 4be83b6cd..5c037d67a 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp @@ -44,7 +44,7 @@ #include "llimagej2c.h" #include "llaudioengine.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewertexteditor.h" #include "llviewercontrol.h" #include "llagent.h" diff --git a/linden/indra/newview/llfloateranimpreview.cpp b/linden/indra/newview/llfloateranimpreview.cpp index 09d3b2cbf..232530c2b 100644 --- a/linden/indra/newview/llfloateranimpreview.cpp +++ b/linden/indra/newview/llfloateranimpreview.cpp @@ -68,7 +68,7 @@ #include "pipeline.h" #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" S32 LLFloaterAnimPreview::sUploadAmount = 10; diff --git a/linden/indra/newview/llfloaterbuy.cpp b/linden/indra/newview/llfloaterbuy.cpp index 86cab43f6..99c9fed5d 100644 --- a/linden/indra/newview/llfloaterbuy.cpp +++ b/linden/indra/newview/llfloaterbuy.cpp @@ -50,7 +50,7 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" LLFloaterBuy* LLFloaterBuy::sInstance = NULL; diff --git a/linden/indra/newview/llfloaterbuycontents.cpp b/linden/indra/newview/llfloaterbuycontents.cpp index 498d6acc4..e16f98dff 100644 --- a/linden/indra/newview/llfloaterbuycontents.cpp +++ b/linden/indra/newview/llfloaterbuycontents.cpp @@ -54,7 +54,7 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL; diff --git a/linden/indra/newview/llfloaterbuycurrency.cpp b/linden/indra/newview/llfloaterbuycurrency.cpp index 509649593..6a0dd6886 100644 --- a/linden/indra/newview/llfloaterbuycurrency.cpp +++ b/linden/indra/newview/llfloaterbuycurrency.cpp @@ -46,7 +46,7 @@ #include "llwindow.h" #include "llappviewer.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" static const S32 STANDARD_BUY_AMOUNT = 2000; static const S32 MINIMUM_BALANCE_AMOUNT = 0; diff --git a/linden/indra/newview/llfloaterbuyland.cpp b/linden/indra/newview/llfloaterbuyland.cpp index 75630b210..8288c581c 100644 --- a/linden/indra/newview/llfloaterbuyland.cpp +++ b/linden/indra/newview/llfloaterbuyland.cpp @@ -66,7 +66,7 @@ #include "llviewernetwork.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // NOTE: This is duplicated in lldatamoney.cpp ... const F32 GROUP_LAND_BONUS_FACTOR = 1.1f; diff --git a/linden/indra/newview/llfloatergodtools.cpp b/linden/indra/newview/llfloatergodtools.cpp index 461dfe258..f918e8a46 100644 --- a/linden/indra/newview/llfloatergodtools.cpp +++ b/linden/indra/newview/llfloatergodtools.cpp @@ -77,7 +77,7 @@ #include "lltransfertargetfile.h" #include "lltransfersourcefile.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const F32 SECONDS_BETWEEN_UPDATE_REQUESTS = 5.0f; diff --git a/linden/indra/newview/llfloatergroups.cpp b/linden/indra/newview/llfloatergroups.cpp index 79e9e3136..f7359236c 100644 --- a/linden/indra/newview/llfloatergroups.cpp +++ b/linden/indra/newview/llfloatergroups.cpp @@ -59,7 +59,7 @@ #include "llviewerwindow.h" #include "llimview.h" -#include "hippoLimits.h" +#include "hippolimits.h" // static std::map<const LLUUID, LLFloaterGroupPicker*> LLFloaterGroupPicker::sInstances; diff --git a/linden/indra/newview/llfloaterhtmlhelp.cpp b/linden/indra/newview/llfloaterhtmlhelp.cpp index 1ec964b36..c89c2e283 100644 --- a/linden/indra/newview/llfloaterhtmlhelp.cpp +++ b/linden/indra/newview/llfloaterhtmlhelp.cpp @@ -54,7 +54,7 @@ #include "llviewerparcelmedia.h" #include "llcombobox.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) { diff --git a/linden/indra/newview/llfloaterimagepreview.cpp b/linden/indra/newview/llfloaterimagepreview.cpp index 8142869af..aa8a94faf 100644 --- a/linden/indra/newview/llfloaterimagepreview.cpp +++ b/linden/indra/newview/llfloaterimagepreview.cpp @@ -60,7 +60,7 @@ #include "llstring.h" #include "llviewercontrol.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #ifdef LL_DARWIN #include "llwindowmacosx-objc.h" diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp index 42bc41c3e..cc3e38563 100644 --- a/linden/indra/newview/llfloaterland.cpp +++ b/linden/indra/newview/llfloaterland.cpp @@ -77,7 +77,7 @@ #include "llviewercontrol.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp index 34b8dde3b..e63ea4b94 100644 --- a/linden/indra/newview/llfloatermap.cpp +++ b/linden/indra/newview/llfloatermap.cpp @@ -44,7 +44,7 @@ #include "lluictrlfactory.h" #include "llfirstuse.h" #include "panelradar.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] diff --git a/linden/indra/newview/llfloaternamedesc.cpp b/linden/indra/newview/llfloaternamedesc.cpp index 941361189..9e8e94b8a 100644 --- a/linden/indra/newview/llfloaternamedesc.cpp +++ b/linden/indra/newview/llfloaternamedesc.cpp @@ -55,7 +55,7 @@ #include "llassetstorage.h" #include "llinventorytype.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const S32 PREVIEW_LINE_HEIGHT = 19; const S32 PREVIEW_CLOSE_BOX_SIZE = 16; diff --git a/linden/indra/newview/llfloaterpostcard.cpp b/linden/indra/newview/llfloaterpostcard.cpp index aa9b2fbae..8cd552ef5 100644 --- a/linden/indra/newview/llfloaterpostcard.cpp +++ b/linden/indra/newview/llfloaterpostcard.cpp @@ -66,7 +66,7 @@ #include <boost/regex.hpp> //boost.regex lib -#include "hippoGridManager.h" +#include "hippogridmanager.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llfloaterproperties.cpp b/linden/indra/newview/llfloaterproperties.cpp index 40b293ae1..96e164265 100644 --- a/linden/indra/newview/llfloaterproperties.cpp +++ b/linden/indra/newview/llfloaterproperties.cpp @@ -59,7 +59,7 @@ #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index 9e6f32347..8ae3fa2a5 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -80,7 +80,7 @@ #include "llviewertexteditor.h" #include "llviewerwindow.h" #include "llvlcomposition.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llfloatersellland.cpp b/linden/indra/newview/llfloatersellland.cpp index bf4a4c3c9..9b257089f 100644 --- a/linden/indra/newview/llfloatersellland.cpp +++ b/linden/indra/newview/llfloatersellland.cpp @@ -46,7 +46,7 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // defined in llfloaterland.cpp void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp index a58120dc7..e007680fa 100644 --- a/linden/indra/newview/llfloatersnapshot.cpp +++ b/linden/indra/newview/llfloatersnapshot.cpp @@ -77,7 +77,7 @@ #include "llvfile.h" #include "llvfs.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 2f02f1ef3..683ebd4ba 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -85,7 +85,7 @@ #include "llvotree.h" #include "lluictrlfactory.h" #include "qtoolalign.h" -#include "hippoLimits.h" +#include "hippolimits.h" // Globals LLFloaterTools *gFloaterTools = NULL; diff --git a/linden/indra/newview/llfloatertos.cpp b/linden/indra/newview/llfloatertos.cpp index f3a124ab7..ac4a06b17 100644 --- a/linden/indra/newview/llfloatertos.cpp +++ b/linden/indra/newview/llfloatertos.cpp @@ -52,7 +52,7 @@ #include "lluictrlfactory.h" #include "llvfile.h" #include "message.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // static diff --git a/linden/indra/newview/llfloaterworldmap.cpp b/linden/indra/newview/llfloaterworldmap.cpp index 0a01ca70a..47f336196 100644 --- a/linden/indra/newview/llfloaterworldmap.cpp +++ b/linden/indra/newview/llfloaterworldmap.cpp @@ -70,7 +70,7 @@ #include "llglheaders.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llgivemoney.cpp b/linden/indra/newview/llgivemoney.cpp index 6c6933424..ee2bf6342 100644 --- a/linden/indra/newview/llgivemoney.cpp +++ b/linden/indra/newview/llgivemoney.cpp @@ -52,7 +52,7 @@ #include "lltransactiontypes.h" #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp index c7136bcd2..10d27cdd2 100644 --- a/linden/indra/newview/llhoverview.cpp +++ b/linden/indra/newview/llhoverview.cpp @@ -73,7 +73,7 @@ #include "llhudmanager.h" // For testing effects #include "llhudeffect.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llmanipscale.cpp b/linden/indra/newview/llmanipscale.cpp index fa7e85f95..268e4310e 100644 --- a/linden/indra/newview/llmanipscale.cpp +++ b/linden/indra/newview/llmanipscale.cpp @@ -63,7 +63,7 @@ #include "v2math.h" #include "llvoavatar.h" -#include "hippoLimits.h" +#include "hippolimits.h" const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f; diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp index cc14b277d..8484c4ec1 100644 --- a/linden/indra/newview/llmaniptranslate.cpp +++ b/linden/indra/newview/llmaniptranslate.cpp @@ -66,7 +66,7 @@ #include "llui.h" #include "pipeline.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp index dc4456aa5..b9dc482ba 100644 --- a/linden/indra/newview/llnetmap.cpp +++ b/linden/indra/newview/llnetmap.cpp @@ -71,7 +71,7 @@ #include "llglheaders.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp index b0f5f9149..891707b90 100644 --- a/linden/indra/newview/llnotify.cpp +++ b/linden/indra/newview/llnotify.cpp @@ -55,7 +55,7 @@ #include "lloverlaybar.h" // for gOverlayBar #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] - Version: 1.23.4 #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelaudioprefs.cpp b/linden/indra/newview/llpanelaudioprefs.cpp index d4c8e9fc0..1acfcbb44 100644 --- a/linden/indra/newview/llpanelaudioprefs.cpp +++ b/linden/indra/newview/llpanelaudioprefs.cpp @@ -62,7 +62,7 @@ #include "llviewerwindow.h" #include "llviewercontrol.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // // Static functions diff --git a/linden/indra/newview/llpanelclassified.cpp b/linden/indra/newview/llpanelclassified.cpp index d3230c80b..99b6cf661 100644 --- a/linden/indra/newview/llpanelclassified.cpp +++ b/linden/indra/newview/llpanelclassified.cpp @@ -70,7 +70,7 @@ #include "llviewerwindow.h" // for window width, height #include "llappviewer.h" // abortQuit() -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpaneldirfind.cpp b/linden/indra/newview/llpaneldirfind.cpp index 14c4a909c..342ffec61 100644 --- a/linden/indra/newview/llpaneldirfind.cpp +++ b/linden/indra/newview/llpaneldirfind.cpp @@ -73,7 +73,7 @@ #include "boost/lexical_cast.hpp" #endif -#include "hippoGridManager.h" +#include "hippogridmanager.h" //--------------------------------------------------------------------------- // LLPanelDirFindAll - Google search appliance based search diff --git a/linden/indra/newview/llpaneldirland.cpp b/linden/indra/newview/llpaneldirland.cpp index c7029314f..3fdf37e7d 100644 --- a/linden/indra/newview/llpaneldirland.cpp +++ b/linden/indra/newview/llpaneldirland.cpp @@ -52,7 +52,7 @@ #include "llviewercontrol.h" #include "llviewermessage.h" #include "llnotify.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //----------------------------------------------------------------------------- // Constants diff --git a/linden/indra/newview/llpanelgroupgeneral.cpp b/linden/indra/newview/llpanelgroupgeneral.cpp index e0d637671..6878f84b3 100644 --- a/linden/indra/newview/llpanelgroupgeneral.cpp +++ b/linden/indra/newview/llpanelgroupgeneral.cpp @@ -34,7 +34,7 @@ #include "llpanelgroupgeneral.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "lluictrlfactory.h" #include "llagent.h" diff --git a/linden/indra/newview/llpanelgrouplandmoney.cpp b/linden/indra/newview/llpanelgrouplandmoney.cpp index bded59c30..3f128fe28 100644 --- a/linden/indra/newview/llpanelgrouplandmoney.cpp +++ b/linden/indra/newview/llpanelgrouplandmoney.cpp @@ -55,7 +55,7 @@ #include "llfloaterworldmap.h" #include "llviewermessage.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //////////////////////////////////////////////////////////////////////////// diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index 41ba5130e..9cd2759c5 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp @@ -82,7 +82,7 @@ #include "llviewerwindow.h" #include "llwearable.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelland.cpp b/linden/indra/newview/llpanelland.cpp index ea6a55795..d1eee80b3 100644 --- a/linden/indra/newview/llpanelland.cpp +++ b/linden/indra/newview/llpanelland.cpp @@ -49,7 +49,7 @@ #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanellandmedia.cpp b/linden/indra/newview/llpanellandmedia.cpp index 11f491c3d..b7df164ca 100644 --- a/linden/indra/newview/llpanellandmedia.cpp +++ b/linden/indra/newview/llpanellandmedia.cpp @@ -55,7 +55,7 @@ #include "lltexturectrl.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //--------------------------------------------------------------------------- // LLPanelLandMedia diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp index 2a8c20f8c..6464f0bb8 100644 --- a/linden/indra/newview/llpanellogin.cpp +++ b/linden/indra/newview/llpanellogin.cpp @@ -36,8 +36,8 @@ #include "llpanelgeneral.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "floatergridmanager.h" #include "indra_constants.h" // for key and mask constants diff --git a/linden/indra/newview/llpanelmsgs.cpp b/linden/indra/newview/llpanelmsgs.cpp index 3ea7aa573..9e04070e4 100644 --- a/linden/indra/newview/llpanelmsgs.cpp +++ b/linden/indra/newview/llpanelmsgs.cpp @@ -40,7 +40,7 @@ #include "lluictrlfactory.h" #include "llfirstuse.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //----------------------------------------------------------------------------- LLPanelMsgs::LLPanelMsgs() : diff --git a/linden/indra/newview/llpanelobject.cpp b/linden/indra/newview/llpanelobject.cpp index 706f98e7f..cc89e24ff 100644 --- a/linden/indra/newview/llpanelobject.cpp +++ b/linden/indra/newview/llpanelobject.cpp @@ -76,7 +76,7 @@ #include "lldrawpool.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp index 5131d2c15..6b7bc1bad 100644 --- a/linden/indra/newview/llpanelpermissions.cpp +++ b/linden/indra/newview/llpanelpermissions.cpp @@ -68,7 +68,7 @@ #include "lluictrlfactory.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelplace.cpp b/linden/indra/newview/llpanelplace.cpp index eb3d17da0..fe88c137e 100644 --- a/linden/indra/newview/llpanelplace.cpp +++ b/linden/indra/newview/llpanelplace.cpp @@ -58,7 +58,7 @@ #include "llweb.h" #include "llsdutil.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //static std::list<LLPanelPlace*> LLPanelPlace::sAllPanels; diff --git a/linden/indra/newview/llpanelweb.cpp b/linden/indra/newview/llpanelweb.cpp index 14df239e9..6f9bd7a5a 100644 --- a/linden/indra/newview/llpanelweb.cpp +++ b/linden/indra/newview/llpanelweb.cpp @@ -37,7 +37,7 @@ // project includes #include "llcheckboxctrl.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" #include "llviewermedia.h" diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp index e915bd2fd..9e86cd348 100644 --- a/linden/indra/newview/llprefsim.cpp +++ b/linden/indra/newview/llprefsim.cpp @@ -49,7 +49,7 @@ #include "lldirpicker.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 49446c714..b744961e4 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -210,8 +210,8 @@ #include "floaterao.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "lggautocorrect.h" // diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp index 457910083..3370f7fbd 100644 --- a/linden/indra/newview/llstatusbar.cpp +++ b/linden/indra/newview/llstatusbar.cpp @@ -83,7 +83,7 @@ #include "llstring.h" #include "message.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "viewertime.h" // diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index f63deb89d..f93a5748f 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -2275,7 +2275,7 @@ void LLTextureFetch::dump() // // *TODO: This is a *HACK and may not work if the grid is heterogenous. // Remove it once OpenSim versions in the wild are > 0.7.0.2! -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include <boost/regex.hpp> //static bool LLTextureFetch::hasBuggyHTTPRange() diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index 4e133de47..18c49178d 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp @@ -75,7 +75,7 @@ // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] -#include "hippoLimits.h" +#include "hippolimits.h" // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a diff --git a/linden/indra/newview/lltoolgrab.cpp b/linden/indra/newview/lltoolgrab.cpp index 9b6d6f76b..10b043113 100644 --- a/linden/indra/newview/lltoolgrab.cpp +++ b/linden/indra/newview/lltoolgrab.cpp @@ -64,7 +64,7 @@ #include "llvoavatar.h" #include "llworld.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index 416746477..59a87d5f3 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -82,7 +82,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index ace0bcbc7..a663e60d9 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -228,8 +228,8 @@ #include "jcfloater_animation_list.h" #include "llfloaterassetbrowser.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "llfloaterteleporthistory.h" diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index 743e0d9ba..5f333e9a4 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -150,8 +150,8 @@ #include <boost/tokenizer.hpp> #include <boost/regex.hpp> // Boost Reg Expresions -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "wlsettingsmanager.h" #if LL_WINDOWS // For Windows specific error handler diff --git a/linden/indra/newview/llviewernetwork.cpp b/linden/indra/newview/llviewernetwork.cpp index c1d5013c8..1cfe6654b 100644 --- a/linden/indra/newview/llviewernetwork.cpp +++ b/linden/indra/newview/llviewernetwork.cpp @@ -37,7 +37,7 @@ #include "llviewercontrol.h" #include "llstartup.h" - #include "hippoGridManager.h" + #include "hippogridmanager.h" unsigned char gMACAddress[MAC_ADDRESS_BYTES]; /* Flawfinder: ignore */ diff --git a/linden/indra/newview/llviewerparcelmgr.cpp b/linden/indra/newview/llviewerparcelmgr.cpp index 53260492d..b589f2e24 100644 --- a/linden/indra/newview/llviewerparcelmgr.cpp +++ b/linden/indra/newview/llviewerparcelmgr.cpp @@ -70,7 +70,7 @@ #include "roles_constants.h" #include "llweb.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const F32 PARCEL_COLLISION_DRAW_SECS = 1.f; diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index c4a4dee44..54aed5406 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -94,7 +94,7 @@ #else #include "boost/lexical_cast.hpp" #endif -#include "hippoLimits.h"// getMaxPrimScale +#include "hippolimits.h"// getMaxPrimScale #include "llstartup.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp index c484462ab..7866bf8f7 100644 --- a/linden/indra/newview/llworld.cpp +++ b/linden/indra/newview/llworld.cpp @@ -60,7 +60,7 @@ #include "pipeline.h" #include "llappviewer.h" // for do_disconnect() -#include "hippoLimits.h" +#include "hippolimits.h" #include <deque> #include <queue> diff --git a/linden/indra/newview/llworldmap.cpp b/linden/indra/newview/llworldmap.cpp index 43d742615..3ada36f26 100644 --- a/linden/indra/newview/llworldmap.cpp +++ b/linden/indra/newview/llworldmap.cpp @@ -47,7 +47,7 @@ #include "llviewerimagelist.h" #include "llviewerregion.h" #include "llregionflags.h" - #include "hippoGridManager.h" + #include "hippogridmanager.h" bool LLWorldMap::sGotMapURL = false; const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // 10 minutes diff --git a/linden/indra/newview/llxmlrpctransaction.cpp b/linden/indra/newview/llxmlrpctransaction.cpp index b993c9954..058946eb2 100644 --- a/linden/indra/newview/llxmlrpctransaction.cpp +++ b/linden/indra/newview/llxmlrpctransaction.cpp @@ -35,7 +35,7 @@ #include "llxmlrpctransaction.h" #include "llcurl.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewercontrol.h" // Have to include these last to avoid queue redefinition! diff --git a/linden/indra/newview/primbackup.cpp b/linden/indra/newview/primbackup.cpp index 63043f068..7f050a01c 100644 --- a/linden/indra/newview/primbackup.cpp +++ b/linden/indra/newview/primbackup.cpp @@ -54,7 +54,7 @@ #include "llappviewer.h" #include "lltransactiontypes.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "primbackup.h" diff --git a/linden/indra/newview/windlightsettingsupdate.cpp b/linden/indra/newview/windlightsettingsupdate.cpp index a5f9cb7ba..ad6e7c968 100644 --- a/linden/indra/newview/windlightsettingsupdate.cpp +++ b/linden/indra/newview/windlightsettingsupdate.cpp @@ -27,7 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llhttpnode.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "llfloatertools.h" #include "llviewercontrol.h" #include "llagent.h" diff --git a/linden/indra/newview/wlfloatermanager.cpp b/linden/indra/newview/wlfloatermanager.cpp index 19468078e..63abe14ac 100644 --- a/linden/indra/newview/wlfloatermanager.cpp +++ b/linden/indra/newview/wlfloatermanager.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloatermanager.h" #include "llviewerregion.h" #include "llviewerparcelmgr.h" diff --git a/linden/indra/newview/wlfloaterwindlightsend.cpp b/linden/indra/newview/wlfloaterwindlightsend.cpp index 5244bcd4f..e6148edd1 100644 --- a/linden/indra/newview/wlfloaterwindlightsend.cpp +++ b/linden/indra/newview/wlfloaterwindlightsend.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloaterwindlightsend.h" #include "llviewerregion.h" diff --git a/linden/indra/newview/wlretrievesettings.cpp b/linden/indra/newview/wlretrievesettings.cpp index ca91ba2ae..afa84f25a 100644 --- a/linden/indra/newview/wlretrievesettings.cpp +++ b/linden/indra/newview/wlretrievesettings.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloaterwindlightsend.h" #include "llviewerregion.h" #include "wlsettingsmanager.h" diff --git a/linden/indra/newview/wlsettingsmanager.cpp b/linden/indra/newview/wlsettingsmanager.cpp index 853d14f9a..c0a07e1fb 100644 --- a/linden/indra/newview/wlsettingsmanager.cpp +++ b/linden/indra/newview/wlsettingsmanager.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloaterwindlightsend.h" #include "llviewerregion.h" #include "wlsettingsmanager.h" From e868c08a10b32aaced171182de10dae077238af5 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 3 Nov 2010 21:32:14 +0100 Subject: [PATCH 134/239] Center the "loading..." text on the login page. The loading.html page is no longer used. Instead embedded html found in panel_login.xml is used. I couldn't get it to show an image, but at least the "loading..." text is now centralized and I changed the background color from black to imprudence-purple. --- .../default/html/en-us/loading/loading.html | 9 ------ .../skins/default/xui/en-us/panel_login.xml | 28 ++++++++++++++----- 2 files changed, 21 insertions(+), 16 deletions(-) delete mode 100644 linden/indra/newview/skins/default/html/en-us/loading/loading.html diff --git a/linden/indra/newview/skins/default/html/en-us/loading/loading.html b/linden/indra/newview/skins/default/html/en-us/loading/loading.html deleted file mode 100644 index 97174b017..000000000 --- a/linden/indra/newview/skins/default/html/en-us/loading/loading.html +++ /dev/null @@ -1,9 +0,0 @@ -<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;"> -<table width="100%" height="100%" border="0"> - <tr> - <td align="center" valign="middle" style="font-size:0.8em;"> - <img src="imprudence_loading.png" align="absmiddle"><br/>   loading... - </td> - </tr> -</table> -</body> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml index 96f3f7718..048005d91 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml @@ -1,13 +1,27 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="panel_login" - bottom="0" left="0" height="600" width="800" - follows="left|top|right|bottom" mouse_opaque="true" > - - <web_browser name="login_html" - bottom="0" top="-1" left="0" right="-1" - border_visible="false" follows="top|left|bottom|right" - start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody bgcolor=%22#000000%22 text=%22ffffff%22%3E%3Ch1%3E%3Ctt%3Eloading...%3C/tt%3E%3C/h1%3E %3C/body%3E %3C/html%3E" /> + bottom="0" left="0" height="600" width="800" + follows="left|top|right|bottom" mouse_opaque="true" > + + <web_browser name="login_html" + bottom="0" top="-1" left="0" right="-1" + border_visible="false" follows="top|left|bottom|right" + start_url="data:text/html, + %3Chtml%3E + %3Chead%3E %3C/head%3E + %3Cbody bgcolor=%22#5a2d65%22 text=%22ffffff%22%3E + %3Ctable width=%22100%%22 height=%22100%%22 border=%220%22%3E + %3Ctr%3E + %3Ctd align=%22center%22 valign=%22middle%22 style=%22font-size:0.8em;%22%3E + %3Cimg src=%22imprudence_loading.png%22 align=%22absmiddle%22%3E + %3Cbr/%3E + %3CH1%3Eloading...%3C/H1%3E + %3C/td%3E + %3C/tr%3C + %3C/table%3E + %3C/body%3E + %3C/html%3E" /> <string name="real_url"> http://secondlife.com/app/login/ </string> From b22f87ec754ce300bec038fd24277d7fb65f9f93 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 5 Nov 2010 14:33:52 +0100 Subject: [PATCH 135/239] IMP-592: Extend login screen menu bar till the top of the window. Basically, this Linden code is just horribly broken. I spend already too much time on this (two days) for dead code, so I settled for a minimal fix for this particular case that works, instead of fixing their code properly. The problem is that without specifying "bottom" the code adds 4 pixels (VPAD) between whatever widget that is added and it's parents top (in LLView::createRect). In order to be sure that bottom is exactly minus the height, I had to specify the height too; hopefully this value is the same for everyone cause theorectically it depends on the font size (4 + fontheight + 4). The default height of the Linden code is only 4 + fontheight (they leave off the VPAD). --- linden/doc/contributions.txt | 1 + linden/indra/newview/skins/default/xui/en-us/menu_login.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index f51891160..a54424ca7 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -80,6 +80,7 @@ Aleric Inglewood IMP-578 IMP-579 IMP-581 + IMP-592 IMP-595 IMP-660 IMP-661 diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_login.xml b/linden/indra/newview/skins/default/xui/en-us/menu_login.xml index d9a9c4cde..18fb8e632 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_login.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_login.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu_bar name="Login Menu" opaque="true" tear_off="false"> +<menu_bar name="Login Menu" opaque="true" tear_off="false" height="18" bottom="-18"> <menu create_jump_keys="true" label="File" name="File" opaque="true" tear_off="false"> <menu_item_call label="Quit" name="Quit" shortcut="control|Q"> <on_click function="File.Quit" userdata="" /> From e8e2de0cf70dd56e8a6c41bf5a83bb71bf6d27e5 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 5 Nov 2010 21:04:35 +0100 Subject: [PATCH 136/239] Update of gtk-etc prebuilt for linux 32bit. libpangocairo-1.0.so* was missing. I did a complete new rebuild of the package with, as usual, debian Lenny (stable) package. This tar ball contains the following debian packages: libatk1.0-0_1.22.0-1_i386.deb libatk1.0-dev_1.22.0-1_i386.deb libcairo2_1.6.4-7_i386.deb libcairo2-dev_1.6.4-7_i386.deb libpango1.0-common_1.20.5-6_all.deb libpango1.0-0_1.20.5-6_i386.deb libpango1.0-dev_1.20.5-6_i386.deb libgtk2.0-0_2.12.12-1~lenny2_i386.deb libgtk2.0-dev_2.12.12-1~lenny2_i386.deb libpixman-1-0_0.10.0-2_i386.deb libpixman-1-dev_0.10.0-2_i386.deb But only the 'copyright' file from doc/*, only the include/* files and only the lib*.so files. Most notably, not pkgconfig, resources, configuration files and modules... (those are absent in the previous prebuilts too). --- linden/install.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index a6a467012..d9bea6708 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -700,9 +700,9 @@ cairo: Copyright © 2002 University of Southern California, Copyright © 2005 Re <key>linux</key> <map> <key>md5sum</key> - <string>57ec243cf8e05e4fb7c737846a287498</string> + <string>31c9ddf859411c4890f1b31564b2fa91</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/gtk-etc-linux32-dbg-20100604.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/gtk-etc-linux-20101105.tar.bz2</uri> </map> <key>linux64</key> <map> From e99e8b57520974fef73646343afaa7bbfa8b800e Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 13:47:32 -0700 Subject: [PATCH 137/239] Fixed missing UseLocalChatWithBubbles control introduced in af6877fb (#685), patch by Nicky Perian --- linden/indra/newview/app_settings/settings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 91ed5c2f0..ccee51392 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -1183,6 +1183,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>UseLocalChatWithBubbles</key> + <map> + <key>Comment</key> + <string>Should local chat still appear even when using chat bubbles?</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>UseUTCTime</key> <map> <key>Comment</key> From 65bab486030247ee84d67b20df89e0d34c52691d Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 13:59:16 -0700 Subject: [PATCH 138/239] Applied patch by Nicky Perian for #680: commented out unused references to gstreamer post-webkit_plugins in viewer_manifest.py --- linden/indra/newview/viewer_manifest.py | 109 ++++++++++++------------ 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index f1892fc9e..e0f08b21e 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -339,63 +339,64 @@ def construct(self): self.path("ortp.dll") self.end_prefix() - +# Gstreamer is not used in webkit_plugins. The librries are never delivered/extracted to +# ../../libraries/i686-win32/lib/release . Commented out until decision made to use or drop. # Gstreamer plugins - if self.prefix(src="lib/gstreamer-plugins", dst=""): - self.path("*.dll", dst="lib/gstreamer-plugins/*.dll") - self.end_prefix() + #if self.prefix(src="lib/gstreamer-plugins", dst=""): + # self.path("*.dll", dst="lib/gstreamer-plugins/*.dll") + # self.end_prefix() # Gstreamer libs - if (not self.standalone()) and self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): - self.path("iconv.dll") - self.path("libxml2.dll") - self.path("libcairo-2.dll") - self.path("libgio-2.0-0.dll") - self.path("libglib-2.0-0.dll") - self.path("libgmodule-2.0-0.dll") - self.path("libgobject-2.0-0.dll") - self.path("libgthread-2.0-0.dll") - self.path("charset.dll") - self.path("intl.dll") - self.path("libgcrypt-11.dll") - self.path("libgnutls-26.dll") - self.path("libgpg-error-0.dll") - self.path("libgstapp.dll") - self.path("libgstaudio.dll") - self.path("libgstbase-0.10.dll") - self.path("libgstcdda.dll") - self.path("libgstcontroller-0.10.dll") - self.path("libgstdataprotocol-0.10.dll") - self.path("libgstdshow.dll") - self.path("libgstfft.dll") - self.path("libgstinterfaces.dll") - self.path("libgstnet-0.10.dll") - self.path("libgstnetbuffer.dll") - self.path("libgstpbutils.dll") - self.path("libgstreamer-0.10.dll") - self.path("libgstriff.dll") - self.path("libgstrtp.dll") - self.path("libgstrtsp.dll") - self.path("libgstsdp.dll") - self.path("libgsttag.dll") - self.path("libgstvideo.dll") - self.path("libjpeg.dll") - self.path("libmp3lame-0.dll") - self.path("libneon-27.dll") - self.path("libogg-0.dll") - self.path("liboil-0.3-0.dll") - self.path("libopenjpeg-2.dll") - self.path("libpng12-0.dll") - self.path("libschroedinger-1.0-0.dll") - self.path("libspeex-1.dll") - self.path("libtheora-0.dll") - self.path("libvorbis-0.dll") - self.path("libvorbisenc-2.dll") - self.path("libxml2-2.dll") - self.path("glew32.dll") - self.path("xvidcore.dll") - self.path("zlib1.dll") - self.end_prefix() + #if (not self.standalone()) and self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): + # self.path("iconv.dll") + # self.path("libxml2.dll") + # self.path("libcairo-2.dll") + # self.path("libgio-2.0-0.dll") + # self.path("libglib-2.0-0.dll") + # self.path("libgmodule-2.0-0.dll") + # self.path("libgobject-2.0-0.dll") + # self.path("libgthread-2.0-0.dll") + # self.path("charset.dll") + # self.path("intl.dll") + # self.path("libgcrypt-11.dll") + # self.path("libgnutls-26.dll") + # self.path("libgpg-error-0.dll") + # self.path("libgstapp.dll") + # self.path("libgstaudio.dll") + # self.path("libgstbase-0.10.dll") + # self.path("libgstcdda.dll") + # self.path("libgstcontroller-0.10.dll") + # self.path("libgstdataprotocol-0.10.dll") + # self.path("libgstdshow.dll") + # self.path("libgstfft.dll") + # self.path("libgstinterfaces.dll") + # self.path("libgstnet-0.10.dll") + # self.path("libgstnetbuffer.dll") + # self.path("libgstpbutils.dll") + # self.path("libgstreamer-0.10.dll") + # self.path("libgstriff.dll") + # self.path("libgstrtp.dll") + # self.path("libgstrtsp.dll") + # self.path("libgstsdp.dll") + # self.path("libgsttag.dll") + # self.path("libgstvideo.dll") + # self.path("libjpeg.dll") + # self.path("libmp3lame-0.dll") + # self.path("libneon-27.dll") + # self.path("libogg-0.dll") + # self.path("liboil-0.3-0.dll") + # self.path("libopenjpeg-2.dll") + # self.path("libpng12-0.dll") + # self.path("libschroedinger-1.0-0.dll") + # self.path("libspeex-1.dll") + # self.path("libtheora-0.dll") + # self.path("libvorbis-0.dll") + # self.path("libvorbisenc-2.dll") + # self.path("libxml2-2.dll") + # self.path("glew32.dll") + # self.path("xvidcore.dll") + # self.path("zlib1.dll") + # self.end_prefix() # # pull in the crash logger and updater from other projects # self.path(src=self.find_existing_file( # tag:"crash-logger" here as a cue to the exporter From d13d991d2d29bd3d0cc9a0d4e5480a0705681d06 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 14:01:50 -0700 Subject: [PATCH 139/239] Applied patch by Ansariel Hiller for #675: Keywords update to reflect changes to llSensor LSL function --- linden/indra/newview/app_settings/dictionaries/en_sl.dic | 2 ++ linden/indra/newview/app_settings/keywords.ini | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/app_settings/dictionaries/en_sl.dic b/linden/indra/newview/app_settings/dictionaries/en_sl.dic index f37b60db0..09076f788 100644 --- a/linden/indra/newview/app_settings/dictionaries/en_sl.dic +++ b/linden/indra/newview/app_settings/dictionaries/en_sl.dic @@ -1098,6 +1098,8 @@ STATUS_DIE_AT_EDGE STATUS_RETURN_AT_EDGE STATUS_CAST_SHADOWS AGENT +AGENT_BY_USERNAME +AGENT_BY_LEGACY_NAME ACTIVE PASSIVE SCRIPTED diff --git a/linden/indra/newview/app_settings/keywords.ini b/linden/indra/newview/app_settings/keywords.ini index 8e303dc22..36a4cdc30 100644 --- a/linden/indra/newview/app_settings/keywords.ini +++ b/linden/indra/newview/app_settings/keywords.ini @@ -66,7 +66,9 @@ STATUS_BLOCK_GRAB Passed in the llSetStatus library function. If TRUE, object c STATUS_DIE_AT_EDGE Passed in the llSetStatus library function. If TRUE, objects that reach the edge of the world just die:rather than teleporting back to the owner STATUS_RETURN_AT_EDGE Passed in the llSetStatus library function. If TRUE, script rezzed objects that reach the edge of the world:are returned rather than killed:STATUS_RETURN_AT_EDGE trumps STATUS_DIE_AT_EDGE if both are set STATUS_CAST_SHADOWS Passed in the llSetStatus library function. If TRUE, object casts shadows on other objects -AGENT Passed in llSensor library function to look for other Agents +AGENT Passed in llSensor library function to look for other Agents; DEPRECATED: Use AGENT_BY_LEGACY_NAME +AGENT_BY_USERNAME Passed in llSensor library function to look for other Agents by username +AGENT_BY_LEGACY_NAME Passed in llSensor library function to look for other Agents by legacy name ACTIVE Passed in llSensor library function to look for moving objects PASSIVE Passed in llSensor library function to look for objects that aren't moving SCRIPTED Passed in llSensor library function to look for scripted objects From 10394290949522474a483e97688a04088fec3baf Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 3 Nov 2010 17:53:55 +0100 Subject: [PATCH 140/239] Rename hippo* files to lower case (PART 1 OF 2) There was a problem with #include "hippolimits.h" because the file is called hippoLimits.h (with an uppercase L). After some discussion on IRC it was reluctantly decided that filenames should be lowercase, as is done for every Linden file. Moreover, hippolimits.h is about the class HippoLimits, with uppercase H, so even that doesn't match. Of course, then we immediately rename all hippo* files to lowercase. This patch ONLY renames the file, with no other changes. This is done in order to make sure that git won't get confused ;). All other necessary changes will be in the next commit. --- .../indra/newview/{hippoGridManager.cpp => hippogridmanager.cpp} | 0 linden/indra/newview/{hippoGridManager.h => hippogridmanager.h} | 0 linden/indra/newview/{hippoLimits.cpp => hippolimits.cpp} | 0 linden/indra/newview/{hippoLimits.h => hippolimits.h} | 0 .../indra/newview/{hippoRestRequest.cpp => hipporestrequest.cpp} | 0 linden/indra/newview/{hippoRestRequest.h => hipporestrequest.h} | 0 linden/indra/newview/{hippoUpdate.cpp => hippoupdate.cpp} | 0 linden/indra/newview/{hippoUpdate.h => hippoupdate.h} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename linden/indra/newview/{hippoGridManager.cpp => hippogridmanager.cpp} (100%) rename linden/indra/newview/{hippoGridManager.h => hippogridmanager.h} (100%) rename linden/indra/newview/{hippoLimits.cpp => hippolimits.cpp} (100%) rename linden/indra/newview/{hippoLimits.h => hippolimits.h} (100%) rename linden/indra/newview/{hippoRestRequest.cpp => hipporestrequest.cpp} (100%) rename linden/indra/newview/{hippoRestRequest.h => hipporestrequest.h} (100%) rename linden/indra/newview/{hippoUpdate.cpp => hippoupdate.cpp} (100%) rename linden/indra/newview/{hippoUpdate.h => hippoupdate.h} (100%) diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippogridmanager.cpp similarity index 100% rename from linden/indra/newview/hippoGridManager.cpp rename to linden/indra/newview/hippogridmanager.cpp diff --git a/linden/indra/newview/hippoGridManager.h b/linden/indra/newview/hippogridmanager.h similarity index 100% rename from linden/indra/newview/hippoGridManager.h rename to linden/indra/newview/hippogridmanager.h diff --git a/linden/indra/newview/hippoLimits.cpp b/linden/indra/newview/hippolimits.cpp similarity index 100% rename from linden/indra/newview/hippoLimits.cpp rename to linden/indra/newview/hippolimits.cpp diff --git a/linden/indra/newview/hippoLimits.h b/linden/indra/newview/hippolimits.h similarity index 100% rename from linden/indra/newview/hippoLimits.h rename to linden/indra/newview/hippolimits.h diff --git a/linden/indra/newview/hippoRestRequest.cpp b/linden/indra/newview/hipporestrequest.cpp similarity index 100% rename from linden/indra/newview/hippoRestRequest.cpp rename to linden/indra/newview/hipporestrequest.cpp diff --git a/linden/indra/newview/hippoRestRequest.h b/linden/indra/newview/hipporestrequest.h similarity index 100% rename from linden/indra/newview/hippoRestRequest.h rename to linden/indra/newview/hipporestrequest.h diff --git a/linden/indra/newview/hippoUpdate.cpp b/linden/indra/newview/hippoupdate.cpp similarity index 100% rename from linden/indra/newview/hippoUpdate.cpp rename to linden/indra/newview/hippoupdate.cpp diff --git a/linden/indra/newview/hippoUpdate.h b/linden/indra/newview/hippoupdate.h similarity index 100% rename from linden/indra/newview/hippoUpdate.h rename to linden/indra/newview/hippoupdate.h From b0446b980cc30d01644ef16f3775372109b612e3 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 3 Nov 2010 17:58:09 +0100 Subject: [PATCH 141/239] Rename hippo* files to lower case (PART 2 OF 2) There was a problem with #include "hippolimits.h" because the file is called hippoLimits.h (with an uppercase L). After some discussion on IRC it was reluctantly decided that filenames should be lowercase, as is done for every Linden file. This is part 2 or 2 (the first part just renamed the files). This part changes all files to make the viewer compile again after the renaming. --- linden/indra/llinventory/lltransactionflags.cpp | 2 +- linden/indra/llui/llnotifications.cpp | 2 +- linden/indra/newview/CMakeLists.txt | 12 ++++++------ linden/indra/newview/chatbar_as_cmdline.cpp | 2 +- linden/indra/newview/floatercommandline.cpp | 2 +- linden/indra/newview/floatergriddefault.cpp | 2 +- linden/indra/newview/floatergridmanager.cpp | 2 +- linden/indra/newview/floaterlocalassetbrowse.cpp | 2 +- linden/indra/newview/hippogridmanager.cpp | 4 ++-- linden/indra/newview/hippolimits.cpp | 4 ++-- linden/indra/newview/hipporestrequest.cpp | 2 +- linden/indra/newview/hippoupdate.cpp | 2 +- linden/indra/newview/kowopenregionsettings.cpp | 2 +- linden/indra/newview/llappviewer.cpp | 6 +++--- linden/indra/newview/llassetuploadresponders.cpp | 2 +- linden/indra/newview/llcurrencyuimanager.cpp | 2 +- linden/indra/newview/llfirstuse.cpp | 2 +- linden/indra/newview/llfloaterabout.cpp | 2 +- linden/indra/newview/llfloateranimpreview.cpp | 2 +- linden/indra/newview/llfloaterbuy.cpp | 2 +- linden/indra/newview/llfloaterbuycontents.cpp | 2 +- linden/indra/newview/llfloaterbuycurrency.cpp | 2 +- linden/indra/newview/llfloaterbuyland.cpp | 2 +- linden/indra/newview/llfloatergodtools.cpp | 2 +- linden/indra/newview/llfloatergroups.cpp | 2 +- linden/indra/newview/llfloaterhtmlhelp.cpp | 2 +- linden/indra/newview/llfloaterimagepreview.cpp | 2 +- linden/indra/newview/llfloaterland.cpp | 2 +- linden/indra/newview/llfloatermap.cpp | 2 +- linden/indra/newview/llfloaternamedesc.cpp | 2 +- linden/indra/newview/llfloaterpostcard.cpp | 2 +- linden/indra/newview/llfloaterproperties.cpp | 2 +- linden/indra/newview/llfloaterregioninfo.cpp | 2 +- linden/indra/newview/llfloatersellland.cpp | 2 +- linden/indra/newview/llfloatersnapshot.cpp | 2 +- linden/indra/newview/llfloatertools.cpp | 2 +- linden/indra/newview/llfloatertos.cpp | 2 +- linden/indra/newview/llfloaterworldmap.cpp | 2 +- linden/indra/newview/llgivemoney.cpp | 2 +- linden/indra/newview/llhoverview.cpp | 2 +- linden/indra/newview/llmanipscale.cpp | 2 +- linden/indra/newview/llmaniptranslate.cpp | 2 +- linden/indra/newview/llnetmap.cpp | 2 +- linden/indra/newview/llnotify.cpp | 2 +- linden/indra/newview/llpanelaudioprefs.cpp | 2 +- linden/indra/newview/llpanelclassified.cpp | 2 +- linden/indra/newview/llpaneldirfind.cpp | 2 +- linden/indra/newview/llpaneldirland.cpp | 2 +- linden/indra/newview/llpanelgroupgeneral.cpp | 2 +- linden/indra/newview/llpanelgrouplandmoney.cpp | 2 +- linden/indra/newview/llpanelinventory.cpp | 2 +- linden/indra/newview/llpanelland.cpp | 2 +- linden/indra/newview/llpanellandmedia.cpp | 2 +- linden/indra/newview/llpanellogin.cpp | 4 ++-- linden/indra/newview/llpanelmsgs.cpp | 2 +- linden/indra/newview/llpanelobject.cpp | 2 +- linden/indra/newview/llpanelpermissions.cpp | 2 +- linden/indra/newview/llpanelplace.cpp | 2 +- linden/indra/newview/llpanelweb.cpp | 2 +- linden/indra/newview/llprefsim.cpp | 2 +- linden/indra/newview/llstartup.cpp | 4 ++-- linden/indra/newview/llstatusbar.cpp | 2 +- linden/indra/newview/lltexturefetch.cpp | 2 +- linden/indra/newview/lltooldraganddrop.cpp | 2 +- linden/indra/newview/lltoolgrab.cpp | 2 +- linden/indra/newview/llviewerdisplay.cpp | 2 +- linden/indra/newview/llviewermenu.cpp | 4 ++-- linden/indra/newview/llviewermessage.cpp | 4 ++-- linden/indra/newview/llviewernetwork.cpp | 2 +- linden/indra/newview/llviewerparcelmgr.cpp | 2 +- linden/indra/newview/llvoavatar.cpp | 2 +- linden/indra/newview/llworld.cpp | 2 +- linden/indra/newview/llworldmap.cpp | 2 +- linden/indra/newview/llxmlrpctransaction.cpp | 2 +- linden/indra/newview/primbackup.cpp | 2 +- linden/indra/newview/windlightsettingsupdate.cpp | 2 +- linden/indra/newview/wlfloatermanager.cpp | 2 +- linden/indra/newview/wlfloaterwindlightsend.cpp | 2 +- linden/indra/newview/wlretrievesettings.cpp | 2 +- linden/indra/newview/wlsettingsmanager.cpp | 2 +- 80 files changed, 93 insertions(+), 93 deletions(-) diff --git a/linden/indra/llinventory/lltransactionflags.cpp b/linden/indra/llinventory/lltransactionflags.cpp index aaea16158..fda8cad90 100644 --- a/linden/indra/llinventory/lltransactionflags.cpp +++ b/linden/indra/llinventory/lltransactionflags.cpp @@ -37,7 +37,7 @@ #include "lltransactionflags.h" #include "lltransactiontypes.h" -#include "../newview/hippoGridManager.h" +#include "../newview/hippogridmanager.h" const U8 TRANSACTION_FLAGS_NONE = 0; const U8 TRANSACTION_FLAG_SOURCE_GROUP = 1; diff --git a/linden/indra/llui/llnotifications.cpp b/linden/indra/llui/llnotifications.cpp index 4d3ff462d..77f2ff778 100644 --- a/linden/indra/llui/llnotifications.cpp +++ b/linden/indra/llui/llnotifications.cpp @@ -40,7 +40,7 @@ #include <algorithm> #include <boost/regex.hpp> -#include "../newview/hippoGridManager.h" +#include "../newview/hippogridmanager.h" const std::string NOTIFICATION_PERSIST_VERSION = "0.93"; diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index 58c89eb5f..e3a1745af 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -82,9 +82,9 @@ set(viewer_SOURCE_FILES floaterlocalassetbrowse.cpp floatervoicelicense.cpp hbfloatergrouptitles.cpp - hippoGridManager.cpp - hippoLimits.cpp - hippoRestRequest.cpp + hippogridmanager.cpp + hippolimits.cpp + hipporestrequest.cpp impprefsfonts.cpp jcfloater_animation_list.cpp jcfloaterareasearch.cpp @@ -534,9 +534,9 @@ set(viewer_HEADER_FILES floaterlocalassetbrowse.h floatervoicelicense.h hbfloatergrouptitles.h - hippoGridManager.h - hippoLimits.h - hippoRestRequest.h + hippogridmanager.h + hippolimits.h + hipporestrequest.h impprefsfonts.h jcfloater_animation_list.h jcfloaterareasearch.h diff --git a/linden/indra/newview/chatbar_as_cmdline.cpp b/linden/indra/newview/chatbar_as_cmdline.cpp index 96787ada6..059309134 100644 --- a/linden/indra/newview/chatbar_as_cmdline.cpp +++ b/linden/indra/newview/chatbar_as_cmdline.cpp @@ -43,7 +43,7 @@ #include "lluuid.h" #include "llviewercontrol.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "material_codes.h" #include "llvolume.h" #include "object_flags.h" diff --git a/linden/indra/newview/floatercommandline.cpp b/linden/indra/newview/floatercommandline.cpp index c093a5828..6889696ca 100644 --- a/linden/indra/newview/floatercommandline.cpp +++ b/linden/indra/newview/floatercommandline.cpp @@ -32,7 +32,7 @@ #include "floatercommandline.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" diff --git a/linden/indra/newview/floatergriddefault.cpp b/linden/indra/newview/floatergriddefault.cpp index 2c31fb66e..6a2526dbb 100644 --- a/linden/indra/newview/floatergriddefault.cpp +++ b/linden/indra/newview/floatergriddefault.cpp @@ -32,7 +32,7 @@ #include "floatergriddefault.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llpanellogin.h" #include "llscrolllistctrl.h" #include "lluictrlfactory.h" diff --git a/linden/indra/newview/floatergridmanager.cpp b/linden/indra/newview/floatergridmanager.cpp index 3d4b17ff4..298fe3505 100644 --- a/linden/indra/newview/floatergridmanager.cpp +++ b/linden/indra/newview/floatergridmanager.cpp @@ -17,7 +17,7 @@ #include "llmd5.h" #include "llurlsimstring.h" #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewernetwork.h" #include "llpanellogin.h" diff --git a/linden/indra/newview/floaterlocalassetbrowse.cpp b/linden/indra/newview/floaterlocalassetbrowse.cpp index 991d2fd60..8ea13ccc3 100644 --- a/linden/indra/newview/floaterlocalassetbrowse.cpp +++ b/linden/indra/newview/floaterlocalassetbrowse.cpp @@ -53,7 +53,7 @@ this feature is still a work in progress. /* misc headers */ #include <time.h> #include <ctime> -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewerimagelist.h" #include "llviewerobjectlist.h" #include "llfilepicker.h" diff --git a/linden/indra/newview/hippogridmanager.cpp b/linden/indra/newview/hippogridmanager.cpp index dd0fa3518..d56214cc0 100644 --- a/linden/indra/newview/hippogridmanager.cpp +++ b/linden/indra/newview/hippogridmanager.cpp @@ -2,7 +2,7 @@ #include "llviewerprecompiledheaders.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include <cctype> @@ -17,7 +17,7 @@ #include "llviewercontrol.h" #include "llweb.h" -#include "hippoRestRequest.h" +#include "hipporestrequest.h" // ******************************************************************** diff --git a/linden/indra/newview/hippolimits.cpp b/linden/indra/newview/hippolimits.cpp index a5d6ee6ad..851e191ee 100644 --- a/linden/indra/newview/hippolimits.cpp +++ b/linden/indra/newview/hippolimits.cpp @@ -2,9 +2,9 @@ #include "llviewerprecompiledheaders.h" -#include "hippoLimits.h" +#include "hippolimits.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewercontrol.h" #include <llerror.h> diff --git a/linden/indra/newview/hipporestrequest.cpp b/linden/indra/newview/hipporestrequest.cpp index ed159074d..9d24aed4b 100644 --- a/linden/indra/newview/hipporestrequest.cpp +++ b/linden/indra/newview/hipporestrequest.cpp @@ -2,7 +2,7 @@ #include "llviewerprecompiledheaders.h" -#include "hippoRestRequest.h" +#include "hipporestrequest.h" #ifndef CURL_STATICLIB #define CURL_STATICLIB 1 diff --git a/linden/indra/newview/hippoupdate.cpp b/linden/indra/newview/hippoupdate.cpp index f6947ade4..192e3d74a 100644 --- a/linden/indra/newview/hippoupdate.cpp +++ b/linden/indra/newview/hippoupdate.cpp @@ -1,5 +1,5 @@ -#include "hippoUpdate.h" +#include "hippoupdate.h" #include <cstdio> #include <list> diff --git a/linden/indra/newview/kowopenregionsettings.cpp b/linden/indra/newview/kowopenregionsettings.cpp index 86a426c03..8aac87cac 100644 --- a/linden/indra/newview/kowopenregionsettings.cpp +++ b/linden/indra/newview/kowopenregionsettings.cpp @@ -27,7 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llhttpnode.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "llfloatertools.h" #include "llviewercontrol.h" #include "llagent.h" diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 3d8be5f91..38985d30c 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -176,9 +176,9 @@ #include "llcommandlineparser.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" -#include "hippoUpdate.h" +#include "hippogridmanager.h" +#include "hippolimits.h" +#include "hippoupdate.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llassetuploadresponders.cpp b/linden/indra/newview/llassetuploadresponders.cpp index b9ec9a026..d4a75f72c 100644 --- a/linden/indra/newview/llassetuploadresponders.cpp +++ b/linden/indra/newview/llassetuploadresponders.cpp @@ -63,7 +63,7 @@ #include "llscrolllistctrl.h" #include "llsdserialize.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // When uploading multiple files, don't display any of them when uploading more than this number. static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; diff --git a/linden/indra/newview/llcurrencyuimanager.cpp b/linden/indra/newview/llcurrencyuimanager.cpp index 99d043053..07b1287e8 100644 --- a/linden/indra/newview/llcurrencyuimanager.cpp +++ b/linden/indra/newview/llcurrencyuimanager.cpp @@ -47,7 +47,7 @@ #include "llxmlrpctransaction.h" #include "llviewernetwork.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0; // how long of a pause in typing a currency buy amount before an diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp index 0b777ea45..18efa9ea8 100644 --- a/linden/indra/newview/llfirstuse.cpp +++ b/linden/indra/newview/llfirstuse.cpp @@ -47,7 +47,7 @@ #include "floatergriddefault.h" #include "floatervoicelicense.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llstartup.h" #include "llvoavatar.h" diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 4be83b6cd..5c037d67a 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp @@ -44,7 +44,7 @@ #include "llimagej2c.h" #include "llaudioengine.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewertexteditor.h" #include "llviewercontrol.h" #include "llagent.h" diff --git a/linden/indra/newview/llfloateranimpreview.cpp b/linden/indra/newview/llfloateranimpreview.cpp index 09d3b2cbf..232530c2b 100644 --- a/linden/indra/newview/llfloateranimpreview.cpp +++ b/linden/indra/newview/llfloateranimpreview.cpp @@ -68,7 +68,7 @@ #include "pipeline.h" #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" S32 LLFloaterAnimPreview::sUploadAmount = 10; diff --git a/linden/indra/newview/llfloaterbuy.cpp b/linden/indra/newview/llfloaterbuy.cpp index 86cab43f6..99c9fed5d 100644 --- a/linden/indra/newview/llfloaterbuy.cpp +++ b/linden/indra/newview/llfloaterbuy.cpp @@ -50,7 +50,7 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" LLFloaterBuy* LLFloaterBuy::sInstance = NULL; diff --git a/linden/indra/newview/llfloaterbuycontents.cpp b/linden/indra/newview/llfloaterbuycontents.cpp index 498d6acc4..e16f98dff 100644 --- a/linden/indra/newview/llfloaterbuycontents.cpp +++ b/linden/indra/newview/llfloaterbuycontents.cpp @@ -54,7 +54,7 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL; diff --git a/linden/indra/newview/llfloaterbuycurrency.cpp b/linden/indra/newview/llfloaterbuycurrency.cpp index 509649593..6a0dd6886 100644 --- a/linden/indra/newview/llfloaterbuycurrency.cpp +++ b/linden/indra/newview/llfloaterbuycurrency.cpp @@ -46,7 +46,7 @@ #include "llwindow.h" #include "llappviewer.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" static const S32 STANDARD_BUY_AMOUNT = 2000; static const S32 MINIMUM_BALANCE_AMOUNT = 0; diff --git a/linden/indra/newview/llfloaterbuyland.cpp b/linden/indra/newview/llfloaterbuyland.cpp index 75630b210..8288c581c 100644 --- a/linden/indra/newview/llfloaterbuyland.cpp +++ b/linden/indra/newview/llfloaterbuyland.cpp @@ -66,7 +66,7 @@ #include "llviewernetwork.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // NOTE: This is duplicated in lldatamoney.cpp ... const F32 GROUP_LAND_BONUS_FACTOR = 1.1f; diff --git a/linden/indra/newview/llfloatergodtools.cpp b/linden/indra/newview/llfloatergodtools.cpp index 461dfe258..f918e8a46 100644 --- a/linden/indra/newview/llfloatergodtools.cpp +++ b/linden/indra/newview/llfloatergodtools.cpp @@ -77,7 +77,7 @@ #include "lltransfertargetfile.h" #include "lltransfersourcefile.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const F32 SECONDS_BETWEEN_UPDATE_REQUESTS = 5.0f; diff --git a/linden/indra/newview/llfloatergroups.cpp b/linden/indra/newview/llfloatergroups.cpp index 79e9e3136..f7359236c 100644 --- a/linden/indra/newview/llfloatergroups.cpp +++ b/linden/indra/newview/llfloatergroups.cpp @@ -59,7 +59,7 @@ #include "llviewerwindow.h" #include "llimview.h" -#include "hippoLimits.h" +#include "hippolimits.h" // static std::map<const LLUUID, LLFloaterGroupPicker*> LLFloaterGroupPicker::sInstances; diff --git a/linden/indra/newview/llfloaterhtmlhelp.cpp b/linden/indra/newview/llfloaterhtmlhelp.cpp index 1ec964b36..c89c2e283 100644 --- a/linden/indra/newview/llfloaterhtmlhelp.cpp +++ b/linden/indra/newview/llfloaterhtmlhelp.cpp @@ -54,7 +54,7 @@ #include "llviewerparcelmedia.h" #include "llcombobox.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) { diff --git a/linden/indra/newview/llfloaterimagepreview.cpp b/linden/indra/newview/llfloaterimagepreview.cpp index 8142869af..aa8a94faf 100644 --- a/linden/indra/newview/llfloaterimagepreview.cpp +++ b/linden/indra/newview/llfloaterimagepreview.cpp @@ -60,7 +60,7 @@ #include "llstring.h" #include "llviewercontrol.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #ifdef LL_DARWIN #include "llwindowmacosx-objc.h" diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp index 42bc41c3e..cc3e38563 100644 --- a/linden/indra/newview/llfloaterland.cpp +++ b/linden/indra/newview/llfloaterland.cpp @@ -77,7 +77,7 @@ #include "llviewercontrol.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp index 34b8dde3b..e63ea4b94 100644 --- a/linden/indra/newview/llfloatermap.cpp +++ b/linden/indra/newview/llfloatermap.cpp @@ -44,7 +44,7 @@ #include "lluictrlfactory.h" #include "llfirstuse.h" #include "panelradar.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] diff --git a/linden/indra/newview/llfloaternamedesc.cpp b/linden/indra/newview/llfloaternamedesc.cpp index 941361189..9e8e94b8a 100644 --- a/linden/indra/newview/llfloaternamedesc.cpp +++ b/linden/indra/newview/llfloaternamedesc.cpp @@ -55,7 +55,7 @@ #include "llassetstorage.h" #include "llinventorytype.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const S32 PREVIEW_LINE_HEIGHT = 19; const S32 PREVIEW_CLOSE_BOX_SIZE = 16; diff --git a/linden/indra/newview/llfloaterpostcard.cpp b/linden/indra/newview/llfloaterpostcard.cpp index aa9b2fbae..8cd552ef5 100644 --- a/linden/indra/newview/llfloaterpostcard.cpp +++ b/linden/indra/newview/llfloaterpostcard.cpp @@ -66,7 +66,7 @@ #include <boost/regex.hpp> //boost.regex lib -#include "hippoGridManager.h" +#include "hippogridmanager.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llfloaterproperties.cpp b/linden/indra/newview/llfloaterproperties.cpp index 40b293ae1..96e164265 100644 --- a/linden/indra/newview/llfloaterproperties.cpp +++ b/linden/indra/newview/llfloaterproperties.cpp @@ -59,7 +59,7 @@ #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index 9e6f32347..8ae3fa2a5 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -80,7 +80,7 @@ #include "llviewertexteditor.h" #include "llviewerwindow.h" #include "llvlcomposition.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llfloatersellland.cpp b/linden/indra/newview/llfloatersellland.cpp index bf4a4c3c9..9b257089f 100644 --- a/linden/indra/newview/llfloatersellland.cpp +++ b/linden/indra/newview/llfloatersellland.cpp @@ -46,7 +46,7 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // defined in llfloaterland.cpp void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp index a58120dc7..e007680fa 100644 --- a/linden/indra/newview/llfloatersnapshot.cpp +++ b/linden/indra/newview/llfloatersnapshot.cpp @@ -77,7 +77,7 @@ #include "llvfile.h" #include "llvfs.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 2f02f1ef3..683ebd4ba 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -85,7 +85,7 @@ #include "llvotree.h" #include "lluictrlfactory.h" #include "qtoolalign.h" -#include "hippoLimits.h" +#include "hippolimits.h" // Globals LLFloaterTools *gFloaterTools = NULL; diff --git a/linden/indra/newview/llfloatertos.cpp b/linden/indra/newview/llfloatertos.cpp index f3a124ab7..ac4a06b17 100644 --- a/linden/indra/newview/llfloatertos.cpp +++ b/linden/indra/newview/llfloatertos.cpp @@ -52,7 +52,7 @@ #include "lluictrlfactory.h" #include "llvfile.h" #include "message.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // static diff --git a/linden/indra/newview/llfloaterworldmap.cpp b/linden/indra/newview/llfloaterworldmap.cpp index 0a01ca70a..47f336196 100644 --- a/linden/indra/newview/llfloaterworldmap.cpp +++ b/linden/indra/newview/llfloaterworldmap.cpp @@ -70,7 +70,7 @@ #include "llglheaders.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llgivemoney.cpp b/linden/indra/newview/llgivemoney.cpp index 6c6933424..ee2bf6342 100644 --- a/linden/indra/newview/llgivemoney.cpp +++ b/linden/indra/newview/llgivemoney.cpp @@ -52,7 +52,7 @@ #include "lltransactiontypes.h" #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp index c7136bcd2..10d27cdd2 100644 --- a/linden/indra/newview/llhoverview.cpp +++ b/linden/indra/newview/llhoverview.cpp @@ -73,7 +73,7 @@ #include "llhudmanager.h" // For testing effects #include "llhudeffect.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llmanipscale.cpp b/linden/indra/newview/llmanipscale.cpp index fa7e85f95..268e4310e 100644 --- a/linden/indra/newview/llmanipscale.cpp +++ b/linden/indra/newview/llmanipscale.cpp @@ -63,7 +63,7 @@ #include "v2math.h" #include "llvoavatar.h" -#include "hippoLimits.h" +#include "hippolimits.h" const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f; diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp index cc14b277d..8484c4ec1 100644 --- a/linden/indra/newview/llmaniptranslate.cpp +++ b/linden/indra/newview/llmaniptranslate.cpp @@ -66,7 +66,7 @@ #include "llui.h" #include "pipeline.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp index dc4456aa5..b9dc482ba 100644 --- a/linden/indra/newview/llnetmap.cpp +++ b/linden/indra/newview/llnetmap.cpp @@ -71,7 +71,7 @@ #include "llglheaders.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp index b0f5f9149..891707b90 100644 --- a/linden/indra/newview/llnotify.cpp +++ b/linden/indra/newview/llnotify.cpp @@ -55,7 +55,7 @@ #include "lloverlaybar.h" // for gOverlayBar #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] - Version: 1.23.4 #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelaudioprefs.cpp b/linden/indra/newview/llpanelaudioprefs.cpp index d4c8e9fc0..1acfcbb44 100644 --- a/linden/indra/newview/llpanelaudioprefs.cpp +++ b/linden/indra/newview/llpanelaudioprefs.cpp @@ -62,7 +62,7 @@ #include "llviewerwindow.h" #include "llviewercontrol.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // // Static functions diff --git a/linden/indra/newview/llpanelclassified.cpp b/linden/indra/newview/llpanelclassified.cpp index d3230c80b..99b6cf661 100644 --- a/linden/indra/newview/llpanelclassified.cpp +++ b/linden/indra/newview/llpanelclassified.cpp @@ -70,7 +70,7 @@ #include "llviewerwindow.h" // for window width, height #include "llappviewer.h" // abortQuit() -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpaneldirfind.cpp b/linden/indra/newview/llpaneldirfind.cpp index 14c4a909c..342ffec61 100644 --- a/linden/indra/newview/llpaneldirfind.cpp +++ b/linden/indra/newview/llpaneldirfind.cpp @@ -73,7 +73,7 @@ #include "boost/lexical_cast.hpp" #endif -#include "hippoGridManager.h" +#include "hippogridmanager.h" //--------------------------------------------------------------------------- // LLPanelDirFindAll - Google search appliance based search diff --git a/linden/indra/newview/llpaneldirland.cpp b/linden/indra/newview/llpaneldirland.cpp index c7029314f..3fdf37e7d 100644 --- a/linden/indra/newview/llpaneldirland.cpp +++ b/linden/indra/newview/llpaneldirland.cpp @@ -52,7 +52,7 @@ #include "llviewercontrol.h" #include "llviewermessage.h" #include "llnotify.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //----------------------------------------------------------------------------- // Constants diff --git a/linden/indra/newview/llpanelgroupgeneral.cpp b/linden/indra/newview/llpanelgroupgeneral.cpp index e0d637671..6878f84b3 100644 --- a/linden/indra/newview/llpanelgroupgeneral.cpp +++ b/linden/indra/newview/llpanelgroupgeneral.cpp @@ -34,7 +34,7 @@ #include "llpanelgroupgeneral.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "lluictrlfactory.h" #include "llagent.h" diff --git a/linden/indra/newview/llpanelgrouplandmoney.cpp b/linden/indra/newview/llpanelgrouplandmoney.cpp index bded59c30..3f128fe28 100644 --- a/linden/indra/newview/llpanelgrouplandmoney.cpp +++ b/linden/indra/newview/llpanelgrouplandmoney.cpp @@ -55,7 +55,7 @@ #include "llfloaterworldmap.h" #include "llviewermessage.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //////////////////////////////////////////////////////////////////////////// diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index 41ba5130e..9cd2759c5 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp @@ -82,7 +82,7 @@ #include "llviewerwindow.h" #include "llwearable.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelland.cpp b/linden/indra/newview/llpanelland.cpp index ea6a55795..d1eee80b3 100644 --- a/linden/indra/newview/llpanelland.cpp +++ b/linden/indra/newview/llpanelland.cpp @@ -49,7 +49,7 @@ #include "lluictrlfactory.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanellandmedia.cpp b/linden/indra/newview/llpanellandmedia.cpp index 11f491c3d..b7df164ca 100644 --- a/linden/indra/newview/llpanellandmedia.cpp +++ b/linden/indra/newview/llpanellandmedia.cpp @@ -55,7 +55,7 @@ #include "lltexturectrl.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //--------------------------------------------------------------------------- // LLPanelLandMedia diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp index 2a8c20f8c..6464f0bb8 100644 --- a/linden/indra/newview/llpanellogin.cpp +++ b/linden/indra/newview/llpanellogin.cpp @@ -36,8 +36,8 @@ #include "llpanelgeneral.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "floatergridmanager.h" #include "indra_constants.h" // for key and mask constants diff --git a/linden/indra/newview/llpanelmsgs.cpp b/linden/indra/newview/llpanelmsgs.cpp index 3ea7aa573..9e04070e4 100644 --- a/linden/indra/newview/llpanelmsgs.cpp +++ b/linden/indra/newview/llpanelmsgs.cpp @@ -40,7 +40,7 @@ #include "lluictrlfactory.h" #include "llfirstuse.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //----------------------------------------------------------------------------- LLPanelMsgs::LLPanelMsgs() : diff --git a/linden/indra/newview/llpanelobject.cpp b/linden/indra/newview/llpanelobject.cpp index 706f98e7f..cc89e24ff 100644 --- a/linden/indra/newview/llpanelobject.cpp +++ b/linden/indra/newview/llpanelobject.cpp @@ -76,7 +76,7 @@ #include "lldrawpool.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp index 5131d2c15..6b7bc1bad 100644 --- a/linden/indra/newview/llpanelpermissions.cpp +++ b/linden/indra/newview/llpanelpermissions.cpp @@ -68,7 +68,7 @@ #include "lluictrlfactory.h" #include "roles_constants.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llpanelplace.cpp b/linden/indra/newview/llpanelplace.cpp index eb3d17da0..fe88c137e 100644 --- a/linden/indra/newview/llpanelplace.cpp +++ b/linden/indra/newview/llpanelplace.cpp @@ -58,7 +58,7 @@ #include "llweb.h" #include "llsdutil.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" //static std::list<LLPanelPlace*> LLPanelPlace::sAllPanels; diff --git a/linden/indra/newview/llpanelweb.cpp b/linden/indra/newview/llpanelweb.cpp index 14df239e9..6f9bd7a5a 100644 --- a/linden/indra/newview/llpanelweb.cpp +++ b/linden/indra/newview/llpanelweb.cpp @@ -37,7 +37,7 @@ // project includes #include "llcheckboxctrl.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" #include "llviewermedia.h" diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp index e915bd2fd..9e86cd348 100644 --- a/linden/indra/newview/llprefsim.cpp +++ b/linden/indra/newview/llprefsim.cpp @@ -49,7 +49,7 @@ #include "lldirpicker.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 49446c714..b744961e4 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -210,8 +210,8 @@ #include "floaterao.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "lggautocorrect.h" // diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp index 457910083..3370f7fbd 100644 --- a/linden/indra/newview/llstatusbar.cpp +++ b/linden/indra/newview/llstatusbar.cpp @@ -83,7 +83,7 @@ #include "llstring.h" #include "message.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "viewertime.h" // diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index f63deb89d..f93a5748f 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -2275,7 +2275,7 @@ void LLTextureFetch::dump() // // *TODO: This is a *HACK and may not work if the grid is heterogenous. // Remove it once OpenSim versions in the wild are > 0.7.0.2! -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include <boost/regex.hpp> //static bool LLTextureFetch::hasBuggyHTTPRange() diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index 4e133de47..18c49178d 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp @@ -75,7 +75,7 @@ // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] -#include "hippoLimits.h" +#include "hippolimits.h" // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a diff --git a/linden/indra/newview/lltoolgrab.cpp b/linden/indra/newview/lltoolgrab.cpp index 9b6d6f76b..10b043113 100644 --- a/linden/indra/newview/lltoolgrab.cpp +++ b/linden/indra/newview/lltoolgrab.cpp @@ -64,7 +64,7 @@ #include "llvoavatar.h" #include "llworld.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index 416746477..59a87d5f3 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -82,7 +82,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index ace0bcbc7..a663e60d9 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -228,8 +228,8 @@ #include "jcfloater_animation_list.h" #include "llfloaterassetbrowser.h" -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "llfloaterteleporthistory.h" diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index 743e0d9ba..5f333e9a4 100755 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -150,8 +150,8 @@ #include <boost/tokenizer.hpp> #include <boost/regex.hpp> // Boost Reg Expresions -#include "hippoGridManager.h" -#include "hippoLimits.h" +#include "hippogridmanager.h" +#include "hippolimits.h" #include "wlsettingsmanager.h" #if LL_WINDOWS // For Windows specific error handler diff --git a/linden/indra/newview/llviewernetwork.cpp b/linden/indra/newview/llviewernetwork.cpp index c1d5013c8..1cfe6654b 100644 --- a/linden/indra/newview/llviewernetwork.cpp +++ b/linden/indra/newview/llviewernetwork.cpp @@ -37,7 +37,7 @@ #include "llviewercontrol.h" #include "llstartup.h" - #include "hippoGridManager.h" + #include "hippogridmanager.h" unsigned char gMACAddress[MAC_ADDRESS_BYTES]; /* Flawfinder: ignore */ diff --git a/linden/indra/newview/llviewerparcelmgr.cpp b/linden/indra/newview/llviewerparcelmgr.cpp index 53260492d..b589f2e24 100644 --- a/linden/indra/newview/llviewerparcelmgr.cpp +++ b/linden/indra/newview/llviewerparcelmgr.cpp @@ -70,7 +70,7 @@ #include "roles_constants.h" #include "llweb.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" const F32 PARCEL_COLLISION_DRAW_SECS = 1.f; diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index c4a4dee44..54aed5406 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -94,7 +94,7 @@ #else #include "boost/lexical_cast.hpp" #endif -#include "hippoLimits.h"// getMaxPrimScale +#include "hippolimits.h"// getMaxPrimScale #include "llstartup.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp index c484462ab..7866bf8f7 100644 --- a/linden/indra/newview/llworld.cpp +++ b/linden/indra/newview/llworld.cpp @@ -60,7 +60,7 @@ #include "pipeline.h" #include "llappviewer.h" // for do_disconnect() -#include "hippoLimits.h" +#include "hippolimits.h" #include <deque> #include <queue> diff --git a/linden/indra/newview/llworldmap.cpp b/linden/indra/newview/llworldmap.cpp index 43d742615..3ada36f26 100644 --- a/linden/indra/newview/llworldmap.cpp +++ b/linden/indra/newview/llworldmap.cpp @@ -47,7 +47,7 @@ #include "llviewerimagelist.h" #include "llviewerregion.h" #include "llregionflags.h" - #include "hippoGridManager.h" + #include "hippogridmanager.h" bool LLWorldMap::sGotMapURL = false; const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // 10 minutes diff --git a/linden/indra/newview/llxmlrpctransaction.cpp b/linden/indra/newview/llxmlrpctransaction.cpp index b993c9954..058946eb2 100644 --- a/linden/indra/newview/llxmlrpctransaction.cpp +++ b/linden/indra/newview/llxmlrpctransaction.cpp @@ -35,7 +35,7 @@ #include "llxmlrpctransaction.h" #include "llcurl.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "llviewercontrol.h" // Have to include these last to avoid queue redefinition! diff --git a/linden/indra/newview/primbackup.cpp b/linden/indra/newview/primbackup.cpp index 63043f068..7f050a01c 100644 --- a/linden/indra/newview/primbackup.cpp +++ b/linden/indra/newview/primbackup.cpp @@ -54,7 +54,7 @@ #include "llappviewer.h" #include "lltransactiontypes.h" -#include "hippoGridManager.h" +#include "hippogridmanager.h" #include "primbackup.h" diff --git a/linden/indra/newview/windlightsettingsupdate.cpp b/linden/indra/newview/windlightsettingsupdate.cpp index a5f9cb7ba..ad6e7c968 100644 --- a/linden/indra/newview/windlightsettingsupdate.cpp +++ b/linden/indra/newview/windlightsettingsupdate.cpp @@ -27,7 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llhttpnode.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "llfloatertools.h" #include "llviewercontrol.h" #include "llagent.h" diff --git a/linden/indra/newview/wlfloatermanager.cpp b/linden/indra/newview/wlfloatermanager.cpp index 19468078e..63abe14ac 100644 --- a/linden/indra/newview/wlfloatermanager.cpp +++ b/linden/indra/newview/wlfloatermanager.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloatermanager.h" #include "llviewerregion.h" #include "llviewerparcelmgr.h" diff --git a/linden/indra/newview/wlfloaterwindlightsend.cpp b/linden/indra/newview/wlfloaterwindlightsend.cpp index 5244bcd4f..e6148edd1 100644 --- a/linden/indra/newview/wlfloaterwindlightsend.cpp +++ b/linden/indra/newview/wlfloaterwindlightsend.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloaterwindlightsend.h" #include "llviewerregion.h" diff --git a/linden/indra/newview/wlretrievesettings.cpp b/linden/indra/newview/wlretrievesettings.cpp index ca91ba2ae..afa84f25a 100644 --- a/linden/indra/newview/wlretrievesettings.cpp +++ b/linden/indra/newview/wlretrievesettings.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloaterwindlightsend.h" #include "llviewerregion.h" #include "wlsettingsmanager.h" diff --git a/linden/indra/newview/wlsettingsmanager.cpp b/linden/indra/newview/wlsettingsmanager.cpp index 853d14f9a..c0a07e1fb 100644 --- a/linden/indra/newview/wlsettingsmanager.cpp +++ b/linden/indra/newview/wlsettingsmanager.cpp @@ -64,7 +64,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" -#include "hippoLimits.h" +#include "hippolimits.h" #include "wlfloaterwindlightsend.h" #include "llviewerregion.h" #include "wlsettingsmanager.h" From 58a00b0ed40ea430a97b263cfe5611b0cf76f08f Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 3 Nov 2010 21:32:14 +0100 Subject: [PATCH 142/239] Center the "loading..." text on the login page. The loading.html page is no longer used. Instead embedded html found in panel_login.xml is used. I couldn't get it to show an image, but at least the "loading..." text is now centralized and I changed the background color from black to imprudence-purple. --- .../default/html/en-us/loading/loading.html | 9 ------ .../skins/default/xui/en-us/panel_login.xml | 28 ++++++++++++++----- 2 files changed, 21 insertions(+), 16 deletions(-) delete mode 100644 linden/indra/newview/skins/default/html/en-us/loading/loading.html diff --git a/linden/indra/newview/skins/default/html/en-us/loading/loading.html b/linden/indra/newview/skins/default/html/en-us/loading/loading.html deleted file mode 100644 index 97174b017..000000000 --- a/linden/indra/newview/skins/default/html/en-us/loading/loading.html +++ /dev/null @@ -1,9 +0,0 @@ -<body style="background-color:#000000;font-family:verdana,helvetica,sans-serif;font-size:62.5%;color:#e9f1f8;"> -<table width="100%" height="100%" border="0"> - <tr> - <td align="center" valign="middle" style="font-size:0.8em;"> - <img src="imprudence_loading.png" align="absmiddle"><br/>   loading... - </td> - </tr> -</table> -</body> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml index 96f3f7718..048005d91 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml @@ -1,13 +1,27 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="panel_login" - bottom="0" left="0" height="600" width="800" - follows="left|top|right|bottom" mouse_opaque="true" > - - <web_browser name="login_html" - bottom="0" top="-1" left="0" right="-1" - border_visible="false" follows="top|left|bottom|right" - start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody bgcolor=%22#000000%22 text=%22ffffff%22%3E%3Ch1%3E%3Ctt%3Eloading...%3C/tt%3E%3C/h1%3E %3C/body%3E %3C/html%3E" /> + bottom="0" left="0" height="600" width="800" + follows="left|top|right|bottom" mouse_opaque="true" > + + <web_browser name="login_html" + bottom="0" top="-1" left="0" right="-1" + border_visible="false" follows="top|left|bottom|right" + start_url="data:text/html, + %3Chtml%3E + %3Chead%3E %3C/head%3E + %3Cbody bgcolor=%22#5a2d65%22 text=%22ffffff%22%3E + %3Ctable width=%22100%%22 height=%22100%%22 border=%220%22%3E + %3Ctr%3E + %3Ctd align=%22center%22 valign=%22middle%22 style=%22font-size:0.8em;%22%3E + %3Cimg src=%22imprudence_loading.png%22 align=%22absmiddle%22%3E + %3Cbr/%3E + %3CH1%3Eloading...%3C/H1%3E + %3C/td%3E + %3C/tr%3C + %3C/table%3E + %3C/body%3E + %3C/html%3E" /> <string name="real_url"> http://secondlife.com/app/login/ </string> From 77444695c7eef38826a85aff5fb9f0fb97b8f9ce Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 5 Nov 2010 14:33:52 +0100 Subject: [PATCH 143/239] IMP-592: Extend login screen menu bar till the top of the window. Basically, this Linden code is just horribly broken. I spend already too much time on this (two days) for dead code, so I settled for a minimal fix for this particular case that works, instead of fixing their code properly. The problem is that without specifying "bottom" the code adds 4 pixels (VPAD) between whatever widget that is added and it's parents top (in LLView::createRect). In order to be sure that bottom is exactly minus the height, I had to specify the height too; hopefully this value is the same for everyone cause theorectically it depends on the font size (4 + fontheight + 4). The default height of the Linden code is only 4 + fontheight (they leave off the VPAD). --- linden/doc/contributions.txt | 1 + linden/indra/newview/skins/default/xui/en-us/menu_login.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index f51891160..a54424ca7 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -80,6 +80,7 @@ Aleric Inglewood IMP-578 IMP-579 IMP-581 + IMP-592 IMP-595 IMP-660 IMP-661 diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_login.xml b/linden/indra/newview/skins/default/xui/en-us/menu_login.xml index d9a9c4cde..18fb8e632 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_login.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_login.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu_bar name="Login Menu" opaque="true" tear_off="false"> +<menu_bar name="Login Menu" opaque="true" tear_off="false" height="18" bottom="-18"> <menu create_jump_keys="true" label="File" name="File" opaque="true" tear_off="false"> <menu_item_call label="Quit" name="Quit" shortcut="control|Q"> <on_click function="File.Quit" userdata="" /> From adbffe79b6b2794e647f6259132f5d64e1e93ea0 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 17:10:28 -0700 Subject: [PATCH 144/239] Created new preferences panel to handle chat colors and name highlighting (removes the 'Extras' panel from Prefs > Advanced and moves the color options from 'Text Chat') --- linden/indra/newview/CMakeLists.txt | 2 + linden/indra/newview/llfloaterpreference.cpp | 14 +- linden/indra/newview/llfloaterpreference.h | 2 + linden/indra/newview/llprefsadvanced.cpp | 27 -- linden/indra/newview/llprefschat.cpp | 51 ---- linden/indra/newview/llprefscolors.cpp | 180 +++++++++++++ linden/indra/newview/llprefscolors.h | 67 +++++ .../xui/en-us/panel_preferences_advanced.xml | 51 ---- .../xui/en-us/panel_preferences_chat.xml | 246 +++++++----------- .../xui/en-us/panel_preferences_colors.xml | 115 ++++++++ 10 files changed, 478 insertions(+), 277 deletions(-) create mode 100644 linden/indra/newview/llprefscolors.cpp create mode 100644 linden/indra/newview/llprefscolors.h create mode 100644 linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index e3a1745af..a4d99f232 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -333,6 +333,7 @@ set(viewer_SOURCE_FILES llpolymorph.cpp llprefsadvanced.cpp llprefschat.cpp + llprefscolors.cpp llprefsim.cpp llprefsvoice.cpp llpreviewanim.cpp @@ -790,6 +791,7 @@ set(viewer_HEADER_FILES llpolymorph.h llprefsadvanced.h llprefschat.h + llprefscolors.h llprefsim.h llprefsvoice.h llpreview.h diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp index b74072569..906cf1194 100644 --- a/linden/indra/newview/llfloaterpreference.cpp +++ b/linden/indra/newview/llfloaterpreference.cpp @@ -64,6 +64,7 @@ #include "llpanelskins.h" #include "llprefsadvanced.h" #include "llprefschat.h" +#include "llprefscolors.h" #include "llprefsvoice.h" #include "llprefsim.h" #include "llresizehandle.h" @@ -133,6 +134,7 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def mAudioPanel(NULL), mMsgPanel(NULL), mSkinsPanel(NULL), + mPrefsColors(NULL), mLCDPanel(NULL), mPrefsFonts(NULL), mPrefsAdvanced(NULL) @@ -190,6 +192,10 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def mMsgPanel = new LLPanelMsgs(); mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mMsgPanel->setDefaultBtn(default_btn); + + mPrefsColors = new LLPrefsColors(); + mTabContainer->addTabPanel(mPrefsColors, mPrefsColors->getLabel(), FALSE, onTabChanged, mTabContainer); + mPrefsColors->setDefaultBtn(default_btn); mSkinsPanel = new LLPanelSkins(); mTabContainer->addTabPanel(mSkinsPanel, mSkinsPanel->getLabel(), FALSE, onTabChanged, mTabContainer); @@ -272,7 +278,11 @@ LLPreferenceCore::~LLPreferenceCore() delete mPrefsFonts; mPrefsFonts = NULL; } - + if (mPrefsColors) + { + delete mPrefsColors; + mPrefsColors = NULL; + } } @@ -290,6 +300,7 @@ void LLPreferenceCore::apply() mSkinsPanel->apply(); mPrefsAdvanced->apply(); mPrefsFonts->apply(); + mPrefsColors->apply(); // hardware menu apply LLFloaterHardwareSettings::instance()->apply(); @@ -320,6 +331,7 @@ void LLPreferenceCore::cancel() mSkinsPanel->cancel(); mPrefsAdvanced->cancel(); mPrefsFonts->cancel(); + mPrefsColors->cancel(); // cancel hardware menu LLFloaterHardwareSettings::instance()->cancel(); diff --git a/linden/indra/newview/llfloaterpreference.h b/linden/indra/newview/llfloaterpreference.h index e98c45cc4..c52f5412c 100644 --- a/linden/indra/newview/llfloaterpreference.h +++ b/linden/indra/newview/llfloaterpreference.h @@ -57,6 +57,7 @@ class LLPanelMsgs; class LLPanelSkins; class LLPrefsAdvanced; class ImpPrefsFonts; +class LLPrefsColors; class LLScrollListCtrl; class LLPreferenceCore @@ -94,6 +95,7 @@ class LLPreferenceCore LLPanelMsgs *mMsgPanel; LLPanelLCD *mLCDPanel; LLPrefsAdvanced *mPrefsAdvanced; + LLPrefsColors *mPrefsColors; ImpPrefsFonts* mPrefsFonts; }; diff --git a/linden/indra/newview/llprefsadvanced.cpp b/linden/indra/newview/llprefsadvanced.cpp index aa62b3445..99bc4fdca 100644 --- a/linden/indra/newview/llprefsadvanced.cpp +++ b/linden/indra/newview/llprefsadvanced.cpp @@ -116,15 +116,6 @@ BOOL LLPrefsAdvanced::postBuild() initHelpBtn("EmeraldHelp_SpellCheck", "EmeraldHelp_SpellCheck"); - childSetValue("HighlightOwnNameInIM", gSavedSettings.getBOOL("HighlightOwnNameInIM")); - childSetValue("HighlightFriendsChat", gSavedSettings.getBOOL("HighlightFriendsChat")); - getChild<LLColorSwatchCtrl>("FriendsChatColor")->set(gSavedSettings.getColor4("FriendsChatColor")); - childSetValue("HighlightOwnNameInChat", gSavedSettings.getBOOL("HighlightOwnNameInChat")); - getChild<LLColorSwatchCtrl>("OwnNameChatColor")->set(gSavedSettings.getColor4("OwnNameChatColor")); - childSetValue("nick01", gSavedSettings.getString("nick01")); - childSetValue("nick02", gSavedSettings.getString("nick02")); - childSetValue("nick03", gSavedSettings.getString("nick03")); - refresh(); return TRUE; @@ -147,24 +138,6 @@ void LLPrefsAdvanced::apply() gSavedSettings.setU32("LightShareAllowed", (U32)childGetValue("lightshare_combo").asInteger()); - gSavedSettings.setBOOL("HighlightOwnNameInIM", childGetValue("HighlightOwnNameInIM")); - gSavedSettings.setBOOL("HighlightFriendsChat", childGetValue("HighlightFriendsChat")); - gSavedSettings.setColor4("FriendsChatColor", getChild<LLColorSwatchCtrl>("FriendsChatColor")->get()); - gSavedSettings.setBOOL("HighlightOwnNameInChat", childGetValue("HighlightOwnNameInChat")); - gSavedSettings.setColor4("OwnNameChatColor", getChild<LLColorSwatchCtrl>("OwnNameChatColor")->get()); - - std::string nick01 = childGetValue("nick01"); - boost::trim(nick01); - gSavedSettings.setString("nick01", nick01); - - std::string nick02 = childGetValue("nick02"); - boost::trim(nick02); - gSavedSettings.setString("nick02", nick02); - - std::string nick03 = childGetValue("nick03"); - boost::trim(nick03); - gSavedSettings.setString("nick03", nick03); - // Need to force a rebake when ClothingLayerProtection toggled for it take effect -- MC if (gSavedSettings.getBOOL("ShowMyClientTagToOthers") != (BOOL)childGetValue("client_name_tag_broadcast_check")) { diff --git a/linden/indra/newview/llprefschat.cpp b/linden/indra/newview/llprefschat.cpp index 8d704d5a3..5f74a2511 100644 --- a/linden/indra/newview/llprefschat.cpp +++ b/linden/indra/newview/llprefschat.cpp @@ -36,10 +36,8 @@ #include "llchatbar.h" #include "llfloaterchat.h" #include "llprefschat.h" -#include "lltexteditor.h" #include "llviewercontrol.h" #include "lluictrlfactory.h" -#include "llcolorswatch.h" #include "llradiogroup.h" #include "llstylemap.h" @@ -57,15 +55,6 @@ class LLPrefsChatImpl : public LLPanel S32 mChatSize; F32 mChatPersist; S32 mChatMaxLines; - LLColor4 mSystemChatColor; - LLColor4 mUserChatColor; - LLColor4 mAgentChatColor; - LLColor4 mIMChatColor; - LLColor4 mObjectChatColor; - LLColor4 mOwnerSayChatColor; - LLColor4 mBGChatColor; - LLColor4 mScriptErrorColor; - LLColor4 mHTMLLinkColor; BOOL mChatFullWidth; BOOL mCloseChatOnReturn; BOOL mArrowKeysMoveAvatar; @@ -92,16 +81,6 @@ LLPrefsChatImpl::LLPrefsChatImpl() childSetValue("fade_chat_time", gSavedSettings.getF32("ChatPersistTime")); childSetValue("max_chat_count", gSavedSettings.getS32("ConsoleMaxLines")); - getChild<LLColorSwatchCtrl>("system")->set(gSavedSettings.getColor4("SystemChatColor")); - getChild<LLColorSwatchCtrl>("user")->set(gSavedSettings.getColor4("UserChatColor")); - getChild<LLColorSwatchCtrl>("agent")->set(gSavedSettings.getColor4("AgentChatColor")); - getChild<LLColorSwatchCtrl>("im")->set(gSavedSettings.getColor4("IMChatColor")); - getChild<LLColorSwatchCtrl>("script_error")->set(gSavedSettings.getColor4("ScriptErrorColor")); - getChild<LLColorSwatchCtrl>("objects")->set(gSavedSettings.getColor4("ObjectChatColor")); - getChild<LLColorSwatchCtrl>("owner")->set(gSavedSettings.getColor4("llOwnerSayChatColor")); - getChild<LLColorSwatchCtrl>("background")->set(gSavedSettings.getColor4("BackgroundChatColor")); - getChild<LLColorSwatchCtrl>("links")->set(gSavedSettings.getColor4("HTMLLinkColor")); - childSetValue("arrow_keys_move_avatar_check", gSavedSettings.getBOOL("ArrowKeysMoveAvatar")); childSetValue("show_timestamps_check", gSavedSettings.getBOOL("ChatShowTimestamps")); childSetValue("script_errors_as_chat", gSavedSettings.getBOOL("ScriptErrorsAsChat")); @@ -124,15 +103,6 @@ void LLPrefsChatImpl::refreshValues() mChatSize = gSavedSettings.getS32("ChatFontSize"); mChatPersist = gSavedSettings.getF32("ChatPersistTime"); mChatMaxLines = gSavedSettings.getS32("ConsoleMaxLines"); - mSystemChatColor = gSavedSettings.getColor4("SystemChatColor"); - mUserChatColor = gSavedSettings.getColor4("UserChatColor"); - mAgentChatColor = gSavedSettings.getColor4("AgentChatColor"); - mIMChatColor = gSavedSettings.getColor4("IMChatColor"); - mObjectChatColor = gSavedSettings.getColor4("ObjectChatColor"); - mOwnerSayChatColor = gSavedSettings.getColor4("llOwnerSayChatColor"); - mBGChatColor = gSavedSettings.getColor4("BackgroundChatColor"); - mScriptErrorColor = gSavedSettings.getColor4("ScriptErrorColor"); - mHTMLLinkColor = gSavedSettings.getColor4("HTMLLinkColor"); mArrowKeysMoveAvatar = gSavedSettings.getBOOL("ArrowKeysMoveAvatar"); mShowTimestamps = gSavedSettings.getBOOL("ChatShowTimestamps"); mScriptErrorAsChat = gSavedSettings.getBOOL("ScriptErrorsAsChat"); @@ -154,15 +124,6 @@ void LLPrefsChatImpl::cancel() gSavedSettings.setS32("ChatFontSize", mChatSize); gSavedSettings.setF32("ChatPersistTime", mChatPersist); gSavedSettings.setS32("ConsoleMaxLines", mChatMaxLines); - gSavedSettings.setColor4("SystemChatColor", mSystemChatColor); - gSavedSettings.setColor4("UserChatColor", mUserChatColor); - gSavedSettings.setColor4("AgentChatColor", mAgentChatColor); - gSavedSettings.setColor4("IMChatColor", mIMChatColor); - gSavedSettings.setColor4("ObjectChatColor", mObjectChatColor); - gSavedSettings.setColor4("llOwnerSayChatColor", mOwnerSayChatColor); - gSavedSettings.setColor4("BackgroundChatColor", mBGChatColor); - gSavedSettings.setColor4("ScriptErrorColor", mScriptErrorColor); - gSavedSettings.setColor4("HTMLLinkColor", mHTMLLinkColor); gSavedSettings.setBOOL("ArrowKeysMoveAvatar", mArrowKeysMoveAvatar); gSavedSettings.setBOOL("ChatShowTimestamps", mShowTimestamps); gSavedSettings.setBOOL("ScriptErrorsAsChat", mScriptErrorAsChat); @@ -184,18 +145,6 @@ void LLPrefsChatImpl::apply() gSavedSettings.setF32("ChatPersistTime", childGetValue("fade_chat_time").asReal()); gSavedSettings.setS32("ConsoleMaxLines", childGetValue("max_chat_count")); - gSavedSettings.setColor4("SystemChatColor", childGetValue("system")); - gSavedSettings.setColor4("UserChatColor", childGetValue("user")); - gSavedSettings.setColor4("AgentChatColor", childGetValue("agent")); - gSavedSettings.setColor4("IMChatColor", childGetValue("im")); - gSavedSettings.setColor4("ScriptErrorColor", childGetValue("script_error")); - gSavedSettings.setColor4("ObjectChatColor", childGetValue("objects")); - gSavedSettings.setColor4("llOwnerSayChatColor", childGetValue("owner")); - gSavedSettings.setColor4("BackgroundChatColor", childGetValue("background")); - - gSavedSettings.setColor4("HTMLLinkColor", childGetValue("links")); - LLTextEditor::setLinkColor(childGetValue("links")); - gSavedSettings.setBOOL("ArrowKeysMoveAvatar", childGetValue("arrow_keys_move_avatar_check")); gSavedSettings.setBOOL("ChatShowTimestamps", childGetValue("show_timestamps_check")); gSavedSettings.setBOOL("ScriptErrorsAsChat", childGetValue("script_errors_as_chat")); diff --git a/linden/indra/newview/llprefscolors.cpp b/linden/indra/newview/llprefscolors.cpp new file mode 100644 index 000000000..9a30fcdc0 --- /dev/null +++ b/linden/indra/newview/llprefscolors.cpp @@ -0,0 +1,180 @@ +/** +* @file llprefscolors.cpp +* @brief Color-specific preferences for Imprudence +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2010, McCabe Maxsted +* +* Imprudence Viewer Source Code +* The source code in this file ("Source Code") is provided to you +* under the terms of the GNU General Public License, version 2.0 +* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in +* this distribution, or online at +* http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llprefscolors.h" +#include "lltexteditor.h" +#include "llviewercontrol.h" + +#include "lluictrlfactory.h" +#include "llcolorswatch.h" + +#include "boost/algorithm/string.hpp" + +LLPrefsColors::LLPrefsColors() +{ + refreshColors(); // initialize member data from saved settings + + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_colors.xml"); +} + +LLPrefsColors::~LLPrefsColors() +{ + // Children all cleaned up by default view destructor. +} + +BOOL LLPrefsColors::postBuild() +{ + getChild<LLColorSwatchCtrl>("system")->set(gSavedSettings.getColor4("SystemChatColor")); + getChild<LLColorSwatchCtrl>("user")->set(gSavedSettings.getColor4("UserChatColor")); + getChild<LLColorSwatchCtrl>("agent")->set(gSavedSettings.getColor4("AgentChatColor")); + getChild<LLColorSwatchCtrl>("im")->set(gSavedSettings.getColor4("IMChatColor")); + getChild<LLColorSwatchCtrl>("script_error")->set(gSavedSettings.getColor4("ScriptErrorColor")); + getChild<LLColorSwatchCtrl>("objects")->set(gSavedSettings.getColor4("ObjectChatColor")); + getChild<LLColorSwatchCtrl>("owner")->set(gSavedSettings.getColor4("llOwnerSayChatColor")); + getChild<LLColorSwatchCtrl>("background")->set(gSavedSettings.getColor4("BackgroundChatColor")); + getChild<LLColorSwatchCtrl>("links")->set(gSavedSettings.getColor4("HTMLLinkColor")); + getChild<LLColorSwatchCtrl>("FriendsChatColor")->set(gSavedSettings.getColor4("FriendsChatColor")); + getChild<LLColorSwatchCtrl>("OwnNameChatColor")->set(gSavedSettings.getColor4("OwnNameChatColor")); + + childSetValue("HighlightOwnNameInIM", gSavedSettings.getBOOL("HighlightOwnNameInIM")); + childSetValue("HighlightFriendsChat", gSavedSettings.getBOOL("HighlightFriendsChat")); + childSetValue("HighlightOwnNameInChat", gSavedSettings.getBOOL("HighlightOwnNameInChat")); + updateSelfCheck(); + updateFriendsCheck(); + + childSetValue("nick01", gSavedSettings.getString("nick01")); + childSetValue("nick02", gSavedSettings.getString("nick02")); + childSetValue("nick03", gSavedSettings.getString("nick03")); + + childSetCommitCallback("HighlightOwnNameInIM", onCommitCheckSelfName, this); + childSetCommitCallback("HighlightOwnNameInChat", onCommitCheckSelfName, this); + childSetCommitCallback("HighlightFriendsChat", onCommitCheckFriends, this); + + return TRUE; +} + +void LLPrefsColors::refreshColors() +{ + mSystemChatColor = gSavedSettings.getColor4("SystemChatColor"); + mUserChatColor = gSavedSettings.getColor4("UserChatColor"); + mAgentChatColor = gSavedSettings.getColor4("AgentChatColor"); + mIMChatColor = gSavedSettings.getColor4("IMChatColor"); + mObjectChatColor = gSavedSettings.getColor4("ObjectChatColor"); + mOwnerSayChatColor = gSavedSettings.getColor4("llOwnerSayChatColor"); + mBGChatColor = gSavedSettings.getColor4("BackgroundChatColor"); + mScriptErrorColor = gSavedSettings.getColor4("ScriptErrorColor"); + mHTMLLinkColor = gSavedSettings.getColor4("HTMLLinkColor"); + mFriendsChatColor = gSavedSettings.getColor4("FriendsChatColor"); + mOwnNameChatColor = gSavedSettings.getColor4("OwnNameChatColor"); +} + +// static +void LLPrefsColors::onCommitCheckSelfName(LLUICtrl* ctrl, void* userdata) +{ + LLPrefsColors* self = (LLPrefsColors*)userdata; + self->updateSelfCheck(); +} + +void LLPrefsColors::updateSelfCheck() +{ + bool highlight_names_enabled = (childGetValue("HighlightOwnNameInIM") || childGetValue("HighlightOwnNameInChat")); + + getChild<LLColorSwatchCtrl>("OwnNameChatColor")->setEnabled(highlight_names_enabled); + childSetEnabled("nick01", highlight_names_enabled); + childSetEnabled("nick02", highlight_names_enabled); + childSetEnabled("nick03", highlight_names_enabled); + childSetEnabled("nick01_text", highlight_names_enabled); + childSetEnabled("nick02_text", highlight_names_enabled); + childSetEnabled("nick03_text", highlight_names_enabled); +} + +// static +void LLPrefsColors::onCommitCheckFriends(LLUICtrl* ctrl, void* userdata) +{ + LLPrefsColors* self = (LLPrefsColors*)userdata; + self->updateFriendsCheck(); +} + +void LLPrefsColors::updateFriendsCheck() +{ + getChild<LLColorSwatchCtrl>("FriendsChatColor")->setEnabled(childGetValue("HighlightFriendsChat")); +} + +void LLPrefsColors::cancel() +{ + gSavedSettings.setColor4("SystemChatColor", mSystemChatColor); + gSavedSettings.setColor4("UserChatColor", mUserChatColor); + gSavedSettings.setColor4("AgentChatColor", mAgentChatColor); + gSavedSettings.setColor4("IMChatColor", mIMChatColor); + gSavedSettings.setColor4("ObjectChatColor", mObjectChatColor); + gSavedSettings.setColor4("llOwnerSayChatColor", mOwnerSayChatColor); + gSavedSettings.setColor4("BackgroundChatColor", mBGChatColor); + gSavedSettings.setColor4("ScriptErrorColor", mScriptErrorColor); + gSavedSettings.setColor4("HTMLLinkColor", mHTMLLinkColor); + gSavedSettings.setColor4("FriendsChatColor", mFriendsChatColor); + gSavedSettings.setColor4("OwnNameChatColor", mOwnNameChatColor); +} + +void LLPrefsColors::apply() +{ + gSavedSettings.setColor4("SystemChatColor", childGetValue("system")); + gSavedSettings.setColor4("UserChatColor", childGetValue("user")); + gSavedSettings.setColor4("AgentChatColor", childGetValue("agent")); + gSavedSettings.setColor4("IMChatColor", childGetValue("im")); + gSavedSettings.setColor4("ScriptErrorColor", childGetValue("script_error")); + gSavedSettings.setColor4("ObjectChatColor", childGetValue("objects")); + gSavedSettings.setColor4("llOwnerSayChatColor", childGetValue("owner")); + gSavedSettings.setColor4("BackgroundChatColor", childGetValue("background")); + + gSavedSettings.setColor4("HTMLLinkColor", childGetValue("links")); + LLTextEditor::setLinkColor(childGetValue("links")); + + gSavedSettings.setBOOL("HighlightOwnNameInIM", childGetValue("HighlightOwnNameInIM")); + gSavedSettings.setBOOL("HighlightFriendsChat", childGetValue("HighlightFriendsChat")); + gSavedSettings.setColor4("FriendsChatColor", getChild<LLColorSwatchCtrl>("FriendsChatColor")->get()); + gSavedSettings.setBOOL("HighlightOwnNameInChat", childGetValue("HighlightOwnNameInChat")); + gSavedSettings.setColor4("OwnNameChatColor", getChild<LLColorSwatchCtrl>("OwnNameChatColor")->get()); + + std::string nick01 = childGetValue("nick01"); + boost::trim(nick01); + gSavedSettings.setString("nick01", nick01); + + std::string nick02 = childGetValue("nick02"); + boost::trim(nick02); + gSavedSettings.setString("nick02", nick02); + + std::string nick03 = childGetValue("nick03"); + boost::trim(nick03); + gSavedSettings.setString("nick03", nick03); + + refreshColors(); // member values become the official values and cancel becomes a no-op. +} diff --git a/linden/indra/newview/llprefscolors.h b/linden/indra/newview/llprefscolors.h new file mode 100644 index 000000000..70bda8977 --- /dev/null +++ b/linden/indra/newview/llprefscolors.h @@ -0,0 +1,67 @@ +/** +* @file llprefscolors.h +* @brief Advanced preferences options for Imprudence +* +* $LicenseInfo:firstyear=2009&license=viewergpl$ +* +* Copyright (c) 2010, McCabe Maxsted +* +* Imprudence Viewer Source Code +* The source code in this file ("Source Code") is provided to you +* under the terms of the GNU General Public License, version 2.0 +* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in +* this distribution, or online at +* http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#ifndef LLPREFSCOLORS_H +#define LLPREFSCOLORS_H + +#include "llpanel.h" + +class LLPrefsColors : public LLPanel +{ +public: + LLPrefsColors(); + ~LLPrefsColors(); + + BOOL postBuild(); + + void apply(); + void cancel(); + +private: + static void onCommitCheckSelfName(LLUICtrl* ctrl, void* userdata); + static void onCommitCheckFriends(LLUICtrl* ctrl, void* userdata); + void refreshColors(); + void updateFriendsCheck(); + void updateSelfCheck(); + + LLColor4 mSystemChatColor; + LLColor4 mUserChatColor; + LLColor4 mAgentChatColor; + LLColor4 mIMChatColor; + LLColor4 mObjectChatColor; + LLColor4 mOwnerSayChatColor; + LLColor4 mBGChatColor; + LLColor4 mScriptErrorColor; + LLColor4 mHTMLLinkColor; + LLColor4 mFriendsChatColor; + LLColor4 mOwnNameChatColor; +}; + +#endif //LLPREFSCOLORS_H diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml index 0f2181bab..1b771b5c4 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml @@ -179,57 +179,6 @@ To use spellcheck, right-click a misspelled word tool_tip="Modify the AutoCorrect word list and settings" left="12" bottom_delta="-50" width="180" height="20" font="SansSerifSmall" follows="left|top"/> </panel> - - <panel border="true" bottom="-580" follows="left|top|right|bottom" height="525" label="Extra" - left="1" mouse_opaque="true" name="Extra" width="418"> - - <check_box bottom_delta="-30" enabled="true" follows="left|top" font="SansSerifSmall" height="16" - initial_value="true" label="Show chat messages from friends in a different color" left="12" - mouse_opaque="true" name="HighlightFriendsChat" radio_style="false" width="270"/> - - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-100" - can_apply_immediately="true" color="1 1 1 1" control_name="FriendsChatColor" - enabled="true" follows="left|top" height="67" label="Friends" left_delta="68" - mouse_opaque="true" name="FriendsChatColor" width="65" /> - - <check_box bottom_delta="-30" enabled="true" follows="left|top" - font="SansSerifSmall" height="16" initial_value="true" - label="Show chat messages containing your name in a different color" left="12" mouse_opaque="true" - name="HighlightOwnNameInChat" radio_style="false" width="217" /> - - <check_box bottom_delta="-30" enabled="true" follows="left|top" font="SansSerifSmall" height="16" - initial_value="true" label="Show GroupIM messages containing your name in a different color" left="12" - mouse_opaque="true" name="HighlightOwnNameInIM" radio_style="false" width="270"/> - - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-230" - can_apply_immediately="true" color="1 1 1 1" control_name="OwnNameChatColor" - enabled="true" follows="left|top" height="67" label="Own Name" left_delta="68" - mouse_opaque="true" name="OwnNameChatColor" width="65" /> - - <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-50" - enabled="true" follows="left|top" font="SansSerif" - handle_edit_keys_directly="true" height="20" left_delta="0" - max_length="50" mouse_opaque="true" name="nick01" - select_all_on_focus_received="true" width="400" word_wrap="false" /> - <text bottom_delta="-3" follows="left|top" font="SansSerifSmall" height="20" left="20" name="nick01_text" width="70">Nick 1</text> - - <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-30" - enabled="true" follows="left|top" font="SansSerif" - handle_edit_keys_directly="true" height="20" left_delta="60" - max_length="50" mouse_opaque="true" name="nick02" - select_all_on_focus_received="true" width="400" word_wrap="false" /> - - <text bottom_delta="-3" follows="left|top" font="SansSerifSmall" height="20" left="20" name="nick02_text" width="70">Nick 2</text> - - <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-30" - enabled="true" follows="left|top" font="SansSerif" - handle_edit_keys_directly="true" height="20" left_delta="60" - max_length="50" mouse_opaque="true" name="nick03" - select_all_on_focus_received="true" width="400" word_wrap="false" /> - - <text bottom_delta="-3" follows="left|top" font="SansSerifSmall" height="20" left="20" name="nick03_text" width="70">Nick 3</text> - - </panel> </tab_container> </panel> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml index fe6020393..27d3fa459 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml @@ -24,60 +24,84 @@ Large </radio_item> </radio_group> + + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-40" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" + mouse_opaque="false" name="text_translate_chat" v_pad="0" width="128"> + Translate Chat: + </text> + <check_box bottom_delta="-3" control_name="TranslateChat" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="false" + label="Use machine translation while chatting (powered by Google)" left="148" mouse_opaque="true" + name="translate_chat" radio_style="false" width="237" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-16" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="10" left="149" + mouse_opaque="false" name="text_translate_chat" v_pad="0" width="160"> + Translate into this language: + </text> + <combo_box allow_text_entry="true" bottom_delta="-5" enabled="true" + follows="left|top" height="16" left_delta="183" max_chars="135" + mouse_opaque="true" name="translate_language_combobox" width="146"> + <combo_item type="string" length="1" enabled="true" name="System Default Language" value="default"> + System Default + </combo_item> + <combo_item type="string" length="1" enabled="true" name="English" value="en"> + English + </combo_item> + + <!-- After "System Default" and "English", please keep the rest of these combo_items in alphabetical order by the first character in the string. --> + + <combo_item type="string" length="1" enabled="true" name="Danish" value="da"> + Dansk (Danish) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Deutsch(German)" value="de"> + Deutsch (German) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Spanish" value="es"> + Español (Spanish) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="French" value="fr"> + Français (French) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Italian" value="it"> + Italiano (Italian) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Hungarian" value="hu"> + Magyar (Hungarian) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Dutch" value="nl"> + Nederlands (Dutch) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Polish" value="pl"> + Polski (Polish) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Portugese" value="pt"> + Portugués (Portuguese) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Russian" value="ru"> + РуÑÑкий (Russian) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Turkish" value="tr"> + Türkçe (Turkish) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Ukrainian" value="uk"> + УкраїнÑька (Ukrainian) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Chinese" value="zh"> + 中文 (简体) (Chinese) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="(Japanese)" value="ja"> + 日本語 (Japanese) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="(Korean)" value="ko"> + 한국어 (Korean) + </combo_item> + </combo_box> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-64" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" - mouse_opaque="false" name="text_box2" v_pad="0" width="128"> - Color: - </text> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-108" - can_apply_immediately="true" color="1 1 1 1" control_name="UserChatColor" - enabled="true" follows="left|top" height="56" label="You" left="148" - mouse_opaque="true" name="user" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-108" - can_apply_immediately="true" color="1 1 1 1" control_name="AgentChatColor" - enabled="true" follows="left|top" height="56" label="Others" left_delta="68" - mouse_opaque="true" name="agent" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-108" - can_apply_immediately="true" color="0.6 0.6 1 1" - enabled="true" follows="left|top" height="56" label="IMs" left_delta="68" - mouse_opaque="true" name="im" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-108" - can_apply_immediately="true" color="0.8 1 1 1" - enabled="true" follows="left|top" - height="56" label="System" left_delta="68" mouse_opaque="true" - name="system" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-108" - can_apply_immediately="true" color="0.82 0.82 0.99 1" - control_name="ScriptErrorColor" enabled="true" follows="left|top" - height="56" label="Errors" left_delta="68" mouse_opaque="true" - name="script_error" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-165" - can_apply_immediately="true" color="0.7 0.9 0.7 1" - control_name="ObjectChatColor" enabled="true" follows="left|top" - height="56" label="Objects" left="148" mouse_opaque="true" - name="objects" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-165" - can_apply_immediately="true" color="0.7 0.9 0.7 1" - control_name="ObjectIMColor" enabled="true" follows="left|top" - height="56" label="Object IMs" left_delta="68" mouse_opaque="true" - name="object_ims" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-165" - can_apply_immediately="true" color="0.7 0.9 0.7 1" - enabled="true" follows="left|top" - height="56" label="Owner" left_delta="68" mouse_opaque="true" name="owner" - width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-165" - can_apply_immediately="true" color="0 0 0 1" - enabled="true" follows="left|top" - height="56" label="Bubble" left_delta="68" mouse_opaque="true" - name="background" width="54" /> - <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-165" - can_apply_immediately="true" color="0.6 0.6 1 1" - enabled="true" follows="left|top" height="56" - label="URLs" left_delta="68" mouse_opaque="true" name="links" width="54" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-25" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom_delta="-40" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" mouse_opaque="false" name="text_box3" v_pad="0" width="135"> Chat Console: @@ -115,8 +139,29 @@ label="Use full screen width (requires restart)" left="148" mouse_opaque="true" name="chat_full_width_check" radio_style="false" width="239" /> + + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-40" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" + mouse_opaque="false" name="text_box7" v_pad="0" width="128"> + Chat Bubbles: + </text> + <check_box bottom_delta="-8" control_name="UseChatBubbles" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="false" + label="Show chat bubbles" left="148" mouse_opaque="true" + name="bubble_text_chat" radio_style="false" width="237" /> + <check_box bottom_delta="-0" control_name="UseLocalChatBubbles" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="false" + label="Show local chat and bubbles" left="288" mouse_opaque="true" + name="local_bubble_text_chat" radio_style="false" width="237" /> + <slider bottom_delta="-20" can_edit_text="false" control_name="ChatBubbleOpacity" + decimal_digits="3" enabled="true" follows="left|top" height="12" + increment="0.05" initial_val="1" label="Bubble opacity:" left="148" max_val="1" + min_val="0" mouse_opaque="true" name="bubble_chat_opacity" show_text="true" + value="0.5" width="225" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" + bottom_delta="-40" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" mouse_opaque="false" name="text_box6" v_pad="0" width="135"> Miscellaneous: @@ -147,98 +192,5 @@ font="SansSerifSmall" height="16" initial_value="false" label="Show custom chat channel" left="148" mouse_opaque="true" name="toggle_channel_control" radio_style="false" width="237" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-379" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" - mouse_opaque="false" name="text_box7" v_pad="0" width="128"> - Chat Bubbles: - </text> - <check_box bottom="-386" control_name="UseChatBubbles" enabled="true" follows="left|top" - font="SansSerifSmall" height="16" initial_value="false" - label="Show chat bubbles" left="148" mouse_opaque="true" - name="bubble_text_chat" radio_style="false" width="237" /> - <check_box bottom="-386" control_name="UseLocalChatBubbles" enabled="true" follows="left|top" - font="SansSerifSmall" height="16" initial_value="false" - label="Show local chat and bubbles" left="288" mouse_opaque="true" - name="local_bubble_text_chat" radio_style="false" width="237" /> - <slider bottom="-402" can_edit_text="false" control_name="ChatBubbleOpacity" - decimal_digits="3" enabled="true" follows="left|top" height="12" - increment="0.05" initial_val="1" label="Bubble opacity:" left="148" max_val="1" - min_val="0" mouse_opaque="true" name="bubble_chat_opacity" show_text="true" - value="0.5" width="225" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-420" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" - mouse_opaque="false" name="text_translate_chat" v_pad="0" width="128"> - Translate Chat: - </text> - <check_box bottom="-427" control_name="TranslateChat" enabled="true" follows="left|top" - font="SansSerifSmall" height="16" initial_value="false" - label="Use machine translation while chatting (powered by Google)" left="148" mouse_opaque="true" - name="translate_chat" radio_style="false" width="237" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-442" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="10" left="149" - mouse_opaque="false" name="text_translate_chat" v_pad="0" width="160"> - Translate into this language: - </text> - <combo_box allow_text_entry="true" bottom="-448" enabled="true" - follows="left|top" height="16" left_delta="183" max_chars="135" - mouse_opaque="true" name="translate_language_combobox" width="146"> - <combo_item type="string" length="1" enabled="true" name="System Default Language" value="default"> - System Default - </combo_item> - <combo_item type="string" length="1" enabled="true" name="English" value="en"> - English - </combo_item> - - <!-- After "System Default" and "English", please keep the rest of these combo_items in alphabetical order by the first character in the string. --> - - <combo_item type="string" length="1" enabled="true" name="Danish" value="da"> - Dansk (Danish) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Deutsch(German)" value="de"> - Deutsch (German) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Spanish" value="es"> - Español (Spanish) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="French" value="fr"> - Français (French) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Italian" value="it"> - Italiano (Italian) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Hungarian" value="hu"> - Magyar (Hungarian) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Dutch" value="nl"> - Nederlands (Dutch) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Polish" value="pl"> - Polski (Polish) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Portugese" value="pt"> - Portugués (Portuguese) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Russian" value="ru"> - РуÑÑкий (Russian) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Turkish" value="tr"> - Türkçe (Turkish) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Ukrainian" value="uk"> - УкраїнÑька (Ukrainian) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="Chinese" value="zh"> - 中文 (简体) (Chinese) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="(Japanese)" value="ja"> - 日本語 (Japanese) - </combo_item> - <combo_item type="string" length="1" enabled="true" name="(Korean)" value="ko"> - 한국어 (Korean) - </combo_item> - </combo_box> </panel> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml new file mode 100644 index 000000000..11810d2e3 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" + height="408" label="Colors" left="102" mouse_opaque="true" name="colors" + width="517"> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" + mouse_opaque="false" name="text_box2" v_pad="0" width="128"> + Chat Colors: + </text> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-75" + can_apply_immediately="true" color="1 1 1 1" control_name="UserChatColor" + enabled="true" follows="left|top" height="65" label="Your chat" left="120" + mouse_opaque="true" name="user" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-75" + can_apply_immediately="true" color="1 1 1 1" control_name="AgentChatColor" + enabled="true" follows="left|top" height="65" label="Others' chat" left_delta="76" + mouse_opaque="true" name="agent" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-75" + can_apply_immediately="true" color="0.6 0.6 1 1" + enabled="true" follows="left|top" height="65" label="IMs" left_delta="76" + mouse_opaque="true" name="im" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-75" + can_apply_immediately="true" color="0.8 1 1 1" + enabled="true" follows="left|top" + height="65" label="System" left_delta="76" mouse_opaque="true" + name="system" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-75" + can_apply_immediately="true" color="0.82 0.82 0.99 1" + control_name="ScriptErrorColor" enabled="true" follows="left|top" + height="65" label="Script errors" left_delta="76" mouse_opaque="true" + name="script_error" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-146" + can_apply_immediately="true" color="0.7 0.9 0.7 1" + control_name="ObjectChatColor" enabled="true" follows="left|top" + height="65" label="Object chat" left="120" mouse_opaque="true" + name="objects" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-146" + can_apply_immediately="true" color="0.7 0.9 0.7 1" + control_name="ObjectIMColor" enabled="true" follows="left|top" + height="65" label="Object IMs" left_delta="76" mouse_opaque="true" + name="object_ims" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-146" + can_apply_immediately="true" color="0.7 0.9 0.7 1" + enabled="true" follows="left|top" + height="65" label="Owner chat" left_delta="76" mouse_opaque="true" name="owner" + width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-146" + can_apply_immediately="true" color="0 0 0 1" + enabled="true" follows="left|top" + height="65" label="Bubble chat" left_delta="76" mouse_opaque="true" + name="background" width="65" /> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-146" + can_apply_immediately="true" color="0.6 0.6 1 1" + enabled="true" follows="left|top" height="65" + label="Links" left_delta="76" mouse_opaque="true" name="links" width="65" /> + + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-30" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="10" left="12" + mouse_opaque="false" name="text_box3" v_pad="0" width="128"> + Line Highlighting: + </text> + + <check_box bottom_delta="-7" enabled="true" follows="left|top" font="SansSerifSmall" height="16" + initial_value="true" label="Highlight chat from friends" left="120" + mouse_opaque="true" name="HighlightFriendsChat" radio_style="false" width="270"/> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom_delta="-70" + can_apply_immediately="true" color="1 1 1 1" control_name="FriendsChatColor" + enabled="true" follows="left|top" height="65" label="Friends" left_delta="20" + mouse_opaque="true" name="FriendsChatColor" width="65" /> + + <check_box bottom_delta="-25" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="true" + label="Highlight local chat containing your name" left="120" mouse_opaque="true" + name="HighlightOwnNameInChat" radio_style="false" width="217" /> + <check_box bottom_delta="-20" enabled="true" follows="left|top" font="SansSerifSmall" height="16" + initial_value="true" label="Highlight group chat containing your name" left_delta="0" + mouse_opaque="true" name="HighlightOwnNameInIM" radio_style="false" width="270"/> + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom_delta="-70" + can_apply_immediately="true" color="1 1 1 1" control_name="OwnNameChatColor" + enabled="true" follows="left|top" height="65" label="Your name" left_delta="20" + mouse_opaque="true" name="OwnNameChatColor" width="65" /> + + <text bottom_delta="-30" follows="left|top" font="SansSerifSmall" height="20" + left="140" name="nick01_text" width="150"> + Highlight nickname 1: + </text> + <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="3" + enabled="true" follows="left|top" font="SansSerif" + handle_edit_keys_directly="true" height="20" left_delta="125" + max_length="50" mouse_opaque="true" name="nick01" + select_all_on_focus_received="true" width="160" word_wrap="false" /> + + <text bottom_delta="-25" follows="left|top" font="SansSerifSmall" height="20" + left="140" name="nick02_text" width="150"> + Highlight nickname 2: + </text> + <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="3" + enabled="true" follows="left|top" font="SansSerif" + handle_edit_keys_directly="true" height="20" left_delta="125" + max_length="50" mouse_opaque="true" name="nick02" + select_all_on_focus_received="true" width="160" word_wrap="false" /> + + <text bottom_delta="-25" follows="left|top" font="SansSerifSmall" height="20" + left="140" name="nick03_text" width="150"> + Highlight nickname 3: + </text> + <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="3" + enabled="true" follows="left|top" font="SansSerif" + handle_edit_keys_directly="true" height="20" left_delta="125" + max_length="50" mouse_opaque="true" name="nick03" + select_all_on_focus_received="true" width="160" word_wrap="false" /> + +</panel> From 9a72dc956425d74faacfd077c92198694a8f6e65 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 17:13:51 -0700 Subject: [PATCH 145/239] Renamed several preferences panels: * Text Chat -> Chat * Voice Chat -> Voice * Communication -> IMs & Logging * Colors -> Chat Colors --- .../newview/skins/default/xui/en-us/panel_preferences_chat.xml | 2 +- .../skins/default/xui/en-us/panel_preferences_colors.xml | 2 +- .../newview/skins/default/xui/en-us/panel_preferences_im.xml | 2 +- .../newview/skins/default/xui/en-us/panel_preferences_voice.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml index 27d3fa459..9ead3bf45 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_chat.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" - height="408" label="Text Chat" left="102" mouse_opaque="true" name="chat" + height="408" label="Chat" left="102" mouse_opaque="true" name="chat" width="517"> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top" diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml index 11810d2e3..40a75a6ca 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_colors.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" - height="408" label="Colors" left="102" mouse_opaque="true" name="colors" + height="408" label="Chat Colors" left="102" mouse_opaque="true" name="colors" width="517"> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top" diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml index bb5002b0d..e64f6c76b 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" - height="408" label="Communication" left="102" mouse_opaque="true" name="im" + height="408" label="IMs & Logging" left="102" mouse_opaque="true" name="im" width="517"> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top" diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_voice.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_voice.xml index fc9b6cde8..b4939cae1 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_voice.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_voice.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" - height="408" label="Voice Chat" left="102" mouse_opaque="true" name="chat" + height="408" label="Voice" left="102" mouse_opaque="true" name="chat" width="517"> <text_editor type="string" length="1" allow_html="false" bg_readonly_color="0 0 0 0" bottom_delta="-26" embedded_items="false" enabled="false" follows="left|top" From cff602ecc9984ccd973f6bfe3521ceb0a1270b31 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 17:17:56 -0700 Subject: [PATCH 146/239] Changed the order of the chat/im/voice preferences panels to include chat colors more logically --- linden/indra/newview/llfloaterpreference.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp index 906cf1194..2fe4b4d98 100644 --- a/linden/indra/newview/llfloaterpreference.cpp +++ b/linden/indra/newview/llfloaterpreference.cpp @@ -167,13 +167,18 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def mTabContainer->addTabPanel(mPrefsChat->getPanel(), mPrefsChat->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer); mPrefsChat->getPanel()->setDefaultBtn(default_btn); - mPrefsVoice = new LLPrefsVoice(); - mTabContainer->addTabPanel(mPrefsVoice, mPrefsVoice->getLabel(), FALSE, onTabChanged, mTabContainer); - mPrefsVoice->setDefaultBtn(default_btn); + mPrefsColors = new LLPrefsColors(); + mTabContainer->addTabPanel(mPrefsColors, mPrefsColors->getLabel(), FALSE, onTabChanged, mTabContainer); + mPrefsColors->setDefaultBtn(default_btn); mPrefsIM = new LLPrefsIM(); mTabContainer->addTabPanel(mPrefsIM->getPanel(), mPrefsIM->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer); mPrefsIM->getPanel()->setDefaultBtn(default_btn); + + mPrefsVoice = new LLPrefsVoice(); + mTabContainer->addTabPanel(mPrefsVoice, mPrefsVoice->getLabel(), FALSE, onTabChanged, mTabContainer); + mPrefsVoice->setDefaultBtn(default_btn); + #if LL_LCD_COMPILE @@ -192,10 +197,6 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def mMsgPanel = new LLPanelMsgs(); mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mMsgPanel->setDefaultBtn(default_btn); - - mPrefsColors = new LLPrefsColors(); - mTabContainer->addTabPanel(mPrefsColors, mPrefsColors->getLabel(), FALSE, onTabChanged, mTabContainer); - mPrefsColors->setDefaultBtn(default_btn); mSkinsPanel = new LLPanelSkins(); mTabContainer->addTabPanel(mSkinsPanel, mSkinsPanel->getLabel(), FALSE, onTabChanged, mTabContainer); From 1d56536c7e479fb4a2fe5e52b2877bda80274a7c Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 17:22:42 -0700 Subject: [PATCH 147/239] Rebranded 'Help' button in preferences to 'Support' and made it point to the Imprudence support page --- .../newview/skins/default/xui/en-us/floater_preferences.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_preferences.xml b/linden/indra/newview/skins/default/xui/en-us/floater_preferences.xml index 5b42e9ff3..939a8773f 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_preferences.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_preferences.xml @@ -16,9 +16,9 @@ width="90" /> <button bottom="-505" enabled="true" follows="left|bottom" font="SansSerif" halign="center" height="20" - help_url="http://secondlife.com/app/help/technical/preferences.php" - label="Help" label_selected="Help" left="9" mouse_opaque="true" - name="Help" scale_image="true" width="90" /> + help_url="http://support.imprudenceviewer.org/" + label="Support" left="9" mouse_opaque="true" + name="Support" scale_image="true" width="100" /> <tab_container bottom="-476" enabled="true" follows="left|top|right|bottom" height="455" left="0" mouse_opaque="false" name="pref core" tab_group="1" tab_position="left" tab_width="120" width="620" /> From e9a57e643407fac9b9a9d0621560a8148e1ecef9 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 17:24:27 -0700 Subject: [PATCH 148/239] Removed unused 'remember password' option that snuck into the Prefs > General tab. This will be handled by the login manager --- .../default/xui/en-us/panel_preferences_general.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml index b47794bf0..edd6febd6 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml @@ -181,16 +181,6 @@ v_pad="0" width="400"> (requires restart for full effect) </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="18" left="10" - mouse_opaque="true" name="remember_password_text" v_pad="0" width="394"> - Remember Password: - </text> - <check_box bottom_delta="0" follows="left|top" - font="SansSerifSmall" height="16" initial_value="false" - label="Remember Password" left="151" mouse_opaque="true" - name="remember_password" radio_style="false" width="256" /> <string name="region_name_prompt"> <Type region name> </string> From f3128be3a551cb4a3e2b78bd535a7c14c8f74fd5 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 17:29:03 -0700 Subject: [PATCH 149/239] Fixed option in Prefs > General overlapping (all this layout still needs to be redone and turned into bottom_deltas) --- .../skins/default/xui/en-us/panel_preferences_general.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml index edd6febd6..4b0b29246 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml @@ -17,7 +17,7 @@ </combo_item> </combo_box> <button name="grid_btn" label="Grid Manager" - bottom_delta="0" left="330" height="16" width="100" + bottom_delta="-3" left="330" height="20" width="100" follows="left|top" font="SansSerifSmall" halign="center" mouse_opaque="true" scale_image="TRUE" /> <check_box bottom="-44" enabled="true" follows="left|top" @@ -57,9 +57,9 @@ font="SansSerifSmall" height="16" initial_value="false" label="Hide all group titles" left="151" mouse_opaque="true" name="show_all_title_checkbox" radio_style="false" width="256" /> - <check_box bottom_delta="-18" follows="left|top" + <check_box bottom_delta="0" follows="left|top" font="SansSerifSmall" height="16" initial_value="false" - label="Hide my group title" left="151" name="show_my_title_checkbox" + label="Hide my group title" left="330" name="show_my_title_checkbox" radio_style="false" width="256" /> <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-210" can_apply_immediately="false" color="1 1 1 1" From fcaa1ae46884524c2e01af55804754b28544acfb Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 17:32:41 -0700 Subject: [PATCH 150/239] Changed nickname highlight nick settings from 'nick#' to 'HighlightNickname#' to match the rest of settings.xml. Nicknames set before this commit will need to be set again due to the new preferences name --- linden/indra/newview/app_settings/settings.xml | 6 +++--- linden/indra/newview/llprefscolors.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index ccee51392..22e4aa5e7 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -6,7 +6,7 @@ <!-- begin name highlighting --> - <key>nick01</key> + <key>HighlightNickname01</key> <map> <key>Comment</key> <string>First Nickname for Chat Highlight</string> @@ -17,7 +17,7 @@ <key>Value</key> <string></string> </map> - <key>nick02</key> + <key>HighlightNickname02</key> <map> <key>Comment</key> <string>Second Nickname for Chat Highlight</string> @@ -28,7 +28,7 @@ <key>Value</key> <string></string> </map> - <key>nick03</key> + <key>HighlightNickname03</key> <map> <key>Comment</key> <string>Third Nickname for Chat Highlight</string> diff --git a/linden/indra/newview/llprefscolors.cpp b/linden/indra/newview/llprefscolors.cpp index 9a30fcdc0..36e98a4d5 100644 --- a/linden/indra/newview/llprefscolors.cpp +++ b/linden/indra/newview/llprefscolors.cpp @@ -71,9 +71,9 @@ BOOL LLPrefsColors::postBuild() updateSelfCheck(); updateFriendsCheck(); - childSetValue("nick01", gSavedSettings.getString("nick01")); - childSetValue("nick02", gSavedSettings.getString("nick02")); - childSetValue("nick03", gSavedSettings.getString("nick03")); + childSetValue("nick01", gSavedSettings.getString("HighlightNickname01")); + childSetValue("nick02", gSavedSettings.getString("HighlightNickname02")); + childSetValue("nick03", gSavedSettings.getString("HighlightNickname03")); childSetCommitCallback("HighlightOwnNameInIM", onCommitCheckSelfName, this); childSetCommitCallback("HighlightOwnNameInChat", onCommitCheckSelfName, this); @@ -166,15 +166,15 @@ void LLPrefsColors::apply() std::string nick01 = childGetValue("nick01"); boost::trim(nick01); - gSavedSettings.setString("nick01", nick01); + gSavedSettings.setString("HighlightNickname01", nick01); std::string nick02 = childGetValue("nick02"); boost::trim(nick02); - gSavedSettings.setString("nick02", nick02); + gSavedSettings.setString("HighlightNickname02", nick02); std::string nick03 = childGetValue("nick03"); boost::trim(nick03); - gSavedSettings.setString("nick03", nick03); + gSavedSettings.setString("HighlightNickname03", nick03); refreshColors(); // member values become the official values and cancel becomes a no-op. } From 97109546d8cb92fe5ddb20cd4b8e2aafe175c2b9 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Sat, 6 Nov 2010 01:42:16 +0100 Subject: [PATCH 151/239] fix: don't use untested libraries --- linden/indra/newview/viewer_manifest.py | 2 +- linden/install.xml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index e0f08b21e..41495ca01 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -1087,7 +1087,7 @@ def construct(self): self.path("libuuid.so", "libuuid.so.1") self.path("libSDL-1.2.so.0") self.path("libELFIO.so") - self.path("libjpeg.so.62") + self.path("libjpeg.so.7") self.path("libpng12.so.0") self.path("libopenjpeg.so.2") self.path("libxml2.so.2") diff --git a/linden/install.xml b/linden/install.xml index a6a467012..fbb269a57 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -794,10 +794,10 @@ cairo: Copyright © 2002 University of Southern California, Copyright © 2005 Re </map> <key>linux64</key> <map> - <key>md5sum</key> - <string>8b5f413bdefec7cfe3d9ad2d69986bdc</string> + <key>md5sum</key> + <string>64e7fa98568ef52b3b9d4a18b3515090</string> <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/jpeglib-6b-linux64-20101012.tar.bz2</uri> + <uri>http://imprudenceviewer.org/download/libs/jpeglib-7-linux64-20091230.tar.bz2</uri> </map> <key>windows</key> <map> @@ -1048,12 +1048,12 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-qt4.6-20100923.tar.bz2</uri> </map> <key>linux64</key> - <map> - <key>md5sum</key> - <string>863f7b31556b1d368651f85457f4e46d</string> - <key>url</key> - <uri>http://imprudenceviewer.org/download/libs/llqtwebkit-linux64-20101012.1.tar.bz2</uri> - </map> + <map> + <key>md5sum</key> + <string>d5deaf897fe8effa3d3537c875060379</string> + <key>url</key> + <uri>http://imprudenceviewer.org/download/libs/llqtwebkit-linux64-20100907.tar.bz2</uri> + </map> <key>windows</key> <map> <key>md5sum</key> From 50105f88e4142ebf5e3786cd84588e2a7abbcf10 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 6 Nov 2010 03:10:09 +0200 Subject: [PATCH 152/239] Bug #681: About Land->Audio doesn't do anything Uncomment the code needed for this panel to work. This was commented out in the inital Snowglobe media plugings merge, and somehow we got that too. --- linden/indra/newview/llfloaterland.cpp | 8 ++++---- linden/indra/newview/llfloaterland.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp index 42bc41c3e..340245d34 100644 --- a/linden/indra/newview/llfloaterland.cpp +++ b/linden/indra/newview/llfloaterland.cpp @@ -209,7 +209,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this); factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this); -// factory_map["land_audio_panel"] = LLCallbackMap(createPanelLandAudio, this); + factory_map["land_audio_panel"] = LLCallbackMap(createPanelLandAudio, this); factory_map["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); factory_map["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); @@ -245,7 +245,7 @@ void LLFloaterLand::refresh() mPanelGeneral->refresh(); mPanelObjects->refresh(); mPanelOptions->refresh(); -// mPanelAudio->refresh(); + mPanelAudio->refresh(); mPanelMedia->refresh(); mPanelAccess->refresh(); } @@ -284,7 +284,7 @@ void* LLFloaterLand::createPanelLandOptions(void* data) return self->mPanelOptions; } -/* + // static void* LLFloaterLand::createPanelLandAudio(void* data) { @@ -292,7 +292,7 @@ void* LLFloaterLand::createPanelLandAudio(void* data) self->mPanelAudio = new LLPanelLandAudio(self->mParcel); return self->mPanelAudio; } -*/ + // static void* LLFloaterLand::createPanelLandMedia(void* data) { diff --git a/linden/indra/newview/llfloaterland.h b/linden/indra/newview/llfloaterland.h index 4105f4426..f8968a783 100644 --- a/linden/indra/newview/llfloaterland.h +++ b/linden/indra/newview/llfloaterland.h @@ -117,7 +117,7 @@ class LLFloaterLand LLPanelLandGeneral* mPanelGeneral; LLPanelLandObjects* mPanelObjects; LLPanelLandOptions* mPanelOptions; -// LLPanelLandAudio* mPanelAudio; + LLPanelLandAudio* mPanelAudio; LLPanelLandMedia* mPanelMedia; LLPanelLandAccess* mPanelAccess; LLPanelLandCovenant* mPanelCovenant; From c250b9391b38df920babb24b9b8a2c3bcab76ceb Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 18:15:57 -0700 Subject: [PATCH 153/239] Set can_edit_text attribute to true for draw distance, particle count, and imposter count. Also increased the draw distance range to 1024 from 512 and changed the increments from 8 to 4 as better defaults --- linden/indra/newview/llpaneldisplay.cpp | 29 ------------------ linden/indra/newview/llpaneldisplay.h | 3 -- .../xui/en-us/panel_preferences_graphics1.xml | 30 +++++-------------- .../en-us/panel_windlight_remote_expanded.xml | 21 +++++-------- 4 files changed, 15 insertions(+), 68 deletions(-) diff --git a/linden/indra/newview/llpaneldisplay.cpp b/linden/indra/newview/llpaneldisplay.cpp index 15b461578..a5c0d97a3 100644 --- a/linden/indra/newview/llpaneldisplay.cpp +++ b/linden/indra/newview/llpaneldisplay.cpp @@ -267,9 +267,6 @@ BOOL LLPanelDisplay::postBuild() // Object detail slider mCtrlDrawDistance = getChild<LLSliderCtrl>("DrawDistance"); - mDrawDistanceMeterText1 = getChild<LLTextBox>("DrawDistanceMeterText1"); - mDrawDistanceMeterText2 = getChild<LLTextBox>("DrawDistanceMeterText2"); - mCtrlDrawDistance->setCommitCallback(&LLPanelDisplay::updateMeterText); mCtrlDrawDistance->setCallbackUserData(this); // Object detail slider @@ -636,8 +633,6 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) llassert(mAvatarText != NULL); llassert(mLightingText != NULL); llassert(mTerrainText != NULL); - llassert(mDrawDistanceMeterText1 != NULL); - llassert(mDrawDistanceMeterText2 != NULL); llassert(mAvatarCountText != NULL); // enable/disable the states @@ -684,16 +679,8 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) mAvatarText->setVisible(!isHidden); mLightingText->setVisible(!isHidden); mTerrainText->setVisible(!isHidden); - mDrawDistanceMeterText1->setVisible(!isHidden); - mDrawDistanceMeterText2->setVisible(!isHidden); mAvatarCountText->setVisible(!isHidden); - // hide one meter text if we're making things visible - if(!isHidden) - { - updateMeterText(mCtrlDrawDistance, this); - } - mMeshDetailText->setVisible(!isHidden); mCtrlAvatarMaxVisible->setVisible(!isHidden); @@ -998,22 +985,6 @@ void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, void* user_data) } } -void LLPanelDisplay::updateMeterText(LLUICtrl* ctrl, void* user_data) -{ - // get our UI widgets - LLPanelDisplay* panel = (LLPanelDisplay*)user_data; - LLSliderCtrl* slider = (LLSliderCtrl*) ctrl; - - LLTextBox* m1 = panel->getChild<LLTextBox>("DrawDistanceMeterText1"); - LLTextBox* m2 = panel->getChild<LLTextBox>("DrawDistanceMeterText2"); - - // toggle the two text boxes based on whether we have 1 or two digits - F32 val = slider->getValueF32(); - bool two_digits = val < 100; - m1->setVisible(two_digits); - m2->setVisible(!two_digits); -} - // static void LLPanelDisplay::onImpostorsEnable(LLUICtrl* ctrl, void* user_data) { diff --git a/linden/indra/newview/llpaneldisplay.h b/linden/indra/newview/llpaneldisplay.h index e92cd2fca..d7727e7fc 100644 --- a/linden/indra/newview/llpaneldisplay.h +++ b/linden/indra/newview/llpaneldisplay.h @@ -128,8 +128,6 @@ class LLPanelDisplay LLTextBox *mAvatarText; LLTextBox *mTerrainText; LLTextBox *mLightingText; - LLTextBox *mDrawDistanceMeterText1; - LLTextBox *mDrawDistanceMeterText2; LLTextBox *mMeshDetailText; LLTextBox *mLODFactorText; @@ -194,7 +192,6 @@ class LLPanelDisplay static void onCommitWindowedMode(LLUICtrl* ctrl, void *data); static void onApplyResolution(LLUICtrl* ctrl, void* data); static void updateSliderText(LLUICtrl* ctrl, void* user_data); - static void updateMeterText(LLUICtrl* ctrl, void* user_data); static void onImpostorsEnable(LLUICtrl* ctrl, void* user_data); /// callback for defaults diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml index 72a643806..bd7886c83 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml @@ -237,35 +237,21 @@ radio_style="false" width="256" /> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="12" left_delta="0" + font="SansSerifSmall" h_pad="0" halign="left" height="12" left_delta="0" mouse_opaque="true" name="AvatarCountText" v_pad="0" width="128"> Max. non-imposters: </text> - <slider bottom_delta="-20" can_edit_text="false" control_name="RenderAvatarMaxVisible" + <slider bottom_delta="-20" can_edit_text="true" control_name="RenderAvatarMaxVisible" decimal_digits="0" enabled="true" follows="left|top" height="16" - increment="1" initial_val="35" label="" + increment="1" initial_val="35" label="" label_width="0" left_delta="0" max_val="50" min_val="0" mouse_opaque="true" name="AvatarMaxVisible" show_text="true" width="100" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-131" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="12" - left="457" mouse_opaque="true" name="DrawDistanceMeterText1" v_pad="0" - width="128"> - m - </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-131" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="12" - left="463" mouse_opaque="true" name="DrawDistanceMeterText2" v_pad="0" - width="128"> - m - </text> - <slider bottom="-135" can_edit_text="false" control_name="RenderFarClip" + <slider bottom="-135" can_edit_text="true" control_name="RenderFarClip" decimal_digits="0" enabled="true" follows="left|top" height="16" - increment="8" initial_val="160" label="Draw distance:" - label_width="140" left="215" max_val="512" min_val="32" mouse_opaque="true" - name="DrawDistance" show_text="true" width="255" /> - <slider bottom_delta="-20" can_edit_text="false" control_name="RenderMaxPartCount" + increment="4" initial_val="160" label="Draw distance (meters):" + label_width="140" left="215" max_val="1024" min_val="32" mouse_opaque="true" + name="DrawDistance" show_text="true" width="262" /> + <slider bottom_delta="-20" can_edit_text="true" control_name="RenderMaxPartCount" decimal_digits="0" enabled="true" follows="left|top" height="16" increment="256" initial_val="4096" label="Max. particle count:" label_width="140" left_delta="0" diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_windlight_remote_expanded.xml b/linden/indra/newview/skins/default/xui/en-us/panel_windlight_remote_expanded.xml index 3849efd19..c7769cc68 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_windlight_remote_expanded.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_windlight_remote_expanded.xml @@ -3,24 +3,17 @@ follows="right|bottom" height="67" left="0" mouse_opaque="true" name="windlight_remote" use_bounding_rect="true" width="182"> <panel bottom="1" filename="panel_bg_tab.xml" name="panel_bg_tab" height="67" left="0" width="182" /> - <slider bottom="-20" can_edit_text="false" control_name="RenderFarClip" + <slider bottom="-20" can_edit_text="true" control_name="RenderFarClip" decimal_digits="0" enabled="true" height="18" - increment="8" initial_val="160" label="Draw distance:" - label_width="78" left="6" max_val="512" min_val="32" mouse_opaque="true" - name="DrawDistance" show_text="true" width="170" /> - <slider bottom_delta="-20" can_edit_text="false" control_name="RenderMaxPartCount" + increment="4" initial_val="160" label="Draw distance:" + label_width="74" left="4" max_val="1024" min_val="32" mouse_opaque="true" + name="DrawDistance" show_text="true" width="174" /> + <slider bottom_delta="-20" can_edit_text="true" control_name="RenderMaxPartCount" decimal_digits="0" enabled="true" follows="left|top" height="18" increment="256" initial_val="4096" - label="Max. particles:" label_width="78" left_delta="0" + label="Max. particles:" label_width="74" left_delta="0" max_val="8192" min_val="0" mouse_opaque="true" name="MaxParticleCount" - show_text="true" width="176" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" - bottom="-14" drop_shadow_visible="true" enabled="true" follows="left|top" - font="SansSerifSmall" h_pad="0" halign="left" height="12" - left="170" mouse_opaque="true" name="DrawDistanceMeterText2" v_pad="0" - width="8"> - m - </text> + show_text="true" width="174" /> <panel bottom="13" filename="panel_windlight_controls.xml" left="0" width="182" /> <string name="atmosphere"> Atmosphere From 2ca774143c29f216ae7cd38c83c9689988e87df4 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 18:28:29 -0700 Subject: [PATCH 154/239] Set can_edit_text attribute to true for the radar distance slider, fixed the layout and the default being too large (2048 isn't supported on SL. This problem needs a different solution) --- .../indra/newview/skins/default/xui/en-us/panel_radar.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml b/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml index ce2d5ad64..4639ef323 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_radar.xml @@ -41,12 +41,12 @@ </text> <slider name="near_me_range" label="" control_name="NearMeRange" - bottom_delta="0" left_delta="62" width="150" height="15" - follows="left|top" min_val="5" max_val="2048" increment="1" - initial_val="96" decimal_digits="0" /> + bottom_delta="0" left_delta="58" width="110" height="15" + follows="left|top" min_val="5" max_val="1024" increment="1" + initial_val="96" decimal_digits="0" can_edit_text="true" /> <text name="meters" - bottom_delta="0" left_delta="10" height="15" width="40" + bottom_delta="0" left_delta="113" height="15" width="40" h_pad="0" halign="left" v_pad="0" follows="left|top" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" drop_shadow_visible="true" From a3c9b138c1f230fdba8c83d926daa9238eed0372 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 18:31:39 -0700 Subject: [PATCH 155/239] Removed 640x480 resolution from preferences since the UI doesn't fit when using it anymore --- .../skins/default/xui/en-us/panel_preferences_graphics1.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml index bd7886c83..e632db2f5 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml @@ -29,9 +29,6 @@ <combo_box allow_text_entry="false" bottom="-67" enabled="true" follows="left|top" height="18" left="185" max_chars="20" mouse_opaque="true" name="windowsize combo" width="150"> - <combo_item type="string" length="1" enabled="true" name="640x480" value="640 x 480"> - 640x480 - </combo_item> <combo_item type="string" length="1" enabled="true" name="800x600" value="800 x 600"> 800x600 </combo_item> From f023761d3c6a7541d8e5197dee0735d283df4b37 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 18:39:48 -0700 Subject: [PATCH 156/239] Added three new resolutions: * 1280x720 (HDV720) * 1440x1080 (HDV1080) * 1920x1080 (HD1080) --- .../xui/en-us/panel_preferences_graphics1.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml index e632db2f5..2ed0869a6 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml @@ -41,8 +41,16 @@ <combo_item type="string" length="1" enabled="true" name="1024x768" value="1024 x 768"> 1024x768 </combo_item> - - </combo_box> + <combo_item type="string" length="1" enabled="true" name="1280x720" value="1280 x 720"> + 1280x720 (HDV720) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="1440x1080" value="1440 x 1080"> + 1440x1080 (HDV1080) + </combo_item> + <combo_item type="string" length="1" enabled="true" name="1920x1080" value="1920 x 1080"> + 1920x1080 (HD1080) + </combo_item> + </combo_box> <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" bottom="-62" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10" From c84c7fa1386665190f9043344d4849fade9c03a1 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 5 Nov 2010 19:38:17 -0700 Subject: [PATCH 157/239] Applied patch by Qarl Fizz to allow drag selection on plants. See http://www.qarl.com/qLab/?p=67 --- linden/indra/newview/llglsandbox.cpp | 10 +- linden/indra/newview/llselectmgr.cpp | 35 ++++++- linden/indra/newview/llviewercamera.cpp | 4 +- linden/indra/newview/llvograss.cpp | 91 +++++++++++++++++ linden/indra/newview/llvograss.h | 9 ++ linden/indra/newview/llvotree.cpp | 125 ++++++++++++++++++++++++ linden/indra/newview/llvotree.h | 14 ++- 7 files changed, 279 insertions(+), 9 deletions(-) diff --git a/linden/indra/newview/llglsandbox.cpp b/linden/indra/newview/llglsandbox.cpp index a4871508b..98c4d06df 100644 --- a/linden/indra/newview/llglsandbox.cpp +++ b/linden/indra/newview/llglsandbox.cpp @@ -275,7 +275,11 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) virtual bool apply(LLViewerObject* vobjp) { LLDrawable* drawable = vobjp->mDrawable; - if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment()) + if (!drawable || + ((vobjp->getPCode() != LL_PCODE_VOLUME) && + (vobjp->getPCode() != LL_PCODE_LEGACY_TREE) && + (vobjp->getPCode() != LL_PCODE_LEGACY_GRASS) )|| + vobjp->isAttachment()) { return true; } @@ -326,7 +330,9 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) LLViewerObject* vobjp = drawable->getVObj(); if (!drawable || !vobjp || - vobjp->getPCode() != LL_PCODE_VOLUME || + ((vobjp->getPCode() != LL_PCODE_VOLUME) && + (vobjp->getPCode() != LL_PCODE_LEGACY_TREE) && + (vobjp->getPCode() != LL_PCODE_LEGACY_GRASS) )|| vobjp->isAttachment() || (deselect && !vobjp->isSelected())) { diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index 0d53e82f6..b0a6834a5 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -85,6 +85,8 @@ #include "llviewerregion.h" #include "llviewerstats.h" #include "llvoavatar.h" +#include "llvograss.h" +#include "llvotree.h" #include "llvovolume.h" #include "pipeline.h" @@ -832,7 +834,10 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) return; } - if (objectp->getPCode() != LL_PCODE_VOLUME) + if ((objectp->getPCode() != LL_PCODE_VOLUME) && + (objectp->getPCode() != LL_PCODE_LEGACY_TREE) && + (objectp->getPCode() != LL_PCODE_LEGACY_GRASS)) + { return; } @@ -880,7 +885,10 @@ void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& o { continue; } - if (object->getPCode() != LL_PCODE_VOLUME) + + if ((object->getPCode() != LL_PCODE_VOLUME) && + (object->getPCode() != LL_PCODE_LEGACY_TREE) && + (object->getPCode() != LL_PCODE_LEGACY_GRASS)) { continue; } @@ -900,7 +908,14 @@ void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& o void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp) { - if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + if (!objectp) + { + return; + } + + if ((objectp->getPCode() != LL_PCODE_VOLUME) && + (objectp->getPCode() != LL_PCODE_LEGACY_TREE) && + (objectp->getPCode() != LL_PCODE_LEGACY_GRASS)) { return; } @@ -5020,6 +5035,14 @@ void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_ { ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point); } + else if (objectp && objectp->getPCode() == LL_PCODE_LEGACY_GRASS) + { + ((LLVOGrass*)objectp)->generateSilhouette(nodep, view_point); + } + else if (objectp && objectp->getPCode() == LL_PCODE_LEGACY_TREE) + { + ((LLVOTree*)objectp)->generateSilhouette(nodep, view_point); + } } // @@ -5355,8 +5378,10 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix); } - LLVolume *volume = objectp->getVolume(); - if (volume) + //LLVolume *volume = objectp->getVolume(); + //if (volume) + // we used to only call this for volumes. but let's render silhouettes for any node that has them. + if (1) { F32 silhouette_thickness; if (is_hud_object && gAgent.getAvatarObject()) diff --git a/linden/indra/newview/llviewercamera.cpp b/linden/indra/newview/llviewercamera.cpp index dade65f1a..16f6e57f7 100644 --- a/linden/indra/newview/llviewercamera.cpp +++ b/linden/indra/newview/llviewercamera.cpp @@ -743,7 +743,9 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) LLVolume* volume = volumep->getVolume(); if (!volume) { - return FALSE; + BOOL inside = pointInFrustum(volumep->getRenderPosition()); + + return (inside > 0); } LLVOVolume* vo_volume = (LLVOVolume*) volumep; diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index f73887226..913ec3386 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -48,6 +48,7 @@ #include "llviewercamera.h" #include "llviewerimagelist.h" #include "llviewerregion.h" +#include "llselectmgr.h" #include "pipeline.h" #include "llspatialpartition.h" #include "llworld.h" @@ -721,3 +722,93 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en return ret; } +void LLVOGrass::generateSilhouetteVertices(std::vector<LLVector3> &vertices, + std::vector<LLVector3> &normals, + std::vector<S32> &segments, + const LLVector3& obj_cam_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat) +{ + vertices.clear(); + normals.clear(); + segments.clear(); + + F32 width = sSpeciesTable[mSpecies]->mBladeSizeX; + F32 height = sSpeciesTable[mSpecies]->mBladeSizeY; + + for (S32 i = 0; i < mNumBlades; i++) + { + F32 x = exp_x[i] * mScale.mV[VX]; + F32 y = exp_y[i] * mScale.mV[VY]; + F32 xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i]; + F32 yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i]; + F32 dzx = dz_x [i]; + F32 dzy = dz_y [i]; + + F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i]; + + LLVector3 position1; + + position1.mV[0] = mPosition.mV[VX] + x + xf; + position1.mV[1] = mPosition.mV[VY] + y + yf; + position1.mV[2] = mRegionp->getLand().resolveHeightRegion(position1); + + LLVector3 position2 = position1; + + position2.mV[0] += dzx; + position2.mV[1] += dzy; + position2.mV[2] += blade_height; + + LLVector3 position3; + + position3.mV[0] = mPosition.mV[VX] + x - xf; + position3.mV[1] = mPosition.mV[VY] + y - xf; + position3.mV[2] = mRegionp->getLand().resolveHeightRegion(position3); + + LLVector3 position4 = position3; + + position4.mV[0] += dzx; + position4.mV[1] += dzy; + position4.mV[2] += blade_height; + + + LLVector3 normal = (position1-position2) % (position2 - position3); + normal.normalize(); + + vertices.push_back(position1 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position2 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position2 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position4 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position4 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position3 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position3 + mRegionp->getOriginAgent()); + normals.push_back(normal); + vertices.push_back(position1 + mRegionp->getOriginAgent()); + normals.push_back(normal); + segments.push_back(vertices.size()); + } +} + + + +void LLVOGrass::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) +{ + generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, + nodep->mSilhouetteSegments, + LLVector3(0,0,0), LLMatrix4(), LLMatrix3()); + + nodep->mSilhouetteExists = TRUE; + +} diff --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index 25fa04cad..c76ab9357 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -37,6 +37,7 @@ #include "lldarray.h" #include <map> +class LLSelectNode; class LLSurfacePatch; class LLViewerImage; @@ -76,6 +77,8 @@ class LLVOGrass : public LLAlphaObject /*virtual*/ BOOL updateLOD(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area + void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); + void plantBlades(); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. @@ -125,6 +128,12 @@ class LLVOGrass : public LLAlphaObject ~LLVOGrass(); private: + void generateSilhouetteVertices(std::vector<LLVector3> &vertices, + std::vector<LLVector3> &normals, + std::vector<S32> &segments, + const LLVector3& view_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat); void updateSpecies(); F32 mLastHeight; // For cheap update hack S32 mNumBlades; diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index 6a59253a9..8c6abdcc4 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -47,6 +47,7 @@ #include "llagent.h" #include "lldrawable.h" #include "llface.h" +#include "llselectmgr.h" #include "llviewercamera.h" #include "llviewerimagelist.h" #include "llviewerobjectlist.h" @@ -1327,3 +1328,127 @@ LLTreePartition::LLTreePartition() mLODPeriod = 1; } + + +void LLVOTree::generateSilhouetteVertices(std::vector<LLVector3> &vertices, + std::vector<LLVector3> &normals, + std::vector<S32> &segments, + const LLVector3& obj_cam_vec, + const LLMatrix4& local_matrix, + const LLMatrix3& normal_matrix) +{ + vertices.clear(); + normals.clear(); + segments.clear(); + + F32 height = mBillboardScale; // *mBillboardRatio * 0.5; + F32 width = height * mTrunkAspect; + + LLVector3 position1 = LLVector3(-width * 0.5,0,0) * local_matrix; + LLVector3 position2 = LLVector3(-width * 0.5,0,height) * local_matrix; + LLVector3 position3 = LLVector3(+width * 0.5,0,height) * local_matrix; + LLVector3 position4 = LLVector3(+width * 0.5,0,0) * local_matrix; + + LLVector3 position5 = LLVector3(0,-width * 0.5,0) * local_matrix; + LLVector3 position6 = LLVector3(0,-width * 0.5,height) * local_matrix; + LLVector3 position7 = LLVector3(0,+width * 0.5,height) * local_matrix; + LLVector3 position8 = LLVector3(0,+width * 0.5,0) * local_matrix; + + + LLVector3 normal = (position1-position2) % (position2-position3); + normal.normalize(); + + vertices.push_back(position1); + normals.push_back(normal); + vertices.push_back(position2); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position2); + normals.push_back(normal); + vertices.push_back(position3); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position3); + normals.push_back(normal); + vertices.push_back(position4); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position4); + normals.push_back(normal); + vertices.push_back(position1); + normals.push_back(normal); + segments.push_back(vertices.size()); + + normal = (position5-position6) % (position6-position7); + normal.normalize(); + + vertices.push_back(position5); + normals.push_back(normal); + vertices.push_back(position6); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position6); + normals.push_back(normal); + vertices.push_back(position7); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position7); + normals.push_back(normal); + vertices.push_back(position8); + normals.push_back(normal); + segments.push_back(vertices.size()); + + vertices.push_back(position8); + normals.push_back(normal); + vertices.push_back(position5); + normals.push_back(normal); + segments.push_back(vertices.size()); + +} + + +void LLVOTree::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) +{ + LLVector3 position; + LLQuaternion rotation; + + if (mDrawable->isActive()) + { + if (mDrawable->isSpatialRoot()) + { + position = LLVector3(); + rotation = LLQuaternion(); + } + else + { + position = mDrawable->getPosition(); + rotation = mDrawable->getRotation(); + } + } + else + { + position = getPosition() + getRegion()->getOriginAgent();; + rotation = getRotation(); + } + + // trees have bizzare scaling rules... because it's cool to make needless exceptions + // PS: the trees are the last remaining tidbit of Philip's code. take a look sometime. + F32 radius = getScale().length() * 0.05f; + LLVector3 scale = LLVector3(1,1,1) * radius; + + // compose final matrix + LLMatrix4 local_matrix; + local_matrix.initAll(scale, rotation, position); + + + generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, + nodep->mSilhouetteSegments, + LLVector3(0,0,0), local_matrix, LLMatrix3()); + + nodep->mSilhouetteExists = TRUE; +} diff --git a/linden/indra/newview/llvotree.h b/linden/indra/newview/llvotree.h index 855c612b8..57116cc37 100644 --- a/linden/indra/newview/llvotree.h +++ b/linden/indra/newview/llvotree.h @@ -39,7 +39,7 @@ class LLFace; class LLDrawPool; - +class LLSelectNode; class LLVOTree : public LLViewerObject { @@ -124,6 +124,9 @@ class LLVOTree : public LLViewerObject LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); + void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); + + static S32 sMaxTreeSpecies; struct TreeSpeciesData @@ -200,6 +203,15 @@ class LLVOTree : public LLViewerObject static S32 sLODVertexCount[4]; static S32 sLODSlices[4]; static F32 sLODAngles[4]; + +private: + void generateSilhouetteVertices(std::vector<LLVector3> &vertices, + std::vector<LLVector3> &normals, + std::vector<S32> &segments, + const LLVector3& view_vec, + const LLMatrix4& mat, + const LLMatrix3& norm_mat); + }; #endif From 6eeb3a5f98aae249d88dc70212788bb4038a99e8 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sat, 6 Nov 2010 17:09:02 +0100 Subject: [PATCH 158/239] This replaces the libcairo package with a self-compiled one that doesn't depend on libdirectfb etc. --- linden/install.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index d9bea6708..d6c318039 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -700,9 +700,9 @@ cairo: Copyright © 2002 University of Southern California, Copyright © 2005 Re <key>linux</key> <map> <key>md5sum</key> - <string>31c9ddf859411c4890f1b31564b2fa91</string> + <string>0d09429e3ef1aa23d5a9d1a83af2a203</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/gtk-etc-linux-20101105.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/gtk-etc-linux-20101106.tar.bz2</uri> </map> <key>linux64</key> <map> From e2699d23f69ca5a82e864e2dc8ae28cdf89ed6f8 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sat, 6 Nov 2010 17:26:18 +0100 Subject: [PATCH 159/239] Add missing gdkconfig.h. I missed this one cause it's install in a different directory than all the other header files. --- linden/install.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index d6c318039..04d7b5eff 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -700,9 +700,9 @@ cairo: Copyright © 2002 University of Southern California, Copyright © 2005 Re <key>linux</key> <map> <key>md5sum</key> - <string>0d09429e3ef1aa23d5a9d1a83af2a203</string> + <string>349ee367e0ac1e878b24b66e449c6ff8</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/gtk-etc-linux-20101106.tar.bz2</uri> + <uri>http://github.com/downloads/AlericInglewood/imprudence/gtk-etc-linux-20101106.1.tar.bz2</uri> </map> <key>linux64</key> <map> From 9d26172d74b6de638339f8f6336f5087c91c8831 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sat, 6 Nov 2010 20:50:03 +0100 Subject: [PATCH 160/239] IMP-688: ERROR: getString: Invalid string control nick01 Don't look for the old variable names, "nick0*", but for the new ones. --- linden/doc/contributions.txt | 1 + linden/indra/newview/llfloaterchat.cpp | 2 +- linden/indra/newview/llprefscolors.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index a54424ca7..cd6544a98 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -89,6 +89,7 @@ Aleric Inglewood IMP-664 IMP-667 IMP-670 + IMP-688 Alissa Sabre VWR-81 VWR-83 diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index a453c3971..e9ea14b02 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp @@ -482,7 +482,7 @@ BOOL LLFloaterChat::isOwnNameInText(const std::string &text_line) for (int i=1; i<=3; i++) { std::stringstream key; - key << "nick0" << i; + key << "HighlightNickname0" << i; std::string nick = gSavedSettings.getString(key.str()); if (! nick.empty()) { diff --git a/linden/indra/newview/llprefscolors.cpp b/linden/indra/newview/llprefscolors.cpp index 36e98a4d5..b0bc34510 100644 --- a/linden/indra/newview/llprefscolors.cpp +++ b/linden/indra/newview/llprefscolors.cpp @@ -71,6 +71,7 @@ BOOL LLPrefsColors::postBuild() updateSelfCheck(); updateFriendsCheck(); + // All three of these settings must exist, they are read by LLFloaterChat::isOwnNameInText. childSetValue("nick01", gSavedSettings.getString("HighlightNickname01")); childSetValue("nick02", gSavedSettings.getString("HighlightNickname02")); childSetValue("nick03", gSavedSettings.getString("HighlightNickname03")); From 1e2effb043c23df5d8ecaf856c80b64a42977e8e Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sat, 6 Nov 2010 20:50:03 +0100 Subject: [PATCH 161/239] IMP-688: ERROR: getString: Invalid string control nick01 Don't look for the old variable names, "nick0*", but for the new ones. --- linden/doc/contributions.txt | 1 + linden/indra/newview/llfloaterchat.cpp | 2 +- linden/indra/newview/llprefscolors.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index a54424ca7..cd6544a98 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -89,6 +89,7 @@ Aleric Inglewood IMP-664 IMP-667 IMP-670 + IMP-688 Alissa Sabre VWR-81 VWR-83 diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index a453c3971..e9ea14b02 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp @@ -482,7 +482,7 @@ BOOL LLFloaterChat::isOwnNameInText(const std::string &text_line) for (int i=1; i<=3; i++) { std::stringstream key; - key << "nick0" << i; + key << "HighlightNickname0" << i; std::string nick = gSavedSettings.getString(key.str()); if (! nick.empty()) { diff --git a/linden/indra/newview/llprefscolors.cpp b/linden/indra/newview/llprefscolors.cpp index 36e98a4d5..b0bc34510 100644 --- a/linden/indra/newview/llprefscolors.cpp +++ b/linden/indra/newview/llprefscolors.cpp @@ -71,6 +71,7 @@ BOOL LLPrefsColors::postBuild() updateSelfCheck(); updateFriendsCheck(); + // All three of these settings must exist, they are read by LLFloaterChat::isOwnNameInText. childSetValue("nick01", gSavedSettings.getString("HighlightNickname01")); childSetValue("nick02", gSavedSettings.getString("HighlightNickname02")); childSetValue("nick03", gSavedSettings.getString("HighlightNickname03")); From 5b4356cefbaa7dbdc8656e7283c110a893b1a89c Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 7 Nov 2010 16:55:50 +0100 Subject: [PATCH 162/239] IMP-692: SNOW-713: Global objects in libllcommon duplicated in plugins See http://jira.secondlife.com/browse/SNOW-713 This patch makes llcommon shared. It contains the following snowglobe (SVN) changesets: 3478, 3479, 3480, 3481, 3482, 3485, 3496, 3498, 3500, 3519 and 3531, plus the fix for all rejects. Note that changes to scripts/automated_build_scripts/opensrc-build.sh (changesets 3500 and 3625) were ignored as we don't have scripts/automated_build_scripts. --- linden/doc/contributions.txt | 1 + linden/indra/cmake/00-Common.cmake | 2 +- linden/indra/cmake/APR.cmake | 20 ++--- linden/indra/cmake/CopyWinLibs.cmake | 6 ++ linden/indra/cmake/LLCommon.cmake | 13 +-- linden/indra/develop.py | 8 +- linden/indra/llcharacter/llcharacter.cpp | 1 + linden/indra/llcommon/CMakeLists.txt | 23 +---- linden/indra/llcommon/imageids.h | 48 +++++------ linden/indra/llcommon/indra_constants.h | 10 +-- linden/indra/llcommon/linden_common.h | 19 +++-- linden/indra/llcommon/llapp.cpp | 2 +- linden/indra/llcommon/llapp.h | 13 +-- linden/indra/llcommon/llapr.h | 21 +++-- linden/indra/llcommon/llassettype.h | 2 +- linden/indra/llcommon/llbase32.h | 2 +- linden/indra/llcommon/llbase64.h | 2 +- linden/indra/llcommon/llcommon.h | 2 +- linden/indra/llcommon/llcrc.h | 2 +- linden/indra/llcommon/llcriticaldamp.h | 2 +- linden/indra/llcommon/llcursortypes.h | 2 +- linden/indra/llcommon/lldate.h | 6 +- linden/indra/llcommon/llerror.cpp | 2 + linden/indra/llcommon/llerror.h | 6 +- linden/indra/llcommon/llerrorcontrol.h | 46 +++++----- linden/indra/llcommon/llerrorthread.cpp | 1 + linden/indra/llcommon/llerrorthread.h | 2 +- linden/indra/llcommon/llevent.h | 10 +-- linden/indra/llcommon/llfasttimer.cpp | 1 + linden/indra/llcommon/llfasttimer.h | 4 +- linden/indra/llcommon/llfile.h | 10 +-- linden/indra/llcommon/llfindlocale.h | 4 +- linden/indra/llcommon/llfixedbuffer.h | 2 +- linden/indra/llcommon/llformat.h | 2 +- linden/indra/llcommon/llframetimer.h | 2 +- linden/indra/llcommon/llheartbeat.h | 2 +- linden/indra/llcommon/llliveappconfig.h | 2 +- linden/indra/llcommon/lllivefile.h | 2 +- linden/indra/llcommon/lllog.h | 2 +- linden/indra/llcommon/llmd5.cpp | 1 + linden/indra/llcommon/llmd5.h | 2 +- linden/indra/llcommon/llmemory.cpp | 13 ++- linden/indra/llcommon/llmemory.h | 10 +-- linden/indra/llcommon/llmemorystream.h | 4 +- linden/indra/llcommon/llmemtype.h | 2 +- linden/indra/llcommon/llmetrics.h | 2 +- linden/indra/llcommon/llmortician.h | 2 +- linden/indra/llcommon/llpreprocessor.h | 62 +++++++++----- linden/indra/llcommon/llprocesslauncher.h | 2 +- linden/indra/llcommon/llqueuedthread.cpp | 1 + linden/indra/llcommon/llqueuedthread.h | 4 +- linden/indra/llcommon/llrand.h | 12 +-- linden/indra/llcommon/llrun.h | 6 +- linden/indra/llcommon/llsd.cpp | 12 ++- linden/indra/llcommon/llsd.h | 4 +- linden/indra/llcommon/llsdserialize.h | 18 ++-- linden/indra/llcommon/llsdserialize_xml.cpp | 2 +- linden/indra/llcommon/llsdutil.h | 22 ++--- linden/indra/llcommon/llsecondlifeurls.h | 8 +- linden/indra/llcommon/llsimplehash.h | 2 +- linden/indra/llcommon/llstat.h | 14 ++-- linden/indra/llcommon/llstreamtools.h | 36 ++++---- linden/indra/llcommon/llstring.h | 83 ++++++++++--------- linden/indra/llcommon/llstringtable.h | 8 +- linden/indra/llcommon/llsys.h | 18 ++-- linden/indra/llcommon/llthread.h | 12 +-- linden/indra/llcommon/lltimer.cpp | 4 +- linden/indra/llcommon/lltimer.h | 29 +++---- linden/indra/llcommon/lluri.h | 4 +- linden/indra/llcommon/lluuid.h | 9 +- linden/indra/llcommon/llworkerthread.h | 4 +- linden/indra/llcommon/metaclass.h | 2 +- linden/indra/llcommon/metaproperty.h | 2 +- linden/indra/llcommon/reflective.h | 2 +- linden/indra/llcommon/timing.h | 2 +- linden/indra/llcommon/u64.h | 10 +-- linden/indra/llinventory/llparcel.h | 2 +- linden/indra/llmath/lloctree.h | 6 +- linden/indra/llmath/lltreenode.h | 2 - linden/indra/llmessage/CMakeLists.txt | 4 +- linden/indra/llmessage/llassetstorage.cpp | 12 +-- linden/indra/llmessage/llassetstorage.h | 6 +- linden/indra/llmessage/llcurl.cpp | 4 +- linden/indra/llmessage/llcurl.h | 2 +- linden/indra/llmessage/llhttpassetstorage.cpp | 2 +- linden/indra/llmessage/llhttpassetstorage.h | 2 + linden/indra/llmessage/llhttpnode.cpp | 18 ++-- linden/indra/llmessage/llhttpnode.h | 10 +-- linden/indra/llmessage/llpumpio.cpp | 1 + .../llmessage/llregionpresenceverifier.cpp | 1 + linden/indra/llmessage/llsdappservices.cpp | 4 +- linden/indra/llmessage/llsdhttpserver.cpp | 4 +- linden/indra/llplugin/CMakeLists.txt | 4 - linden/indra/llrender/llfontgl.cpp | 1 + linden/indra/llrender/llgl.cpp | 2 - linden/indra/llui/llfunctorregistry.cpp | 1 + linden/indra/llvfs/lldir.cpp | 1 + linden/indra/llvfs/llpidlock.cpp | 3 +- linden/indra/llvfs/llpidlock.h | 2 - linden/indra/llvfs/llvfile.cpp | 1 + linden/indra/llvfs/llvfs.cpp | 1 + linden/indra/llwindow/lldxhardware.cpp | 1 + linden/indra/llwindow/llwindowmacosx.h | 1 + linden/indra/llwindow/llwindowsdl.cpp | 6 +- linden/indra/llwindow/llwindowsdl.h | 2 +- linden/indra/llwindow/llwindowwin32.cpp | 2 + linden/indra/lscript/lscript_execute.h | 1 + .../lscript_execute/llscriptresource.cpp | 1 + .../indra/media_plugins/base/CMakeLists.txt | 4 - .../media_plugins/example/CMakeLists.txt | 4 - .../media_plugins/gstreamer010/CMakeLists.txt | 12 --- .../llmediaimplgstreamertriviallogging.h | 26 ++---- .../media_plugin_gstreamer010.cpp | 2 +- .../indra/media_plugins/webkit/CMakeLists.txt | 12 --- linden/indra/newview/CMakeLists.txt | 14 +++- linden/indra/newview/llagent.cpp | 4 +- linden/indra/newview/llappviewer.h | 2 + linden/indra/newview/llfeaturemanager.cpp | 1 - linden/indra/newview/llfloaterabout.cpp | 1 - .../indra/newview/llhomelocationresponder.cpp | 5 +- .../indra/newview/llhomelocationresponder.h | 2 +- linden/indra/newview/llspatialpartition.cpp | 6 +- linden/indra/newview/llviewerassetstorage.h | 1 + linden/indra/newview/llwatchdog.h | 3 +- linden/indra/newview/viewer_manifest.py | 51 +++++++++++- linden/install.xml | 8 +- 126 files changed, 532 insertions(+), 473 deletions(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index cd6544a98..89d22ee96 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -90,6 +90,7 @@ Aleric Inglewood IMP-667 IMP-670 IMP-688 + IMP-692 Alissa Sabre VWR-81 VWR-83 diff --git a/linden/indra/cmake/00-Common.cmake b/linden/indra/cmake/00-Common.cmake index 4c04be975..c3aa9eafb 100644 --- a/linden/indra/cmake/00-Common.cmake +++ b/linden/indra/cmake/00-Common.cmake @@ -210,7 +210,7 @@ if (LINUX OR DARWIN) set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") endif (NOT GCC_DISABLE_FATAL_WARNINGS) - set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor") + set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor -Woverloaded-virtual") set(CMAKE_C_FLAGS "${GCC_WARNINGS} ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "${GCC_CXX_WARNINGS} ${CMAKE_CXX_FLAGS}") diff --git a/linden/indra/cmake/APR.cmake b/linden/indra/cmake/APR.cmake index e9f64118d..d1f089891 100644 --- a/linden/indra/cmake/APR.cmake +++ b/linden/indra/cmake/APR.cmake @@ -14,27 +14,27 @@ else (STANDALONE) use_prebuilt_binary(apr_suite) if (WINDOWS) set(APR_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/apr-1.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/apr-1.lib + debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.lib + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.lib ) set(APRICONV_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/apriconv-1.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/apriconv-1.lib + debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapriconv-1.lib + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapriconv-1.lib ) # Doesn't need to link with iconv.dll set(APRICONV_LIBRARIES "") set(APRUTIL_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/aprutil-1.lib ${APRICONV_LIBRARIES} - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/aprutil-1.lib ${APRICONV_LIBRARIES} + debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.lib ${APRICONV_LIBRARIES} + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.lib ${APRICONV_LIBRARIES} ) elseif (DARWIN) set(APR_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.a - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.a + debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.0.3.7.dylib + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.0.3.7.dylib ) set(APRUTIL_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.a - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.a + debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.0.3.8.dylib + optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.0.3.8.dylib ) set(APRICONV_LIBRARIES iconv) else (WINDOWS) diff --git a/linden/indra/cmake/CopyWinLibs.cmake b/linden/indra/cmake/CopyWinLibs.cmake index a091a3177..f5846891b 100644 --- a/linden/indra/cmake/CopyWinLibs.cmake +++ b/linden/indra/cmake/CopyWinLibs.cmake @@ -29,6 +29,9 @@ set(debug_files openal32.dll openjpegd.dll libhunspell.dll + libapr-1.dll + libaprutil-1.dll + libapriconv-1.dll ) copy_if_different( @@ -209,6 +212,9 @@ set(release_files openal32.dll openjpeg.dll libhunspell.dll + libapr-1.dll + libaprutil-1.dll + libapriconv-1.dll ) copy_if_different( diff --git a/linden/indra/cmake/LLCommon.cmake b/linden/indra/cmake/LLCommon.cmake index 9158e9824..410766e4f 100644 --- a/linden/indra/cmake/LLCommon.cmake +++ b/linden/indra/cmake/LLCommon.cmake @@ -12,15 +12,4 @@ set(LLCOMMON_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ) -# Files that need PIC code (pluginAPI) need to set REQUIRE_PIC on 64bit systems -# this will link against a llcommon built with Position Independent Code -# this is a requirment to link a static library (.a) to a DSO on 64 bit systems - -if(REQUIRE_PIC) - set(LLCOMMON_LIBRARIES llcommonPIC) -else(REQUIRE_PIC) - set(LLCOMMON_LIBRARIES llcommon) -endif(REQUIRE_PIC) - -#force clear the flag, files that need this must explicity set it themselves -set(REQUIRE_PIC 0) \ No newline at end of file +set(LLCOMMON_LIBRARIES llcommon) diff --git a/linden/indra/develop.py b/linden/indra/develop.py index 2ce9f91af..e80437473 100755 --- a/linden/indra/develop.py +++ b/linden/indra/develop.py @@ -76,6 +76,7 @@ class PlatformSetup(object): build_type = build_types['relwithdebinfo'] standalone = 'OFF' unattended = 'OFF' + universal = 'OFF' project_name = 'Imprudence' distcc = True cmake_opts = [] @@ -404,7 +405,7 @@ def os(self): return 'darwin' def arch(self): - if self.unattended == 'ON': + if self.universal == 'ON': return 'universal' else: return UnixSetup.arch(self) @@ -417,10 +418,10 @@ def cmake_commandline(self, src_dir, build_dir, opts, simple): standalone=self.standalone, unattended=self.unattended, project_name=self.project_name, - universal='', + universal=self.universal, type=self.build_type.upper() ) - if self.unattended == 'ON': + if self.universal == 'ON': args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386\'' #if simple: # return 'cmake %(opts)s %(dir)r' % args @@ -696,6 +697,7 @@ def cmake_commandline(self, src_dir, build_dir, opts, simple): --standalone build standalone, without Linden prebuild libraries --unattended build unattended, do not invoke any tools requiring a human response + --universal build a universal binary on Mac OS X (unsupported) -t | --type=NAME build type ("Debug", "Release", or "RelWithDebInfo") -N | --no-distcc disable use of distcc -G | --generator=NAME generator name diff --git a/linden/indra/llcharacter/llcharacter.cpp b/linden/indra/llcharacter/llcharacter.cpp index dcdfe074e..46ac3262e 100644 --- a/linden/indra/llcharacter/llcharacter.cpp +++ b/linden/indra/llcharacter/llcharacter.cpp @@ -38,6 +38,7 @@ #include "llcharacter.h" #include "llstring.h" +#include "llfasttimer.h" #define SKEL_HEADER "Linden Skeleton 1.0" diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt index 7d001ae57..5d590a9b9 100644 --- a/linden/indra/llcommon/CMakeLists.txt +++ b/linden/indra/llcommon/CMakeLists.txt @@ -4,6 +4,7 @@ project(llcommon) include(00-Common) include(LLCommon) +include(Linking) include_directories( ${EXPAT_INCLUDE_DIRS} @@ -192,31 +193,13 @@ set_source_files_properties(${llcommon_HEADER_FILES} list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) -add_library (llcommon ${llcommon_SOURCE_FILES}) +add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) target_link_libraries( llcommon ${APRUTIL_LIBRARIES} ${APR_LIBRARIES} ${EXPAT_LIBRARIES} ${ZLIB_LIBRARIES} + ${WINDOWS_LIBRARIES} ) -if(HAVE_64_BIT) - add_library (llcommonPIC ${llcommon_SOURCE_FILES}) - add_dependencies(llcommonPIC prepare) - - if(WINDOWS) - add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) - - target_link_libraries( - llcommonPIC - ${APRUTIL_LIBRARIES} - ${APR_LIBRARIES} - ${EXPAT_LIBRARIES} - ${ZLIB_LIBRARIES} - ) -endif(HAVE_64_BIT) - diff --git a/linden/indra/llcommon/imageids.h b/linden/indra/llcommon/imageids.h index 7bae496e7..dc726dcf5 100644 --- a/linden/indra/llcommon/imageids.h +++ b/linden/indra/llcommon/imageids.h @@ -41,35 +41,35 @@ class LLUUID; -extern const LLUUID IMG_SMOKE; +LL_COMMON_API extern const LLUUID IMG_SMOKE; -extern const LLUUID IMG_DEFAULT; +LL_COMMON_API extern const LLUUID IMG_DEFAULT; -extern const LLUUID IMG_SUN; -extern const LLUUID IMG_MOON; -extern const LLUUID IMG_CLOUD_POOF; -extern const LLUUID IMG_SHOT; -extern const LLUUID IMG_SPARK; -extern const LLUUID IMG_FIRE; -extern const LLUUID IMG_FACE_SELECT; -extern const LLUUID IMG_DEFAULT_AVATAR; -extern const LLUUID IMG_INVISIBLE; +LL_COMMON_API extern const LLUUID IMG_SUN; +LL_COMMON_API extern const LLUUID IMG_MOON; +LL_COMMON_API extern const LLUUID IMG_CLOUD_POOF; +LL_COMMON_API extern const LLUUID IMG_SHOT; +LL_COMMON_API extern const LLUUID IMG_SPARK; +LL_COMMON_API extern const LLUUID IMG_FIRE; +LL_COMMON_API extern const LLUUID IMG_FACE_SELECT; +LL_COMMON_API extern const LLUUID IMG_DEFAULT_AVATAR; +LL_COMMON_API extern const LLUUID IMG_INVISIBLE; -extern const LLUUID IMG_EXPLOSION; -extern const LLUUID IMG_EXPLOSION_2; -extern const LLUUID IMG_EXPLOSION_3; -extern const LLUUID IMG_EXPLOSION_4; -extern const LLUUID IMG_SMOKE_POOF; +LL_COMMON_API extern const LLUUID IMG_EXPLOSION; +LL_COMMON_API extern const LLUUID IMG_EXPLOSION_2; +LL_COMMON_API extern const LLUUID IMG_EXPLOSION_3; +LL_COMMON_API extern const LLUUID IMG_EXPLOSION_4; +LL_COMMON_API extern const LLUUID IMG_SMOKE_POOF; -extern const LLUUID IMG_BIG_EXPLOSION_1; -extern const LLUUID IMG_BIG_EXPLOSION_2; +LL_COMMON_API extern const LLUUID IMG_BIG_EXPLOSION_1; +LL_COMMON_API extern const LLUUID IMG_BIG_EXPLOSION_2; -extern const LLUUID IMG_BLOOM1; -extern const LLUUID TERRAIN_DIRT_DETAIL; -extern const LLUUID TERRAIN_GRASS_DETAIL; -extern const LLUUID TERRAIN_MOUNTAIN_DETAIL; -extern const LLUUID TERRAIN_ROCK_DETAIL; +LL_COMMON_API extern const LLUUID IMG_BLOOM1; +LL_COMMON_API extern const LLUUID TERRAIN_DIRT_DETAIL; +LL_COMMON_API extern const LLUUID TERRAIN_GRASS_DETAIL; +LL_COMMON_API extern const LLUUID TERRAIN_MOUNTAIN_DETAIL; +LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL; -extern const LLUUID DEFAULT_WATER_NORMAL; +LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; #endif diff --git a/linden/indra/llcommon/indra_constants.h b/linden/indra/llcommon/indra_constants.h index 34d1538d3..279d280df 100644 --- a/linden/indra/llcommon/indra_constants.h +++ b/linden/indra/llcommon/indra_constants.h @@ -263,15 +263,15 @@ const U8 GOD_LIKE = 1; const U8 GOD_NOT = 0; // "agent id" for things that should be done to ALL agents -extern const LLUUID LL_UUID_ALL_AGENTS; +LL_COMMON_API extern const LLUUID LL_UUID_ALL_AGENTS; // inventory library owner -extern const LLUUID ALEXANDRIA_LINDEN_ID; +LL_COMMON_API extern const LLUUID ALEXANDRIA_LINDEN_ID; -extern const LLUUID GOVERNOR_LINDEN_ID; -extern const LLUUID REALESTATE_LINDEN_ID; +LL_COMMON_API extern const LLUUID GOVERNOR_LINDEN_ID; +LL_COMMON_API extern const LLUUID REALESTATE_LINDEN_ID; // Maintenance's group id. -extern const LLUUID MAINTENANCE_GROUP_ID; +LL_COMMON_API extern const LLUUID MAINTENANCE_GROUP_ID; // Flags for kick message const U32 KICK_FLAGS_DEFAULT = 0x0; diff --git a/linden/indra/llcommon/linden_common.h b/linden/indra/llcommon/linden_common.h index 25dd62947..bf844b99b 100644 --- a/linden/indra/llcommon/linden_common.h +++ b/linden/indra/llcommon/linden_common.h @@ -51,16 +51,16 @@ #include <cstdio> #include <cstdlib> #include <ctime> -#include <iostream> -#include <fstream> +#include <iosfwd> -// Work Microsoft compiler warnings +// Work around Microsoft compiler warnings in STL headers #ifdef LL_WINDOWS #pragma warning (disable : 4702) // unreachable code #pragma warning (disable : 4244) // conversion from time_t to S32 #endif // LL_WINDOWS -#include <algorithm> +// *TODO: Eliminate these, most library .cpp files don't need them. +// Add them to llviewerprecompiledheaders.h if necessary. #include <list> #include <map> #include <vector> @@ -76,18 +76,21 @@ #pragma warning (disable : 4512) // assignment operator could not be generated #pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) ) #pragma warning (disable : 4265) // boost 1.36.0, non-virtual destructor in boost::exception_detail::* + +// Reenable warnings we disabled above +#pragma warning (3 : 4702) // unreachable code, we like level 3, not 4 +// moved msvc warnings to llpreprocessor.h *TODO - delete this comment after merge conflicts are unlikely -brad #endif // LL_WINDOWS // Linden only libs in alpha-order other than stdtypes.h +// *NOTE: Please keep includes here to a minimum, see above. #include "stdtypes.h" #include "lldefs.h" #include "llerror.h" #include "llextendedstatus.h" -#include "llfasttimer.h" +// Don't do this, adds 15K lines of header code to every library file. +//#include "llfasttimer.h" #include "llfile.h" #include "llformat.h" -#include "llstring.h" -#include "llsys.h" -#include "lltimer.h" #endif diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp index 199315f34..e269f59d6 100644 --- a/linden/indra/llcommon/llapp.cpp +++ b/linden/indra/llcommon/llapp.cpp @@ -420,7 +420,7 @@ void LLApp::incSigChildCount() int LLApp::getPid() { #if LL_WINDOWS - return 0; + return GetCurrentProcessId(); #else return getpid(); #endif diff --git a/linden/indra/llcommon/llapp.h b/linden/indra/llcommon/llapp.h index f8a593c33..96112c971 100644 --- a/linden/indra/llcommon/llapp.h +++ b/linden/indra/llcommon/llapp.h @@ -34,14 +34,17 @@ #define LL_LLAPP_H #include <map> -#include "llapr.h" #include "llrun.h" #include "llsd.h" // Forward declarations +template <typename Type> class LLAtomic32; +typedef LLAtomic32<U32> LLAtomicU32; class LLErrorThread; -class LLApp; - +class LLLiveFile; +#if LL_LINUX +typedef struct siginfo siginfo_t; +#endif typedef void (*LLAppErrorHandler)(); typedef void (*LLAppChildCallback)(int pid, bool exited, int status); @@ -62,7 +65,7 @@ class LLChildInfo }; #endif -class LLApp +class LL_COMMON_API LLApp { friend class LLErrorThread; public: @@ -189,8 +192,6 @@ class LLApp #if !LL_WINDOWS static U32 getSigChildCount(); static void incSigChildCount(); -#else -#define getpid GetCurrentProcessId #endif static int getPid(); diff --git a/linden/indra/llcommon/llapr.h b/linden/indra/llcommon/llapr.h index 7f770b0ee..2aed51511 100644 --- a/linden/indra/llcommon/llapr.h +++ b/linden/indra/llcommon/llapr.h @@ -48,25 +48,24 @@ #include "apr_atomic.h" #include "llstring.h" -extern apr_thread_mutex_t* gLogMutexp; -extern apr_thread_mutex_t* gCallStacksLogMutexp; +extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; /** * @brief initialize the common apr constructs -- apr itself, the * global pool, and a mutex. */ -void ll_init_apr(); +void LL_COMMON_API ll_init_apr(); /** * @brief Cleanup those common apr constructs. */ -void ll_cleanup_apr(); +void LL_COMMON_API ll_cleanup_apr(); // //LL apr_pool //manage apr_pool_t, destroy allocated apr_pool in the destruction function. // -class LLAPRPool +class LL_COMMON_API LLAPRPool { public: LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ; @@ -92,7 +91,7 @@ class LLAPRPool //which clears memory automatically. //so it can not hold static data or data after memory is cleared // -class LLVolatileAPRPool : protected LLAPRPool +class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool { public: LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); @@ -126,7 +125,7 @@ class LLVolatileAPRPool : protected LLAPRPool * destructor handles the unlock. Instances of this class are * <b>not</b> thread safe. */ -class LLScopedLock : private boost::noncopyable +class LL_COMMON_API LLScopedLock : private boost::noncopyable { public: /** @@ -201,7 +200,7 @@ typedef LLAtomic32<S32> LLAtomicS32; // 2, a global pool. // -class LLAPRFile : boost::noncopyable +class LL_COMMON_API LLAPRFile : boost::noncopyable { // make this non copyable since a copy closes the file private: @@ -257,10 +256,10 @@ class LLAPRFile : boost::noncopyable * APR_SUCCESS. * @return Returns <code>true</code> if status is an error condition. */ -bool ll_apr_warn_status(apr_status_t status); +bool LL_COMMON_API ll_apr_warn_status(apr_status_t status); -void ll_apr_assert_status(apr_status_t status); +void LL_COMMON_API ll_apr_assert_status(apr_status_t status); -extern "C" apr_pool_t* gAPRPoolp; // Global APR memory pool +extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool #endif // LL_LLAPR_H diff --git a/linden/indra/llcommon/llassettype.h b/linden/indra/llcommon/llassettype.h index 4077b8d2c..9f611aec9 100644 --- a/linden/indra/llcommon/llassettype.h +++ b/linden/indra/llcommon/llassettype.h @@ -37,7 +37,7 @@ #include "stdenums.h" // for EDragAndDropType -class LLAssetType +class LL_COMMON_API LLAssetType { public: enum EType diff --git a/linden/indra/llcommon/llbase32.h b/linden/indra/llcommon/llbase32.h index 63a93e11a..47cd893d9 100644 --- a/linden/indra/llcommon/llbase32.h +++ b/linden/indra/llcommon/llbase32.h @@ -34,7 +34,7 @@ #ifndef LLBASE32_H #define LLBASE32_h -class LLBase32 +class LL_COMMON_API LLBase32 { public: static std::string encode(const U8* input, size_t input_size); diff --git a/linden/indra/llcommon/llbase64.h b/linden/indra/llcommon/llbase64.h index 58414bba8..15b27a65d 100644 --- a/linden/indra/llcommon/llbase64.h +++ b/linden/indra/llcommon/llbase64.h @@ -34,7 +34,7 @@ #ifndef LLBASE64_H #define LLBASE64_h -class LLBase64 +class LL_COMMON_API LLBase64 { public: static std::string encode(const U8* input, size_t input_size); diff --git a/linden/indra/llcommon/llcommon.h b/linden/indra/llcommon/llcommon.h index 5f7798833..851d4ac2d 100644 --- a/linden/indra/llcommon/llcommon.h +++ b/linden/indra/llcommon/llcommon.h @@ -38,7 +38,7 @@ #include "lltimer.h" #include "llfile.h" -class LLCommon +class LL_COMMON_API LLCommon { public: static void initClass(); diff --git a/linden/indra/llcommon/llcrc.h b/linden/indra/llcommon/llcrc.h index 27fae7d26..74369062c 100644 --- a/linden/indra/llcommon/llcrc.h +++ b/linden/indra/llcommon/llcrc.h @@ -50,7 +50,7 @@ // llinfos << "File crc: " << crc.getCRC() << llendl; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLCRC +class LL_COMMON_API LLCRC { protected: U32 mCurrent; diff --git a/linden/indra/llcommon/llcriticaldamp.h b/linden/indra/llcommon/llcriticaldamp.h index ad98284a6..13e37d8b7 100644 --- a/linden/indra/llcommon/llcriticaldamp.h +++ b/linden/indra/llcommon/llcriticaldamp.h @@ -38,7 +38,7 @@ #include "llframetimer.h" -class LLCriticalDamp +class LL_COMMON_API LLCriticalDamp { public: LLCriticalDamp(); diff --git a/linden/indra/llcommon/llcursortypes.h b/linden/indra/llcommon/llcursortypes.h index bea70351b..836ecc3c0 100644 --- a/linden/indra/llcommon/llcursortypes.h +++ b/linden/indra/llcommon/llcursortypes.h @@ -77,6 +77,6 @@ enum ECursorType { UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) }; -ECursorType getCursorFromString(const std::string& cursor_string); +LL_COMMON_API ECursorType getCursorFromString(const std::string& cursor_string); #endif // LL_LLCURSORTYPES_H diff --git a/linden/indra/llcommon/lldate.h b/linden/indra/llcommon/lldate.h index 5e1a4910d..d27da79ad 100644 --- a/linden/indra/llcommon/lldate.h +++ b/linden/indra/llcommon/lldate.h @@ -46,7 +46,7 @@ * * The date class represents a point in time after epoch - 1970-01-01. */ -class LLDate +class LL_COMMON_API LLDate { public: /** @@ -153,9 +153,9 @@ class LLDate }; // Helper function to stream out a date -std::ostream& operator<<(std::ostream& s, const LLDate& date); +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLDate& date); // Helper function to stream in a date -std::istream& operator>>(std::istream& s, LLDate& date); +LL_COMMON_API std::istream& operator>>(std::istream& s, LLDate& date); #endif // LL_LLDATE_H diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp index 30b61a916..edc570f34 100644 --- a/linden/indra/llcommon/llerror.cpp +++ b/linden/indra/llcommon/llerror.cpp @@ -58,7 +58,9 @@ #include "llsd.h" #include "llsdserialize.h" #include "llstl.h" +#include "lltimer.h" +extern apr_thread_mutex_t* gCallStacksLogMutexp; namespace { #if !LL_WINDOWS diff --git a/linden/indra/llcommon/llerror.h b/linden/indra/llcommon/llerror.h index 37e922d4b..5a4c64485 100644 --- a/linden/indra/llcommon/llerror.h +++ b/linden/indra/llcommon/llerror.h @@ -131,7 +131,7 @@ namespace LLError class CallSite; - class Log + class LL_COMMON_API Log { public: static bool shouldLog(CallSite&); @@ -140,7 +140,7 @@ namespace LLError static void flush(std::ostringstream*, const CallSite&); }; - class CallSite + class LL_COMMON_API CallSite { // Represents a specific place in the code where a message is logged // This is public because it is used by the macros below. It is not @@ -189,7 +189,7 @@ namespace LLError //LLCallStacks is designed not to be thread-safe. //so try not to use it in multiple parallel threads at same time. //Used in a single thread at a time is fine. - class LLCallStacks + class LL_COMMON_API LLCallStacks { private: static char** sBuffer ; diff --git a/linden/indra/llcommon/llerrorcontrol.h b/linden/indra/llcommon/llerrorcontrol.h index fae7547af..54138b2b0 100644 --- a/linden/indra/llcommon/llerrorcontrol.h +++ b/linden/indra/llcommon/llerrorcontrol.h @@ -52,12 +52,12 @@ class LLSD; namespace LLError { - void initForServer(const std::string& identity); + LL_COMMON_API void initForServer(const std::string& identity); // resets all logging settings to defaults needed by server processes // logs to stderr, syslog, and windows debug log // the identity string is used for in the syslog - void initForApplication(const std::string& dir); + LL_COMMON_API void initForApplication(const std::string& dir); // resets all logging settings to defaults needed by applicaitons // logs to stderr and windows debug log // sets up log configuration from the file logcontrol.xml in dir @@ -68,14 +68,14 @@ namespace LLError Setting a level means log messages at that level or above. */ - void setPrintLocation(bool); - void setDefaultLevel(LLError::ELevel); - void setFunctionLevel(const std::string& function_name, LLError::ELevel); - void setClassLevel(const std::string& class_name, LLError::ELevel); - void setFileLevel(const std::string& file_name, LLError::ELevel); - void setTagLevel(const std::string& file_name, LLError::ELevel); + LL_COMMON_API void setPrintLocation(bool); + LL_COMMON_API void setDefaultLevel(LLError::ELevel); + LL_COMMON_API void setFunctionLevel(const std::string& function_name, LLError::ELevel); + LL_COMMON_API void setClassLevel(const std::string& class_name, LLError::ELevel); + LL_COMMON_API void setFileLevel(const std::string& file_name, LLError::ELevel); + LL_COMMON_API void setTagLevel(const std::string& file_name, LLError::ELevel); - void configure(const LLSD&); + LL_COMMON_API void configure(const LLSD&); // the LLSD can configure all of the settings // usually read automatically from the live errorlog.xml file @@ -85,25 +85,25 @@ namespace LLError */ typedef void(*FatalFunction)(const std::string& message); - void crashAndLoop(const std::string& message); + LL_COMMON_API void crashAndLoop(const std::string& message); // Default fatal funtion: access null pointer and loops forever - void setFatalFunction(FatalFunction); + LL_COMMON_API void setFatalFunction(FatalFunction); // The fatal function will be called when an message of LEVEL_ERROR // is logged. Note: supressing a LEVEL_ERROR message from being logged // (by, for example, setting a class level to LEVEL_NONE), will keep // the that message from causing the fatal funciton to be invoked. typedef std::string (*TimeFunction)(); - std::string utcTime(); + LL_COMMON_API std::string utcTime(); - void setTimeFunction(TimeFunction); + LL_COMMON_API void setTimeFunction(TimeFunction); // The function is use to return the current time, formatted for // display by those error recorders that want the time included. - class Recorder + class LL_COMMON_API Recorder { // An object that handles the actual output or error messages. public: @@ -117,17 +117,17 @@ namespace LLError // included in the text of the message }; - void addRecorder(Recorder*); - void removeRecorder(Recorder*); + LL_COMMON_API void addRecorder(Recorder*); + LL_COMMON_API void removeRecorder(Recorder*); // each error message is passed to each recorder via recordMessage() - void logToFile(const std::string& filename); - void logToFixedBuffer(LLFixedBuffer*); + LL_COMMON_API void logToFile(const std::string& filename); + LL_COMMON_API void logToFixedBuffer(LLFixedBuffer*); // Utilities to add recorders for logging to a file or a fixed buffer // A second call to the same function will remove the logger added // with the first. // Passing the empty string or NULL to just removes any prior. - std::string logFileName(); + LL_COMMON_API std::string logFileName(); // returns name of current logging file, empty string if none @@ -136,11 +136,11 @@ namespace LLError */ class Settings; - Settings* saveAndResetSettings(); - void restoreSettings(Settings *); + LL_COMMON_API Settings* saveAndResetSettings(); + LL_COMMON_API void restoreSettings(Settings *); - std::string abbreviateFile(const std::string& filePath); - int shouldLogCallCount(); + LL_COMMON_API std::string abbreviateFile(const std::string& filePath); + LL_COMMON_API int shouldLogCallCount(); }; diff --git a/linden/indra/llcommon/llerrorthread.cpp b/linden/indra/llcommon/llerrorthread.cpp index 4c779c58c..e2b106aa2 100644 --- a/linden/indra/llcommon/llerrorthread.cpp +++ b/linden/indra/llcommon/llerrorthread.cpp @@ -32,6 +32,7 @@ #include "linden_common.h" #include "llerrorthread.h" #include "llapp.h" +#include "lltimer.h" LLErrorThread::LLErrorThread() : LLThread("Error"), diff --git a/linden/indra/llcommon/llerrorthread.h b/linden/indra/llcommon/llerrorthread.h index f1d6ffc34..3121d2967 100644 --- a/linden/indra/llcommon/llerrorthread.h +++ b/linden/indra/llcommon/llerrorthread.h @@ -35,7 +35,7 @@ #include "llthread.h" -class LLErrorThread : public LLThread +class LL_COMMON_API LLErrorThread : public LLThread { public: LLErrorThread(); diff --git a/linden/indra/llcommon/llevent.h b/linden/indra/llcommon/llevent.h index 60887a060..6b223a8ee 100644 --- a/linden/indra/llcommon/llevent.h +++ b/linden/indra/llcommon/llevent.h @@ -44,7 +44,7 @@ class LLEventDispatcher; class LLObservable; // Abstract event. All events derive from LLEvent -class LLEvent : public LLThreadSafeRefCount +class LL_COMMON_API LLEvent : public LLThreadSafeRefCount { protected: virtual ~LLEvent(); @@ -72,7 +72,7 @@ class LLEvent : public LLThreadSafeRefCount }; // Abstract listener. All listeners derive from LLEventListener -class LLEventListener : public LLThreadSafeRefCount +class LL_COMMON_API LLEventListener : public LLThreadSafeRefCount { protected: virtual ~LLEventListener(); @@ -89,7 +89,7 @@ class LLEventListener : public LLThreadSafeRefCount }; // A listener which tracks references to it and cleans up when it's deallocated -class LLSimpleListener : public LLEventListener +class LL_COMMON_API LLSimpleListener : public LLEventListener { public: void clearDispatchers(); @@ -114,7 +114,7 @@ struct LLListenerEntry // Base class for a dispatcher - an object which listens // to events being fired and relays them to their // appropriate destinations. -class LLEventDispatcher : public LLThreadSafeRefCount +class LL_COMMON_API LLEventDispatcher : public LLThreadSafeRefCount { protected: virtual ~LLEventDispatcher(); @@ -157,7 +157,7 @@ class LLEventDispatcher : public LLThreadSafeRefCount // In order for this class to work properly, it needs // an instance of an LLEventDispatcher to route events to their // listeners. -class LLObservable +class LL_COMMON_API LLObservable { public: // Initialize with the default Dispatcher diff --git a/linden/indra/llcommon/llfasttimer.cpp b/linden/indra/llcommon/llfasttimer.cpp index 4aa23bb47..5f091d5db 100644 --- a/linden/indra/llcommon/llfasttimer.cpp +++ b/linden/indra/llcommon/llfasttimer.cpp @@ -42,6 +42,7 @@ #include <sched.h> #elif LL_DARWIN #include <sys/time.h> +#include "lltimer.h" // get_clock_count() #else #error "architecture not supported" #endif diff --git a/linden/indra/llcommon/llfasttimer.h b/linden/indra/llcommon/llfasttimer.h index 8c1cf4712..602a2f7c7 100644 --- a/linden/indra/llcommon/llfasttimer.h +++ b/linden/indra/llcommon/llfasttimer.h @@ -35,9 +35,9 @@ #define FAST_TIMER_ON 1 -U64 get_cpu_clock_count(); +LL_COMMON_API U64 get_cpu_clock_count(); -class LLFastTimer +class LL_COMMON_API LLFastTimer { public: enum EFastTimerType diff --git a/linden/indra/llcommon/llfile.h b/linden/indra/llcommon/llfile.h index c6092f7b9..ee376054b 100644 --- a/linden/indra/llcommon/llfile.h +++ b/linden/indra/llcommon/llfile.h @@ -70,7 +70,7 @@ typedef struct stat llstat; #include "llstring.h" // safe char* -> std::string conversion -class LLFile +class LL_COMMON_API LLFile { public: // All these functions take UTF8 path/filenames. @@ -95,7 +95,7 @@ class LLFile #if USE_LLFILESTREAMS -class llifstream : public std::basic_istream < char , std::char_traits < char > > +class LL_COMMON_API llifstream : public std::basic_istream < char , std::char_traits < char > > { // input stream associated with a C stream public: @@ -136,7 +136,7 @@ class llifstream : public std::basic_istream < char , std::char_traits < char > }; -class llofstream : public std::basic_ostream< char , std::char_traits < char > > +class LL_COMMON_API llofstream : public std::basic_ostream< char , std::char_traits < char > > { public: typedef std::basic_ostream< char , std::char_traits < char > > _Myt; @@ -185,7 +185,7 @@ class llofstream : public std::basic_ostream< char , std::char_traits < char > > //#define llifstream std::ifstream //#define llofstream std::ofstream -class llifstream : public std::ifstream +class LL_COMMON_API llifstream : public std::ifstream { public: llifstream() : std::ifstream() @@ -203,7 +203,7 @@ class llifstream : public std::ifstream }; -class llofstream : public std::ofstream +class LL_COMMON_API llofstream : public std::ofstream { public: llofstream() : std::ofstream() diff --git a/linden/indra/llcommon/llfindlocale.h b/linden/indra/llcommon/llfindlocale.h index f17c7740f..b812a065d 100644 --- a/linden/indra/llcommon/llfindlocale.h +++ b/linden/indra/llcommon/llfindlocale.h @@ -59,8 +59,8 @@ typedef enum { /* This allocates/fills in a FL_Locale structure with pointers to strings (which should be treated as static), or NULL for inappropriate / undetected fields. */ -FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain); +LL_COMMON_API FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain); /* This should be used to free the struct written by FL_FindLocale */ -void FL_FreeLocale(FL_Locale **locale); +LL_COMMON_API void FL_FreeLocale(FL_Locale **locale); #endif /*__findlocale_h_*/ diff --git a/linden/indra/llcommon/llfixedbuffer.h b/linden/indra/llcommon/llfixedbuffer.h index 992a024df..51d070173 100644 --- a/linden/indra/llcommon/llfixedbuffer.h +++ b/linden/indra/llcommon/llfixedbuffer.h @@ -41,7 +41,7 @@ // Fixed size buffer for console output and other things. -class LLFixedBuffer +class LL_COMMON_API LLFixedBuffer { public: LLFixedBuffer(const U32 max_lines = 20); diff --git a/linden/indra/llcommon/llformat.h b/linden/indra/llcommon/llformat.h index 44c62d971..ad30d4fb1 100644 --- a/linden/indra/llcommon/llformat.h +++ b/linden/indra/llcommon/llformat.h @@ -40,6 +40,6 @@ // *NOTE: buffer limited to 1024, (but vsnprintf prevents overrun) // should perhaps be replaced with boost::format. -std::string llformat(const char *fmt, ...); +LL_COMMON_API std::string llformat(const char *fmt, ...); #endif // LL_LLFORMAT_H diff --git a/linden/indra/llcommon/llframetimer.h b/linden/indra/llcommon/llframetimer.h index 8f51272af..f4775a992 100644 --- a/linden/indra/llcommon/llframetimer.h +++ b/linden/indra/llcommon/llframetimer.h @@ -43,7 +43,7 @@ #include "lltimer.h" #include "timing.h" -class LLFrameTimer +class LL_COMMON_API LLFrameTimer { public: LLFrameTimer() : mStartTime( sFrameTime ), mExpiry(0), mStarted(TRUE) {} diff --git a/linden/indra/llcommon/llheartbeat.h b/linden/indra/llcommon/llheartbeat.h index fecb5b1e5..6f7026970 100644 --- a/linden/indra/llcommon/llheartbeat.h +++ b/linden/indra/llcommon/llheartbeat.h @@ -40,7 +40,7 @@ // Note: Win32 does not support the heartbeat/smackdown system; // heartbeat-delivery turns into a no-op there. -class LLHeartbeat +class LL_COMMON_API LLHeartbeat { public: // secs_between_heartbeat: after a heartbeat is successfully delivered, diff --git a/linden/indra/llcommon/llliveappconfig.h b/linden/indra/llcommon/llliveappconfig.h index 55d84a477..3251a7c50 100644 --- a/linden/indra/llcommon/llliveappconfig.h +++ b/linden/indra/llcommon/llliveappconfig.h @@ -37,7 +37,7 @@ class LLApp; -class LLLiveAppConfig : public LLLiveFile +class LL_COMMON_API LLLiveAppConfig : public LLLiveFile { public: // To use this, instantiate a LLLiveAppConfig object inside your main loop. diff --git a/linden/indra/llcommon/lllivefile.h b/linden/indra/llcommon/lllivefile.h index fddf00622..72f16fd99 100644 --- a/linden/indra/llcommon/lllivefile.h +++ b/linden/indra/llcommon/lllivefile.h @@ -36,7 +36,7 @@ const F32 configFileRefreshRate = 5.0; // seconds -class LLLiveFile +class LL_COMMON_API LLLiveFile { public: LLLiveFile(const std::string &filename, const F32 refresh_period = 5.f); diff --git a/linden/indra/llcommon/lllog.h b/linden/indra/llcommon/lllog.h index 7ac6c8aa4..4b6777bb9 100644 --- a/linden/indra/llcommon/lllog.h +++ b/linden/indra/llcommon/lllog.h @@ -41,7 +41,7 @@ class LLLogImpl; class LLApp; class LLSD; -class LLLog +class LL_COMMON_API LLLog { public: LLLog(LLApp* app); diff --git a/linden/indra/llcommon/llmd5.cpp b/linden/indra/llcommon/llmd5.cpp index 14b4f9f4b..887979bbf 100644 --- a/linden/indra/llcommon/llmd5.cpp +++ b/linden/indra/llcommon/llmd5.cpp @@ -83,6 +83,7 @@ documentation and/or software. #include "llmd5.h" #include <cassert> +#include <iostream> // how many bytes to grab at a time when checking files const int LLMD5::BLOCK_LEN = 4096; diff --git a/linden/indra/llcommon/llmd5.h b/linden/indra/llcommon/llmd5.h index d8bca03e4..df9d7324a 100644 --- a/linden/indra/llcommon/llmd5.h +++ b/linden/indra/llcommon/llmd5.h @@ -80,7 +80,7 @@ const int MD5RAW_BYTES = 16; const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null const int MD5HEX_STR_BYTES = 32; // message system fixed size -class LLMD5 { +class LL_COMMON_API LLMD5 { // first, some types: typedef unsigned int uint4; // assumes integer is 4 words long typedef unsigned short int uint2; // assumes short integer is 2 words long diff --git a/linden/indra/llcommon/llmemory.cpp b/linden/indra/llcommon/llmemory.cpp index a6de3d2d6..74004b019 100644 --- a/linden/indra/llcommon/llmemory.cpp +++ b/linden/indra/llcommon/llmemory.cpp @@ -283,6 +283,11 @@ LLRefCount::LLRefCount() : { } +LLRefCount::LLRefCount(const LLRefCount& other) +: mRef(0) +{ +} + LLRefCount::~LLRefCount() { if (mRef != 0) @@ -290,7 +295,13 @@ LLRefCount::~LLRefCount() llerrs << "deleting non-zero reference" << llendl; } } - + +LLRefCount& LLRefCount::operator=(const LLRefCount&) +{ + // do nothing, since ref count is specific to *this* reference + return *this; +} + //---------------------------------------------------------------------------- #if defined(LL_WINDOWS) diff --git a/linden/indra/llcommon/llmemory.h b/linden/indra/llcommon/llmemory.h index b5c071148..9aa4b857e 100644 --- a/linden/indra/llcommon/llmemory.h +++ b/linden/indra/llcommon/llmemory.h @@ -45,7 +45,7 @@ const U32 LLREFCOUNT_SENTINEL_VALUE = 0xAAAAAAAA; //---------------------------------------------------------------------------- -class LLMemory +class LL_COMMON_API LLMemory { public: static void initClass(); @@ -68,12 +68,12 @@ class LLMemory //---------------------------------------------------------------------------- -class LLRefCount +class LL_COMMON_API LLRefCount { protected: - LLRefCount(const LLRefCount&); // not implemented + LLRefCount(const LLRefCount&); private: - LLRefCount&operator=(const LLRefCount&); // not implemented + LLRefCount&operator=(const LLRefCount&); protected: virtual ~LLRefCount(); // use unref() @@ -467,6 +467,6 @@ class LLSingleton // Return the resident set size of the current process, in bytes. // Return value is zero if not known. -U64 getCurrentRSS(); +LL_COMMON_API U64 getCurrentRSS(); #endif diff --git a/linden/indra/llcommon/llmemorystream.h b/linden/indra/llcommon/llmemorystream.h index f3486324c..fa0f5d22f 100644 --- a/linden/indra/llcommon/llmemorystream.h +++ b/linden/indra/llcommon/llmemorystream.h @@ -52,7 +52,7 @@ * be careful to always pass in a valid memory location that exists * for at least as long as this streambuf. */ -class LLMemoryStreamBuf : public std::streambuf +class LL_COMMON_API LLMemoryStreamBuf : public std::streambuf { public: LLMemoryStreamBuf(const U8* start, S32 length); @@ -74,7 +74,7 @@ class LLMemoryStreamBuf : public std::streambuf * be careful to always pass in a valid memory location that exists * for at least as long as this streambuf. */ -class LLMemoryStream : public std::istream +class LL_COMMON_API LLMemoryStream : public std::istream { public: LLMemoryStream(const U8* start, S32 length); diff --git a/linden/indra/llcommon/llmemtype.h b/linden/indra/llcommon/llmemtype.h index a9ebc2062..d4cc67ea4 100644 --- a/linden/indra/llcommon/llmemtype.h +++ b/linden/indra/llcommon/llmemtype.h @@ -57,7 +57,7 @@ static void operator delete(void* p) { ll_release(p); } //---------------------------------------------------------------------------- -class LLMemType +class LL_COMMON_API LLMemType { public: // Also update sTypeDesc in llmemory.cpp diff --git a/linden/indra/llcommon/llmetrics.h b/linden/indra/llcommon/llmetrics.h index 1d91e8c8a..f6f49eb45 100644 --- a/linden/indra/llcommon/llmetrics.h +++ b/linden/indra/llcommon/llmetrics.h @@ -38,7 +38,7 @@ class LLMetricsImpl; class LLSD; -class LLMetrics +class LL_COMMON_API LLMetrics { public: LLMetrics(); diff --git a/linden/indra/llcommon/llmortician.h b/linden/indra/llcommon/llmortician.h index 247632f52..55a101a97 100644 --- a/linden/indra/llcommon/llmortician.h +++ b/linden/indra/llcommon/llmortician.h @@ -35,7 +35,7 @@ #include "stdtypes.h" -class LLMortician +class LL_COMMON_API LLMortician { public: LLMortician() { mIsDead = FALSE; } diff --git a/linden/indra/llcommon/llpreprocessor.h b/linden/indra/llcommon/llpreprocessor.h index 2e4fd4787..6886e3a34 100644 --- a/linden/indra/llcommon/llpreprocessor.h +++ b/linden/indra/llcommon/llpreprocessor.h @@ -92,47 +92,63 @@ #endif - // Deal with the differeneces on Windows -#if LL_MSVC -namespace snprintf_hack -{ - int snprintf(char *str, size_t size, const char *format, ...); -} - -// #define snprintf safe_snprintf /* Flawfinder: ignore */ -using snprintf_hack::snprintf; -#endif // LL_MSVC - -// Static linking with apr on windows needs to be declared. -#ifdef LL_WINDOWS -#ifndef APR_DECLARE_STATIC -#define APR_DECLARE_STATIC // For APR on Windows -#endif -#ifndef APU_DECLARE_STATIC -#define APU_DECLARE_STATIC // For APR util on Windows -#endif -#endif - #if defined(LL_WINDOWS) #define BOOST_REGEX_NO_LIB 1 #define CURL_STATICLIB 1 #define XML_STATIC #endif // LL_WINDOWS - // Deal with VC6 problems #if LL_MSVC #pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4. #pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4. #pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4. //#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4. +#pragma warning( 3 : 4263 ) // 'function' : member function does not override any base class virtual member function +#pragma warning( 3 : 4264 ) // "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden" #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" -#pragma warning( disable : 4786 ) // silly MS warning deep inside their <map> include file +//#pragma warning( disable : 4265 ) // boost 1.36.0, non-virtual destructor in boost::exception_detail::* +#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden +#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored #pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file #pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. #pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) #pragma warning( disable : 4996 ) // warning: deprecated + +// Linker optimization with "extern template" generates these warnings +#pragma warning( disable : 4231 ) // nonstandard extension used : 'extern' before template explicit instantiation +#pragma warning( disable : 4506 ) // no definition for inline function + +// level 4 warnings that we need to disable: +#pragma warning (disable : 4100) // unreferenced formal parameter +#pragma warning (disable : 4127) // conditional expression is constant (e.g. while(1) ) +#pragma warning (disable : 4244) // possible loss of data on conversions +#pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template +#pragma warning (disable : 4512) // assignment operator could not be generated +#pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) ) + +#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class +#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class #endif // LL_MSVC +#if LL_WINDOWS +#define LL_DLLEXPORT __declspec(dllexport) +#define LL_DLLIMPORT __declspec(dllimport) +#elif LL_LINUX +#define LL_DLLEXPORT __attribute__ ((visibility("default"))) +#define LL_DLLIMPORT +#else +#define LL_DLLEXPORT +#define LL_DLLIMPORT +#endif // LL_WINDOWS + +#ifdef llcommon_EXPORTS +// Compiling llcommon (shared) +#define LL_COMMON_API LL_DLLEXPORT +#else // llcommon_EXPORTS +// Using llcommon (shared) +#define LL_COMMON_API LL_DLLIMPORT +#endif // llcommon_EXPORTS + #endif // not LL_LINDEN_PREPROCESSOR_H diff --git a/linden/indra/llcommon/llprocesslauncher.h b/linden/indra/llcommon/llprocesslauncher.h index 9cdb0f68a..b72be2713 100644 --- a/linden/indra/llcommon/llprocesslauncher.h +++ b/linden/indra/llcommon/llprocesslauncher.h @@ -43,7 +43,7 @@ It also keeps track of whether the process is still running, and can kill it if required. */ -class LLProcessLauncher +class LL_COMMON_API LLProcessLauncher { LOG_CLASS(LLProcessLauncher); public: diff --git a/linden/indra/llcommon/llqueuedthread.cpp b/linden/indra/llcommon/llqueuedthread.cpp index caf4c2a89..bee95be62 100644 --- a/linden/indra/llcommon/llqueuedthread.cpp +++ b/linden/indra/llcommon/llqueuedthread.cpp @@ -32,6 +32,7 @@ #include "linden_common.h" #include "llqueuedthread.h" #include "llstl.h" +#include "lltimer.h" //============================================================================ diff --git a/linden/indra/llcommon/llqueuedthread.h b/linden/indra/llcommon/llqueuedthread.h index aa7c6e4f6..e0e0f1bfe 100644 --- a/linden/indra/llcommon/llqueuedthread.h +++ b/linden/indra/llcommon/llqueuedthread.h @@ -47,7 +47,7 @@ // Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small // It is assumed that LLQueuedThreads are rarely created/destroyed. -class LLQueuedThread : public LLThread +class LL_COMMON_API LLQueuedThread : public LLThread { //------------------------------------------------------------------------ public: @@ -80,7 +80,7 @@ class LLQueuedThread : public LLThread //------------------------------------------------------------------------ public: - class QueuedRequest : public LLSimpleHashEntry<handle_t> + class LL_COMMON_API QueuedRequest : public LLSimpleHashEntry<handle_t> { friend class LLQueuedThread; diff --git a/linden/indra/llcommon/llrand.h b/linden/indra/llcommon/llrand.h index d12597bb5..73ea17956 100644 --- a/linden/indra/llcommon/llrand.h +++ b/linden/indra/llcommon/llrand.h @@ -65,32 +65,32 @@ /** *@brief Generate a float from [0, RAND_MAX). */ -S32 ll_rand(); +LL_COMMON_API S32 ll_rand(); /** *@brief Generate a float from [0, val) or (val, 0]. */ -S32 ll_rand(S32 val); +LL_COMMON_API S32 ll_rand(S32 val); /** *@brief Generate a float from [0, 1.0). */ -F32 ll_frand(); +LL_COMMON_API F32 ll_frand(); /** *@brief Generate a float from [0, val) or (val, 0]. */ -F32 ll_frand(F32 val); +LL_COMMON_API F32 ll_frand(F32 val); /** *@brief Generate a double from [0, 1.0). */ -F64 ll_drand(); +LL_COMMON_API F64 ll_drand(); /** *@brief Generate a double from [0, val) or (val, 0]. */ -F64 ll_drand(F64 val); +LL_COMMON_API F64 ll_drand(F64 val); /** * @brief typedefs for good boost lagged fibonacci. diff --git a/linden/indra/llcommon/llrun.h b/linden/indra/llcommon/llrun.h index 77b23d905..0f8d51d81 100644 --- a/linden/indra/llcommon/llrun.h +++ b/linden/indra/llcommon/llrun.h @@ -38,6 +38,8 @@ #include <vector> #include <boost/shared_ptr.hpp> +#include "llpreprocessor.h" + class LLRunnable; /** @@ -48,7 +50,7 @@ class LLRunnable; * which are scheduled to run on a repeating or one time basis. * @see LLRunnable */ -class LLRunner +class LL_COMMON_API LLRunner { public: /** @@ -149,7 +151,7 @@ class LLRunner * something useful. * @see LLRunner */ -class LLRunnable +class LL_COMMON_API LLRunnable { public: LLRunnable(); diff --git a/linden/indra/llcommon/llsd.cpp b/linden/indra/llcommon/llsd.cpp index 2cc94c291..be40bb634 100644 --- a/linden/indra/llcommon/llsd.cpp +++ b/linden/indra/llcommon/llsd.cpp @@ -75,7 +75,7 @@ class LLSD::Impl ///< This constructor is used for static objects and causes the // suppresses adjusting the debugging counters when they are // finally initialized. - + virtual ~Impl(); bool shared() const { return mUseCount > 1; } @@ -162,6 +162,7 @@ namespace virtual LLSD::Type type() const { return T; } + using LLSD::Impl::assign; virtual void assign(LLSD::Impl*& var, DataRef value) { if (shared()) { @@ -348,6 +349,10 @@ namespace virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } + using LLSD::Impl::get; // Unhiding get(LLSD::Integer) + using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) + using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) + virtual bool has(const LLSD::String&) const; virtual LLSD get(const LLSD::String&) const; LLSD& insert(const LLSD::String& k, const LLSD& v); @@ -440,6 +445,11 @@ namespace virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } virtual int size() const; + + using LLSD::Impl::get; // Unhiding get(LLSD::Integer) + using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) + using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) + virtual LLSD get(LLSD::Integer) const; void set(LLSD::Integer, const LLSD&); LLSD& insert(LLSD::Integer, const LLSD&); diff --git a/linden/indra/llcommon/llsd.h b/linden/indra/llcommon/llsd.h index d2845a375..552bb5749 100644 --- a/linden/indra/llcommon/llsd.h +++ b/linden/indra/llcommon/llsd.h @@ -89,7 +89,7 @@ @nosubgrouping */ -class LLSD +class LL_COMMON_API LLSD { public: LLSD(); ///< initially Undefined @@ -387,7 +387,7 @@ struct llsd_select_string : public std::unary_function<LLSD, LLSD::String> } }; -std::ostream& operator<<(std::ostream& s, const LLSD& llsd); +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd); /** QUESTIONS & TO DOS - Would Binary be more convenient as usigned char* buffer semantics? diff --git a/linden/indra/llcommon/llsdserialize.h b/linden/indra/llcommon/llsdserialize.h index f7cd91bb7..a01b6dcd3 100644 --- a/linden/indra/llcommon/llsdserialize.h +++ b/linden/indra/llcommon/llsdserialize.h @@ -43,7 +43,7 @@ * @class LLSDParser * @brief Abstract base class for LLSD parsers. */ -class LLSDParser : public LLRefCount +class LL_COMMON_API LLSDParser : public LLRefCount { protected: /** @@ -220,7 +220,7 @@ class LLSDParser : public LLRefCount * @class LLSDNotationParser * @brief Parser which handles the original notation format for LLSD. */ -class LLSDNotationParser : public LLSDParser +class LL_COMMON_API LLSDNotationParser : public LLSDParser { protected: /** @@ -293,7 +293,7 @@ class LLSDNotationParser : public LLSDParser * @class LLSDXMLParser * @brief Parser which handles XML format LLSD. */ -class LLSDXMLParser : public LLSDParser +class LL_COMMON_API LLSDXMLParser : public LLSDParser { protected: /** @@ -341,7 +341,7 @@ class LLSDXMLParser : public LLSDParser * @class LLSDBinaryParser * @brief Parser which handles binary formatted LLSD. */ -class LLSDBinaryParser : public LLSDParser +class LL_COMMON_API LLSDBinaryParser : public LLSDParser { protected: /** @@ -406,7 +406,7 @@ class LLSDBinaryParser : public LLSDParser * @class LLSDFormatter * @brief Abstract base class for formatting LLSD. */ -class LLSDFormatter : public LLRefCount +class LL_COMMON_API LLSDFormatter : public LLRefCount { protected: /** @@ -478,7 +478,7 @@ class LLSDFormatter : public LLRefCount * @class LLSDNotationFormatter * @brief Formatter which outputs the original notation format for LLSD. */ -class LLSDNotationFormatter : public LLSDFormatter +class LL_COMMON_API LLSDNotationFormatter : public LLSDFormatter { protected: /** @@ -519,7 +519,7 @@ class LLSDNotationFormatter : public LLSDFormatter * @class LLSDXMLFormatter * @brief Formatter which outputs the LLSD as XML. */ -class LLSDXMLFormatter : public LLSDFormatter +class LL_COMMON_API LLSDXMLFormatter : public LLSDFormatter { protected: /** @@ -587,7 +587,7 @@ class LLSDXMLFormatter : public LLSDFormatter * Map: '{' + 4 byte integer size every(key + value) + '}'<br> * map keys are serialized as 'k' + 4 byte integer size + string */ -class LLSDBinaryFormatter : public LLSDFormatter +class LL_COMMON_API LLSDBinaryFormatter : public LLSDFormatter { protected: /** @@ -676,7 +676,7 @@ typedef LLSDOStreamer<LLSDXMLFormatter> LLSDXMLStreamer; * @class LLSDSerialize * @brief Serializer / deserializer for the various LLSD formats */ -class LLSDSerialize +class LL_COMMON_API LLSDSerialize { public: enum ELLSD_Serialize diff --git a/linden/indra/llcommon/llsdserialize_xml.cpp b/linden/indra/llcommon/llsdserialize_xml.cpp index c12ca350d..33206b46d 100644 --- a/linden/indra/llcommon/llsdserialize_xml.cpp +++ b/linden/indra/llcommon/llsdserialize_xml.cpp @@ -562,7 +562,7 @@ void LLSDXMLParser::Impl::parsePart(const char* buf, int len) #ifdef XML_PARSER_PERFORMANCE_TESTS -extern U64 totalTime(); +extern LL_COMMON_API U64 totalTime(); U64 readElementTime = 0; U64 startElementTime = 0; U64 endElementTime = 0; diff --git a/linden/indra/llcommon/llsdutil.h b/linden/indra/llcommon/llsdutil.h index b67ad521e..4740a308e 100644 --- a/linden/indra/llcommon/llsdutil.h +++ b/linden/indra/llcommon/llsdutil.h @@ -68,28 +68,28 @@ LLSD ll_sd_from_color4(const LLColor4& c); LLColor4 ll_color4_from_sd(const LLSD& sd); // U32 -LLSD ll_sd_from_U32(const U32); -U32 ll_U32_from_sd(const LLSD& sd); +LL_COMMON_API LLSD ll_sd_from_U32(const U32); +LL_COMMON_API U32 ll_U32_from_sd(const LLSD& sd); // U64 -LLSD ll_sd_from_U64(const U64); -U64 ll_U64_from_sd(const LLSD& sd); +LL_COMMON_API LLSD ll_sd_from_U64(const U64); +LL_COMMON_API U64 ll_U64_from_sd(const LLSD& sd); // IP Address -LLSD ll_sd_from_ipaddr(const U32); -U32 ll_ipaddr_from_sd(const LLSD& sd); +LL_COMMON_API LLSD ll_sd_from_ipaddr(const U32); +LL_COMMON_API U32 ll_ipaddr_from_sd(const LLSD& sd); // Binary to string -LLSD ll_string_from_binary(const LLSD& sd); +LL_COMMON_API LLSD ll_string_from_binary(const LLSD& sd); //String to binary -LLSD ll_binary_from_string(const LLSD& sd); +LL_COMMON_API LLSD ll_binary_from_string(const LLSD& sd); // Serializes sd to static buffer and returns pointer, useful for gdb debugging. -char* ll_print_sd(const LLSD& sd); +LL_COMMON_API char* ll_print_sd(const LLSD& sd); // Serializes sd to static buffer and returns pointer, using "pretty printing" mode. -char* ll_pretty_print_sd(const LLSD& sd); +LL_COMMON_API char* ll_pretty_print_sd(const LLSD& sd); //compares the structure of an LLSD to a template LLSD and stores the //"valid" values in a 3rd LLSD. Default values @@ -98,7 +98,7 @@ char* ll_pretty_print_sd(const LLSD& sd); //Returns false if the test is of same type but values differ in type //Otherwise, returns true -BOOL compare_llsd_with_template( +LL_COMMON_API BOOL compare_llsd_with_template( const LLSD& llsd_to_test, const LLSD& template_llsd, LLSD& resultant_llsd); diff --git a/linden/indra/llcommon/llsecondlifeurls.h b/linden/indra/llcommon/llsecondlifeurls.h index 9c64b5766..e3932d0de 100644 --- a/linden/indra/llcommon/llsecondlifeurls.h +++ b/linden/indra/llcommon/llsecondlifeurls.h @@ -34,14 +34,14 @@ #define LL_LLSECONDLIFEURLS_H -extern const std::string AUCTION_URL; +LL_COMMON_API extern const std::string AUCTION_URL; -extern const std::string EVENTS_URL; +LL_COMMON_API extern const std::string EVENTS_URL; // Currency page -extern const std::string BUY_CURRENCY_URL; +LL_COMMON_API extern const std::string BUY_CURRENCY_URL; // Release Notes Redirect URL for Server and Viewer -extern const std::string RELEASE_NOTES_BASE_URL; +LL_COMMON_API extern const std::string RELEASE_NOTES_BASE_URL; #endif diff --git a/linden/indra/llcommon/llsimplehash.h b/linden/indra/llcommon/llsimplehash.h index 0ba2a3014..5df93b646 100644 --- a/linden/indra/llcommon/llsimplehash.h +++ b/linden/indra/llcommon/llsimplehash.h @@ -64,7 +64,7 @@ class LLSimpleHashEntry }; template <typename HASH_KEY_TYPE, int TABLE_SIZE> -class LLSimpleHash +class LL_COMMON_API LLSimpleHash { public: LLSimpleHash() diff --git a/linden/indra/llcommon/llstat.h b/linden/indra/llcommon/llstat.h index 66521a31c..951091b47 100644 --- a/linden/indra/llcommon/llstat.h +++ b/linden/indra/llcommon/llstat.h @@ -52,7 +52,7 @@ class LLSD; // amounts of time with very low memory cost. // -class LLStatAccum +class LL_COMMON_API LLStatAccum { protected: LLStatAccum(bool use_frame_timer); @@ -109,7 +109,7 @@ class LLStatAccum F64 mLastSampleValue; }; -class LLStatMeasure : public LLStatAccum +class LL_COMMON_API LLStatMeasure : public LLStatAccum // gathers statistics about things that are measured // ex.: tempature, time dilation { @@ -124,7 +124,7 @@ class LLStatMeasure : public LLStatAccum }; -class LLStatRate : public LLStatAccum +class LL_COMMON_API LLStatRate : public LLStatAccum // gathers statistics about things that can be counted over time // ex.: LSL instructions executed, messages sent, simulator frames completed // renders it in terms of rate of thing per second @@ -140,7 +140,7 @@ class LLStatRate : public LLStatAccum }; -class LLStatTime : public LLStatAccum +class LL_COMMON_API LLStatTime : public LLStatAccum // gathers statistics about time spent in a block of code // measure average duration per second in the block { @@ -171,7 +171,7 @@ class LLStatTime : public LLStatAccum // Use this class on the stack to record statistics about an area of code -class LLPerfBlock +class LL_COMMON_API LLPerfBlock { public: struct StatEntry @@ -213,7 +213,7 @@ class LLPerfBlock // ---------------------------------------------------------------------------- -class LLPerfStats +class LL_COMMON_API LLPerfStats { public: LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0); @@ -249,7 +249,7 @@ class LLPerfStats }; // ---------------------------------------------------------------------------- -class LLStat +class LL_COMMON_API LLStat { public: LLStat(const U32 num_bins = 32, BOOL use_frame_timer = FALSE); diff --git a/linden/indra/llcommon/llstreamtools.h b/linden/indra/llcommon/llstreamtools.h index a6dc4d51e..371fac57a 100644 --- a/linden/indra/llcommon/llstreamtools.h +++ b/linden/indra/llcommon/llstreamtools.h @@ -39,23 +39,23 @@ // unless specifed otherwise these all return input_stream.good() // skips spaces and tabs -bool skip_whitespace(std::istream& input_stream); +LL_COMMON_API bool skip_whitespace(std::istream& input_stream); // skips whitespace and newlines -bool skip_emptyspace(std::istream& input_stream); +LL_COMMON_API bool skip_emptyspace(std::istream& input_stream); // skips emptyspace and lines that start with a # -bool skip_comments_and_emptyspace(std::istream& input_stream); +LL_COMMON_API bool skip_comments_and_emptyspace(std::istream& input_stream); // skips to character after next newline -bool skip_line(std::istream& input_stream); +LL_COMMON_API bool skip_line(std::istream& input_stream); // skips to beginning of next non-emptyspace -bool skip_to_next_word(std::istream& input_stream); +LL_COMMON_API bool skip_to_next_word(std::istream& input_stream); // skips to character after the end of next keyword // a 'keyword' is defined as the first word on a line -bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream); +LL_COMMON_API bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream); // skip_to_start_of_next_keyword() is disabled -- might tickle corruption bug // in windows iostream @@ -65,14 +65,14 @@ bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream // characters are pulled out of input_stream and appended to output_string // returns result of input_stream.good() after characters are pulled -bool get_word(std::string& output_string, std::istream& input_stream); -bool get_line(std::string& output_string, std::istream& input_stream); +LL_COMMON_API bool get_word(std::string& output_string, std::istream& input_stream); +LL_COMMON_API bool get_line(std::string& output_string, std::istream& input_stream); // characters are pulled out of input_stream (up to a max of 'n') // and appended to output_string // returns result of input_stream.good() after characters are pulled -bool get_word(std::string& output_string, std::istream& input_stream, int n); -bool get_line(std::string& output_string, std::istream& input_stream, int n); +LL_COMMON_API bool get_word(std::string& output_string, std::istream& input_stream, int n); +LL_COMMON_API bool get_line(std::string& output_string, std::istream& input_stream, int n); // unget_line() is disabled -- might tickle corruption bug in windows iostream //// backs up the input_stream by line_size + 1 characters @@ -82,28 +82,28 @@ bool get_line(std::string& output_string, std::istream& input_stream, int n); // removes the last char in 'line' if it matches 'c' // returns true if removed last char -bool remove_last_char(char c, std::string& line); +LL_COMMON_API bool remove_last_char(char c, std::string& line); // replaces escaped characters with the correct characters from left to right // "\\" ---> '\\' // "\n" ---> '\n' -void unescape_string(std::string& line); +LL_COMMON_API void unescape_string(std::string& line); // replaces unescaped characters with expanded equivalents from left to right // '\\' ---> "\\" // '\n' ---> "\n" -void escape_string(std::string& line); +LL_COMMON_API void escape_string(std::string& line); // replaces each '\n' character with ' ' -void replace_newlines_with_whitespace(std::string& line); +LL_COMMON_API void replace_newlines_with_whitespace(std::string& line); // erases any double-quote characters in line -void remove_double_quotes(std::string& line); +LL_COMMON_API void remove_double_quotes(std::string& line); // the 'keyword' is defined as the first word on a line // the 'value' is everything after the keyword on the same line // starting at the first non-whitespace and ending right before the newline -void get_keyword_and_value(std::string& keyword, +LL_COMMON_API void get_keyword_and_value(std::string& keyword, std::string& value, const std::string& line); @@ -111,13 +111,13 @@ void get_keyword_and_value(std::string& keyword, // read anymore or until we hit the count. Some istream // implimentations have a max that they will read. // Returns the number of bytes read. -std::streamsize fullread( +LL_COMMON_API std::streamsize fullread( std::istream& istr, char* buf, std::streamsize requested); -std::istream& operator>>(std::istream& str, const char *tocheck); +LL_COMMON_API std::istream& operator>>(std::istream& str, const char *tocheck); #endif diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index bab89b12d..3f2c8d85d 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -144,7 +144,7 @@ struct char_traits<U16> }; #endif -class LLStringOps +class LL_COMMON_API LLStringOps { public: static char toUpper(char elem) { return toupper((unsigned char)elem); } @@ -179,8 +179,8 @@ class LLStringOps * @brief Return a string constructed from in without crashing if the * pointer is NULL. */ -std::string ll_safe_string(const char* in); -std::string ll_safe_string(const char* in, S32 maxlen); +std::string LL_COMMON_API ll_safe_string(const char* in); +std::string LL_COMMON_API ll_safe_string(const char* in, S32 maxlen); // Allowing assignments from non-strings into format_map_t is apparently @@ -349,7 +349,7 @@ inline std::string chop_tail_copy( * @brief This translates a nybble stored as a hex value from 0-f back * to a nybble in the low order bits of the return byte. */ -U8 hex_as_nybble(char hex); +LL_COMMON_API U8 hex_as_nybble(char hex); /** * @brief read the contents of a file into a string. @@ -360,7 +360,7 @@ U8 hex_as_nybble(char hex); * @param filename The full name of the file to read. * @return Returns true on success. If false, str is unmodified. */ -bool _read_file_into_string(std::string& str, const std::string& filename); +LL_COMMON_API bool _read_file_into_string(std::string& str, const std::string& filename); /** * Unicode support @@ -369,52 +369,52 @@ bool _read_file_into_string(std::string& str, const std::string& filename); // Make the incoming string a utf8 string. Replaces any unknown glyph // with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest // of the data may not be recovered. -std::string rawstr_to_utf8(const std::string& raw); +LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw); // // We should never use UTF16 except when communicating with Win32! // typedef std::basic_string<U16> llutf16string; -LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len); -LLWString utf16str_to_wstring(const llutf16string &utf16str); +LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len); +LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str); -llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); -llutf16string wstring_to_utf16str(const LLWString &utf32str); +LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); +LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str); -llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); -llutf16string utf8str_to_utf16str ( const std::string& utf8str ); +LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); +LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str ); -LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); -LLWString utf8str_to_wstring(const std::string &utf8str); +LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); +LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str); // Same function, better name. JC inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } // -S32 wchar_to_utf8chars(llwchar inchar, char* outchars); +LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars); -std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); -std::string wstring_to_utf8str(const LLWString &utf32str); +LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); +LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str); -std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len); -std::string utf16str_to_utf8str(const llutf16string &utf16str); +LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len); +LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str); // Length of this UTF32 string in bytes when transformed to UTF8 -S32 wstring_utf8_length(const LLWString& wstr); +LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr); // Length in bytes of this wide char in a UTF8 string -S32 wchar_utf8_length(const llwchar wc); +LL_COMMON_API S32 wchar_utf8_length(const llwchar wc); -std::string utf8str_tolower(const std::string& utf8str); +LL_COMMON_API std::string utf8str_tolower(const std::string& utf8str); // Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string. -S32 utf16str_wstring_length(const llutf16string &utf16str, S32 len); +LL_COMMON_API S32 utf16str_wstring_length(const llutf16string &utf16str, S32 len); // Length in utf16string (UTF-16) of wlen wchars beginning at woffset. -S32 wstring_utf16_length(const LLWString & wstr, S32 woffset, S32 wlen); +LL_COMMON_API S32 wstring_utf16_length(const LLWString & wstr, S32 woffset, S32 wlen); // Length in wstring (i.e., llwchar count) of a part of a wstring specified by utf16 length (i.e., utf16 units.) -S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = NULL); +LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = NULL); /** * @brief Properly truncate a utf8 string to a maximum byte count. @@ -426,11 +426,11 @@ S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset * @param max_len The maximum number of bytes in the return value. * @return Returns a valid utf8 string with byte count <= max_len. */ -std::string utf8str_truncate(const std::string& utf8str, const S32 max_len); +LL_COMMON_API std::string utf8str_truncate(const std::string& utf8str, const S32 max_len); -std::string utf8str_trim(const std::string& utf8str); +LL_COMMON_API std::string utf8str_trim(const std::string& utf8str); -S32 utf8str_compare_insensitive( +LL_COMMON_API S32 utf8str_compare_insensitive( const std::string& lhs, const std::string& rhs); @@ -441,17 +441,17 @@ S32 utf8str_compare_insensitive( * @param target_char The wchar to be replaced * @param replace_char The wchar which is written on replace */ -std::string utf8str_substChar( +LL_COMMON_API std::string utf8str_substChar( const std::string& utf8str, const llwchar target_char, const llwchar replace_char); -std::string utf8str_makeASCII(const std::string& utf8str); +LL_COMMON_API std::string utf8str_makeASCII(const std::string& utf8str); // Hack - used for evil notecards. -std::string mbcsstring_makeASCII(const std::string& str); +LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str); -std::string utf8str_removeCRLF(const std::string& utf8str); +LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); #if LL_WINDOWS @@ -476,14 +476,21 @@ std::string utf8str_removeCRLF(const std::string& utf8str); * formatted string. * */ -int safe_snprintf(char* str, size_t size, const char* format, ...); + +// Deal with the differeneces on Windows +namespace snprintf_hack +{ + LL_COMMON_API int snprintf(char *str, size_t size, const char *format, ...); +} + +using snprintf_hack::snprintf; /** * @brief Convert a wide string to std::string * * This replaces the unsafe W2A macro from ATL. */ -std::string ll_convert_wide_to_string(const wchar_t* in); +LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); //@} #endif // LL_WINDOWS @@ -506,7 +513,7 @@ namespace LLStringFn * with zero non-printable characters. * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. */ - void replace_nonprintable_in_ascii( + LL_COMMON_API void replace_nonprintable_in_ascii( std::basic_string<char>& string, char replacement); @@ -520,7 +527,7 @@ namespace LLStringFn * with zero non-printable characters and zero pipe characters. * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. */ - void replace_nonprintable_and_pipe_in_ascii(std::basic_string<char>& str, + LL_COMMON_API void replace_nonprintable_and_pipe_in_ascii(std::basic_string<char>& str, char replacement); @@ -529,7 +536,7 @@ namespace LLStringFn * Returns a copy of the string with those characters removed. * Works with US ASCII and UTF-8 encoded strings. JC */ - std::string strip_invalid_xml(const std::string& input); + LL_COMMON_API std::string strip_invalid_xml(const std::string& input); /** @@ -540,7 +547,7 @@ namespace LLStringFn * with zero non-printable characters. * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. */ - void replace_ascii_controlchars( + LL_COMMON_API void replace_ascii_controlchars( std::basic_string<char>& string, char replacement); } diff --git a/linden/indra/llcommon/llstringtable.h b/linden/indra/llcommon/llstringtable.h index 449206327..b13b01639 100644 --- a/linden/indra/llcommon/llstringtable.h +++ b/linden/indra/llcommon/llstringtable.h @@ -56,7 +56,7 @@ const U32 MAX_STRINGS_LENGTH = 256; -class LLStringTableEntry +class LL_COMMON_API LLStringTableEntry { public: LLStringTableEntry(const char *str) @@ -81,7 +81,7 @@ class LLStringTableEntry S32 mCount; }; -class LLStringTable +class LL_COMMON_API LLStringTable { public: LLStringTable(int tablesize); @@ -115,7 +115,7 @@ class LLStringTable #endif }; -extern LLStringTable gStringTable; +extern LL_COMMON_API LLStringTable gStringTable; //============================================================================ @@ -125,7 +125,7 @@ extern LLStringTable gStringTable; typedef const std::string* LLStdStringHandle; -class LLStdStringTable +class LL_COMMON_API LLStdStringTable { public: LLStdStringTable(S32 tablesize = 0) diff --git a/linden/indra/llcommon/llsys.h b/linden/indra/llcommon/llsys.h index 03f48ca01..d5575b2e1 100644 --- a/linden/indra/llcommon/llsys.h +++ b/linden/indra/llcommon/llsys.h @@ -45,7 +45,7 @@ #include <iosfwd> #include <string> -class LLOSInfo +class LL_COMMON_API LLOSInfo { public: LLOSInfo(); @@ -70,7 +70,7 @@ class LLOSInfo }; -class LLCPUInfo +class LL_COMMON_API LLCPUInfo { public: LLCPUInfo(); @@ -99,7 +99,7 @@ class LLCPUInfo // // CLASS LLMemoryInfo -class LLMemoryInfo +class LL_COMMON_API LLMemoryInfo /*! @brief Class to query the memory subsystem @@ -123,15 +123,15 @@ class LLMemoryInfo }; -std::ostream& operator<<(std::ostream& s, const LLOSInfo& info); -std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info); -std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info); +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLOSInfo& info); +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info); +LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info); // gunzip srcfile into dstfile. Returns FALSE on error. -BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile); +LL_COMMON_API BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile); // gzip srcfile into dstfile. Returns FALSE on error. -BOOL gzip_file(const std::string& srcfile, const std::string& dstfile); +LL_COMMON_API BOOL gzip_file(const std::string& srcfile, const std::string& dstfile); -extern LLCPUInfo gSysCPU; +LL_COMMON_API extern LLCPUInfo gSysCPU; #endif // LL_LLSYS_H diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index ed76a3b4f..98d64efb1 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h @@ -43,7 +43,7 @@ class LLThread; class LLMutex; class LLCondition; -class LLThread +class LL_COMMON_API LLThread { public: typedef enum e_thread_status @@ -125,7 +125,7 @@ class LLThread //============================================================================ -class LLMutex +class LL_COMMON_API LLMutex { public: LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex @@ -145,7 +145,7 @@ class LLMutex }; // Actually a condition/mutex pair (since each condition needs to be associated with a mutex). -class LLCondition : public LLMutex +class LL_COMMON_API LLCondition : public LLMutex { public: LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. @@ -159,7 +159,7 @@ class LLCondition : public LLMutex apr_thread_cond_t *mAPRCondp; }; -class LLMutexLock +class LL_COMMON_API LLMutexLock { public: LLMutexLock(LLMutex* mutex) @@ -192,7 +192,7 @@ void LLThread::unlockData() // see llmemory.h for LLPointer<> definition -class LLThreadSafeRefCount +class LL_COMMON_API LLThreadSafeRefCount { public: static void initThreadSafeRefCount(); // creates sMutex @@ -244,7 +244,7 @@ class LLThreadSafeRefCount // Simple responder for self destructing callbacks // Pure virtual class -class LLResponder : public LLThreadSafeRefCount +class LL_COMMON_API LLResponder : public LLThreadSafeRefCount { protected: virtual ~LLResponder(); diff --git a/linden/indra/llcommon/lltimer.cpp b/linden/indra/llcommon/lltimer.cpp index fb3e1ef27..2d283ecaa 100644 --- a/linden/indra/llcommon/lltimer.cpp +++ b/linden/indra/llcommon/lltimer.cpp @@ -33,6 +33,7 @@ #include "linden_common.h" #include "lltimer.h" +#include "timing.h" // totalTime prototype. #include "u64.h" @@ -51,9 +52,6 @@ // // Locally used constants // -const U32 SEC_PER_DAY = 86400; -const F64 SEC_TO_MICROSEC = 1000000.f; -const U64 SEC_TO_MICROSEC_U64 = 1000000; const F64 USEC_TO_SEC_F64 = 0.000001; diff --git a/linden/indra/llcommon/lltimer.h b/linden/indra/llcommon/lltimer.h index a6532334e..8590328c7 100644 --- a/linden/indra/llcommon/lltimer.h +++ b/linden/indra/llcommon/lltimer.h @@ -39,6 +39,7 @@ #include <limits.h> #include "stdtypes.h" +#include "llpreprocessor.h" #include "lldate.h" #include <string> @@ -54,7 +55,7 @@ const U32 USEC_PER_HOUR = USEC_PER_MIN * MIN_PER_HOUR; const U32 SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR; const F64 SEC_PER_USEC = 1.0 / (F64) USEC_PER_SEC; -class LLTimer +class LL_COMMON_API LLTimer { public: static LLTimer *sTimer; // global timer @@ -113,17 +114,17 @@ class LLTimer // // Various functions for initializing/accessing clock and timing stuff. Don't use these without REALLY knowing how they work. // -U64 get_clock_count(); -F64 calc_clock_frequency(U32 msecs); -void update_clock_frequencies(); +LL_COMMON_API U64 get_clock_count(); +LL_COMMON_API F64 calc_clock_frequency(U32 msecs); +LL_COMMON_API void update_clock_frequencies(); // Sleep for milliseconds -void ms_sleep(U32 ms); -U32 micro_sleep(U64 us, U32 max_yields = 0xFFFFFFFF); +LL_COMMON_API void ms_sleep(U32 ms); +LL_COMMON_API U32 micro_sleep(U64 us, U32 max_yields = 0xFFFFFFFF); // Returns the correct UTC time in seconds, like time(NULL). // Useful on the viewer, which may have its local clock set wrong. -time_t time_corrected(); +LL_COMMON_API time_t time_corrected(); static inline time_t time_min() { @@ -154,25 +155,25 @@ static inline time_t time_max() } // Correction factor used by time_corrected() above. -extern S32 gUTCOffset; +LL_COMMON_API extern S32 gUTCOffset; // Is the current computer (in its current time zone) // observing daylight savings time? -BOOL is_daylight_savings(); +LL_COMMON_API BOOL is_daylight_savings(); // Converts internal "struct tm" time buffer to Pacific Standard/Daylight Time // Usage: // S32 utc_time; // utc_time = time_corrected(); // struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight); -struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); -struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST); +LL_COMMON_API struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); +LL_COMMON_API struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST); -void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); -void secondsToTimecodeString(F32 current_time, std::string& tcstring); +LL_COMMON_API void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); +LL_COMMON_API void secondsToTimecodeString(F32 current_time, std::string& tcstring); // class for scheduling a function to be called at a given frequency (approximate, inprecise) -class LLEventTimer +class LL_COMMON_API LLEventTimer { public: LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds diff --git a/linden/indra/llcommon/lluri.h b/linden/indra/llcommon/lluri.h index 156d80b97..57bbedf42 100644 --- a/linden/indra/llcommon/lluri.h +++ b/linden/indra/llcommon/lluri.h @@ -47,7 +47,7 @@ class LLApp; * See: http://www.ietf.org/rfc/rfc3986.txt * */ -class LLURI +class LL_COMMON_API LLURI { public: LLURI(); @@ -189,6 +189,6 @@ class LLURI }; // this operator required for tut -bool operator!=(const LLURI& first, const LLURI& second); +LL_COMMON_API bool operator!=(const LLURI& first, const LLURI& second); #endif // LL_LLURI_H diff --git a/linden/indra/llcommon/lluuid.h b/linden/indra/llcommon/lluuid.h index 4b32138a0..c78fb1201 100644 --- a/linden/indra/llcommon/lluuid.h +++ b/linden/indra/llcommon/lluuid.h @@ -35,6 +35,7 @@ #include <iostream> #include <set> #include "stdtypes.h" +#include "llpreprocessor.h" const S32 UUID_BYTES = 16; const S32 UUID_WORDS = 4; @@ -47,7 +48,7 @@ struct uuid_time_t { U32 low; }; -class LLUUID +class LL_COMMON_API LLUUID { public: // @@ -106,8 +107,8 @@ class LLUUID LLUUID combine(const LLUUID& other) const; void combine(const LLUUID& other, LLUUID& result) const; - friend std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); - friend std::istream& operator>>(std::istream& s, LLUUID &uuid); + friend LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); + friend LL_COMMON_API std::istream& operator>>(std::istream& s, LLUUID &uuid); void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) void toString(std::string& out) const; @@ -323,7 +324,7 @@ typedef std::set<LLUUID, lluuid_less> uuid_list_t; */ typedef LLUUID LLAssetID; -class LLTransactionID : public LLUUID +class LL_COMMON_API LLTransactionID : public LLUUID { public: LLTransactionID() : LLUUID() { } diff --git a/linden/indra/llcommon/llworkerthread.h b/linden/indra/llcommon/llworkerthread.h index 708d81236..33d4c40f8 100644 --- a/linden/indra/llcommon/llworkerthread.h +++ b/linden/indra/llcommon/llworkerthread.h @@ -50,7 +50,7 @@ class LLWorkerClass; // Note: ~LLWorkerThread is O(N) N=# of worker threads, assumed to be small // It is assumed that LLWorkerThreads are rarely created/destroyed. -class LLWorkerThread : public LLQueuedThread +class LL_COMMON_API LLWorkerThread : public LLQueuedThread { friend class LLWorkerClass; public: @@ -114,7 +114,7 @@ class LLWorkerThread : public LLQueuedThread // Only one background task can be active at a time (per instance). // i.e. don't call addWork() if haveWork() returns true -class LLWorkerClass +class LL_COMMON_API LLWorkerClass { friend class LLWorkerThread; friend class LLWorkerThread::WorkRequest; diff --git a/linden/indra/llcommon/metaclass.h b/linden/indra/llcommon/metaclass.h index cc10f1675..f38bcd2d5 100644 --- a/linden/indra/llcommon/metaclass.h +++ b/linden/indra/llcommon/metaclass.h @@ -43,7 +43,7 @@ class LLReflective; class LLMetaProperty; class LLMetaMethod; -class LLMetaClass +class LL_COMMON_API LLMetaClass { public: diff --git a/linden/indra/llcommon/metaproperty.h b/linden/indra/llcommon/metaproperty.h index e5ac35907..6c016c56d 100644 --- a/linden/indra/llcommon/metaproperty.h +++ b/linden/indra/llcommon/metaproperty.h @@ -41,7 +41,7 @@ class LLMetaClass; class LLReflective; -class LLMetaProperty +class LL_COMMON_API LLMetaProperty { public: LLMetaProperty(const std::string& name, const LLMetaClass& object_class); diff --git a/linden/indra/llcommon/reflective.h b/linden/indra/llcommon/reflective.h index e2c18ebc6..a13537681 100644 --- a/linden/indra/llcommon/reflective.h +++ b/linden/indra/llcommon/reflective.h @@ -36,7 +36,7 @@ #define LL_REFLECTIVE_H class LLMetaClass; -class LLReflective +class LL_COMMON_API LLReflective { public: LLReflective(); diff --git a/linden/indra/llcommon/timing.h b/linden/indra/llcommon/timing.h index 2b9f60ada..cfc637eb6 100644 --- a/linden/indra/llcommon/timing.h +++ b/linden/indra/llcommon/timing.h @@ -44,6 +44,6 @@ const U64 SEC_TO_MICROSEC_U64 = 1000000; const U32 SEC_PER_DAY = 86400; // This is just a stub, implementation in lltimer.cpp. This file will be deprecated in the future. -U64 totalTime(); // Returns current system time in microseconds +LL_COMMON_API U64 totalTime(); // Returns current system time in microseconds #endif diff --git a/linden/indra/llcommon/u64.h b/linden/indra/llcommon/u64.h index 09a6b3e18..eb51131e9 100644 --- a/linden/indra/llcommon/u64.h +++ b/linden/indra/llcommon/u64.h @@ -39,14 +39,14 @@ * @param str The string to parse. * @return Returns the first U64 value found in the string or 0 on failure. */ -U64 str_to_U64(const std::string& str); +LL_COMMON_API U64 str_to_U64(const std::string& str); /** * @brief Given a U64 value, return a printable representation. * @param value The U64 to turn into a printable character array. * @return Returns the result string. */ -std::string U64_to_str(U64 value); +LL_COMMON_API std::string U64_to_str(U64 value); /** * @brief Given a U64 value, return a printable representation. @@ -65,16 +65,16 @@ std::string U64_to_str(U64 value); * @param result_size The size of the buffer allocated. Use U64_BUF. * @return Returns the result pointer. */ -char* U64_to_str(U64 value, char* result, S32 result_size); +LL_COMMON_API char* U64_to_str(U64 value, char* result, S32 result_size); /** * @brief Convert a U64 to the closest F64 value. */ -F64 U64_to_F64(const U64 value); +LL_COMMON_API F64 U64_to_F64(const U64 value); /** * @brief Helper function to wrap strtoull() which is not available on windows. */ -U64 llstrtou64(const char* str, char** end, S32 base); +LL_COMMON_API U64 llstrtou64(const char* str, char** end, S32 base); #endif diff --git a/linden/indra/llinventory/llparcel.h b/linden/indra/llinventory/llparcel.h index 47571d077..8faa673c3 100644 --- a/linden/indra/llinventory/llparcel.h +++ b/linden/indra/llinventory/llparcel.h @@ -39,7 +39,7 @@ #include "llparcelflags.h" #include "llpermissions.h" #include "v3math.h" - +#include "lltimer.h" // Grid out of which parcels taken is stepped every 4 meters. const F32 PARCEL_GRID_STEP_METERS = 4.f; diff --git a/linden/indra/llmath/lloctree.h b/linden/indra/llmath/lloctree.h index bced84cb1..2029554bf 100644 --- a/linden/indra/llmath/lloctree.h +++ b/linden/indra/llmath/lloctree.h @@ -68,8 +68,7 @@ template <class T> class LLOctreeTraveler : public LLTreeTraveler<T> { public: - virtual void traverse(const LLTreeNode<T>* node); - virtual void visit(const LLTreeNode<T>* state) { } + virtual void traverse(const LLOctreeNode<T>* node); virtual void visit(const LLOctreeNode<T>* branch) = 0; }; @@ -705,9 +704,8 @@ class LLOctreeRoot : public LLOctreeNode<T> // LLOctreeTraveler //======================== template <class T> -void LLOctreeTraveler<T>::traverse(const LLTreeNode<T>* tree_node) +void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node) { - const LLOctreeNode<T>* node = (const LLOctreeNode<T>*) tree_node; node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) { diff --git a/linden/indra/llmath/lltreenode.h b/linden/indra/llmath/lltreenode.h index ee9836241..ccbeda57c 100644 --- a/linden/indra/llmath/lltreenode.h +++ b/linden/indra/llmath/lltreenode.h @@ -82,8 +82,6 @@ class LLTreeTraveler { public: virtual ~LLTreeTraveler() { }; - virtual void traverse(const LLTreeNode<T>* node) = 0; - virtual void visit(const LLTreeNode<T>* node) = 0; }; template <class T> diff --git a/linden/indra/llmessage/CMakeLists.txt b/linden/indra/llmessage/CMakeLists.txt index 472328180..a5e424925 100644 --- a/linden/indra/llmessage/CMakeLists.txt +++ b/linden/indra/llmessage/CMakeLists.txt @@ -218,7 +218,7 @@ IF (NOT LINUX AND VIEWER) # These can not be found when we try to run the tests, so we had to disable them, for the viewer build. # TODO: Can someone with viewer knowledge figure out how to make these find the correct so. #ADD_BUILD_TEST(llhttpclientadapter llmessage) - ADD_BUILD_TEST(lltrustedmessageservice llmessage) - ADD_BUILD_TEST(lltemplatemessagedispatcher llmessage) + #ADD_BUILD_TEST(lltrustedmessageservice llmessage) + #ADD_BUILD_TEST(lltemplatemessagedispatcher llmessage) ENDIF (NOT LINUX AND VIEWER) diff --git a/linden/indra/llmessage/llassetstorage.cpp b/linden/indra/llmessage/llassetstorage.cpp index 16a96b75b..0ab108120 100644 --- a/linden/indra/llmessage/llassetstorage.cpp +++ b/linden/indra/llmessage/llassetstorage.cpp @@ -1028,12 +1028,12 @@ LLSD LLAssetStorage::getPendingDetails(LLAssetStorage::ERequestType rt, { const request_list_t* requests = getRequestList(rt); LLSD sd; - sd["requests"] = getPendingDetails(requests, asset_type, detail_prefix); + sd["requests"] = getPendingDetailsImpl(requests, asset_type, detail_prefix); return sd; } // virtual -LLSD LLAssetStorage::getPendingDetails(const LLAssetStorage::request_list_t* requests, +LLSD LLAssetStorage::getPendingDetailsImpl(const LLAssetStorage::request_list_t* requests, LLAssetType::EType asset_type, const std::string& detail_prefix) const { @@ -1116,11 +1116,11 @@ LLSD LLAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt, const LLUUID& asset_id) const { const request_list_t* requests = getRequestList(rt); - return getPendingRequest(requests, asset_type, asset_id); + return getPendingRequestImpl(requests, asset_type, asset_id); } // virtual -LLSD LLAssetStorage::getPendingRequest(const LLAssetStorage::request_list_t* requests, +LLSD LLAssetStorage::getPendingRequestImpl(const LLAssetStorage::request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id) const { @@ -1139,7 +1139,7 @@ bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt, const LLUUID& asset_id) { request_list_t* requests = getRequestList(rt); - if (deletePendingRequest(requests, asset_type, asset_id)) + if (deletePendingRequestImpl(requests, asset_type, asset_id)) { llinfos << "Asset " << getRequestName(rt) << " request for " << asset_id << "." << LLAssetType::lookup(asset_type) @@ -1150,7 +1150,7 @@ bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt, } // virtual -bool LLAssetStorage::deletePendingRequest(LLAssetStorage::request_list_t* requests, +bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id) { diff --git a/linden/indra/llmessage/llassetstorage.h b/linden/indra/llmessage/llassetstorage.h index c094ef487..83cfdf611 100644 --- a/linden/indra/llmessage/llassetstorage.h +++ b/linden/indra/llmessage/llassetstorage.h @@ -315,15 +315,15 @@ class LLAssetStorage : public LLTempAssetStorage void markAssetToxic( const LLUUID& uuid ); protected: - virtual LLSD getPendingDetails(const request_list_t* requests, + virtual LLSD getPendingDetailsImpl(const request_list_t* requests, LLAssetType::EType asset_type, const std::string& detail_prefix) const; - virtual LLSD getPendingRequest(const request_list_t* requests, + virtual LLSD getPendingRequestImpl(const request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id) const; - virtual bool deletePendingRequest(request_list_t* requests, + virtual bool deletePendingRequestImpl(request_list_t* requests, LLAssetType::EType asset_type, const LLUUID& asset_id); diff --git a/linden/indra/llmessage/llcurl.cpp b/linden/indra/llmessage/llcurl.cpp index 12321feba..202332c9d 100644 --- a/linden/indra/llmessage/llcurl.cpp +++ b/linden/indra/llmessage/llcurl.cpp @@ -120,7 +120,7 @@ LLCurl::Responder::~Responder() } // virtual -void LLCurl::Responder::error( +void LLCurl::Responder::errorWithContent( U32 status, const std::string& reason, const LLSD&) @@ -161,7 +161,7 @@ void LLCurl::Responder::completed(U32 status, const std::string& reason, const L } else { - error(status, reason, content); + errorWithContent(status, reason, content); } } diff --git a/linden/indra/llmessage/llcurl.h b/linden/indra/llmessage/llcurl.h index 3e9c0d430..32637b200 100644 --- a/linden/indra/llmessage/llcurl.h +++ b/linden/indra/llmessage/llcurl.h @@ -85,7 +85,7 @@ class LLCurl return((200 <= status) && (status < 300)); } - virtual void error( + virtual void errorWithContent( U32 status, const std::string& reason, const LLSD& content); diff --git a/linden/indra/llmessage/llhttpassetstorage.cpp b/linden/indra/llmessage/llhttpassetstorage.cpp index dfdad59e2..49dbdbd56 100644 --- a/linden/indra/llmessage/llhttpassetstorage.cpp +++ b/linden/indra/llmessage/llhttpassetstorage.cpp @@ -626,7 +626,7 @@ LLSD LLHTTPAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt, const request_list_t* running = getRunningList(rt); if (running) { - LLSD sd = LLAssetStorage::getPendingRequest(running, asset_type, asset_id); + LLSD sd = LLAssetStorage::getPendingRequestImpl(running, asset_type, asset_id); if (sd) { sd["is_running"] = true; diff --git a/linden/indra/llmessage/llhttpassetstorage.h b/linden/indra/llmessage/llhttpassetstorage.h index 5786c5df3..231437dad 100644 --- a/linden/indra/llmessage/llhttpassetstorage.h +++ b/linden/indra/llmessage/llhttpassetstorage.h @@ -62,6 +62,8 @@ class LLHTTPAssetStorage : public LLAssetStorage virtual ~LLHTTPAssetStorage(); + using LLAssetStorage::storeAssetData; // Unhiding virtuals... + virtual void storeAssetData( const LLUUID& uuid, LLAssetType::EType atype, diff --git a/linden/indra/llmessage/llhttpnode.cpp b/linden/indra/llmessage/llhttpnode.cpp index 2ba900a53..440b91fcf 100644 --- a/linden/indra/llmessage/llhttpnode.cpp +++ b/linden/indra/llmessage/llhttpnode.cpp @@ -98,19 +98,19 @@ namespace { } // virtual -LLSD LLHTTPNode::get() const +LLSD LLHTTPNode::simpleGet() const { throw NotImplemented(); } // virtual -LLSD LLHTTPNode::put(const LLSD& input) const +LLSD LLHTTPNode::simplePut(const LLSD& input) const { throw NotImplemented(); } // virtual -LLSD LLHTTPNode::post(const LLSD& input) const +LLSD LLHTTPNode::simplePost(const LLSD& input) const { throw NotImplemented(); } @@ -121,7 +121,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons { try { - response->result(get()); + response->result(simpleGet()); } catch (NotImplemented) { @@ -134,7 +134,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons { try { - response->result(put(input)); + response->result(simplePut(input)); } catch (NotImplemented) { @@ -147,7 +147,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con { try { - response->result(post(input)); + response->result(simplePost(input)); } catch (NotImplemented) { @@ -160,7 +160,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons { try { - response->result(del(context)); + response->result(simpleDel(context)); } catch (NotImplemented) { @@ -170,7 +170,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons } // virtual -LLSD LLHTTPNode::del(const LLSD&) const +LLSD LLHTTPNode::simpleDel(const LLSD&) const { throw NotImplemented(); } @@ -388,7 +388,7 @@ LLHTTPNode::Response::~Response() { } -void LLHTTPNode::Response::status(S32 code) +void LLHTTPNode::Response::statusUnknownError(S32 code) { status(code, "Unknown Error"); } diff --git a/linden/indra/llmessage/llhttpnode.h b/linden/indra/llmessage/llhttpnode.h index 17ffd66e8..87f0c480f 100644 --- a/linden/indra/llmessage/llhttpnode.h +++ b/linden/indra/llmessage/llhttpnode.h @@ -83,10 +83,10 @@ class LLHTTPNode //@{ public: - virtual LLSD get() const; - virtual LLSD put(const LLSD& input) const; - virtual LLSD post(const LLSD& input) const; - virtual LLSD del(const LLSD& context) const; + virtual LLSD simpleGet() const; + virtual LLSD simplePut(const LLSD& input) const; + virtual LLSD simplePost(const LLSD& input) const; + virtual LLSD simpleDel(const LLSD& context) const; /** * @brief Abstract Base Class declaring Response interface. @@ -116,7 +116,7 @@ class LLHTTPNode /** * @brief Return no body, just status code and 'UNKNOWN ERROR'. */ - virtual void status(S32 code); + virtual void statusUnknownError(S32 code); virtual void notFound(const std::string& message); virtual void notFound(); diff --git a/linden/indra/llmessage/llpumpio.cpp b/linden/indra/llmessage/llpumpio.cpp index 3e3f0b37a..8ef2b16c0 100644 --- a/linden/indra/llmessage/llpumpio.cpp +++ b/linden/indra/llmessage/llpumpio.cpp @@ -43,6 +43,7 @@ #include "llmemtype.h" #include "llstl.h" #include "llstat.h" +#include "llfasttimer.h" // These should not be enabled in production, but they can be // intensely useful during development for finding certain kinds of diff --git a/linden/indra/llmessage/llregionpresenceverifier.cpp b/linden/indra/llmessage/llregionpresenceverifier.cpp index 24410a7a0..04eba34b6 100644 --- a/linden/indra/llmessage/llregionpresenceverifier.cpp +++ b/linden/indra/llmessage/llregionpresenceverifier.cpp @@ -30,6 +30,7 @@ * $/LicenseInfo$ */ +#include "linden_common.h" #include "llregionpresenceverifier.h" #include "llhttpclientinterface.h" #include <sstream> diff --git a/linden/indra/llmessage/llsdappservices.cpp b/linden/indra/llmessage/llsdappservices.cpp index dc135c51b..b87c0cd6b 100644 --- a/linden/indra/llmessage/llsdappservices.cpp +++ b/linden/indra/llmessage/llsdappservices.cpp @@ -56,7 +56,7 @@ class LLHTTPConfigService : public LLHTTPNode desc.source(__FILE__, __LINE__); } - virtual LLSD get() const + virtual LLSD simpleGet() const { LLSD result; LLApp* app = LLApp::instance(); @@ -82,7 +82,7 @@ class LLHTTPConfigRuntimeService : public LLHTTPNode desc.source(__FILE__, __LINE__); } - virtual LLSD get() const + virtual LLSD simpleGet() const { return LLApp::instance()->getOptionData( LLApp::PRIORITY_RUNTIME_OVERRIDE); diff --git a/linden/indra/llmessage/llsdhttpserver.cpp b/linden/indra/llmessage/llsdhttpserver.cpp index 00fc170c5..7d06c298a 100644 --- a/linden/indra/llmessage/llsdhttpserver.cpp +++ b/linden/indra/llmessage/llsdhttpserver.cpp @@ -62,7 +62,7 @@ class LLHTTPHelloService : public LLHTTPNode desc.source(__FILE__, __LINE__); } - virtual LLSD get() const + virtual LLSD simpleGet() const { LLSD result = "hello"; return result; @@ -86,7 +86,7 @@ class LLHTTPEchoService : public LLHTTPNode desc.source(__FILE__, __LINE__); } - virtual LLSD post(const LLSD& params) const + virtual LLSD simplePost(const LLSD& params) const { return params; } diff --git a/linden/indra/llplugin/CMakeLists.txt b/linden/indra/llplugin/CMakeLists.txt index 73cd9a396..7a7f4e583 100644 --- a/linden/indra/llplugin/CMakeLists.txt +++ b/linden/indra/llplugin/CMakeLists.txt @@ -2,10 +2,6 @@ project(llplugin) -if(HAVE_64_BIT) - set(REQUIRE_PIC) -endif(HAVE_64_BIT) - include(00-Common) include(CURL) include(LLCommon) diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp index 5d3d6a7fd..7baec8159 100644 --- a/linden/indra/llrender/llfontgl.cpp +++ b/linden/indra/llrender/llfontgl.cpp @@ -42,6 +42,7 @@ #include "llrender.h" #include "v4color.h" #include "llstl.h" +#include "llfasttimer.h" const S32 BOLD_OFFSET = 1; diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp index 2e9b2bdeb..4a4ff1b93 100644 --- a/linden/indra/llrender/llgl.cpp +++ b/linden/indra/llrender/llgl.cpp @@ -547,8 +547,6 @@ void LLGLManager::shutdownGL() // these are used to turn software blending on. They appear in the Debug/Avatar menu // presence of vertex skinning/blending or vertex programs will set these to FALSE by default. -extern LLCPUInfo gSysCPU; - void LLGLManager::initExtensions() { #if LL_MESA_HEADLESS diff --git a/linden/indra/llui/llfunctorregistry.cpp b/linden/indra/llui/llfunctorregistry.cpp index 0c5b1655b..5f9644f25 100644 --- a/linden/indra/llui/llfunctorregistry.cpp +++ b/linden/indra/llui/llfunctorregistry.cpp @@ -31,6 +31,7 @@ * $/LicenseInfo$ **/ +#include "linden_common.h" #include "llfunctorregistry.h" // This is a default functor always resident in the system. diff --git a/linden/indra/llvfs/lldir.cpp b/linden/indra/llvfs/lldir.cpp index b8a4794c4..0c93cbbe6 100644 --- a/linden/indra/llvfs/lldir.cpp +++ b/linden/indra/llvfs/lldir.cpp @@ -43,6 +43,7 @@ #include "lldir.h" #include "llerror.h" #include "lluuid.h" +#include "lltimer.h" #if LL_WINDOWS #include "lldir_win32.h" diff --git a/linden/indra/llvfs/llpidlock.cpp b/linden/indra/llvfs/llpidlock.cpp index 93ac12030..cb6442816 100755 --- a/linden/indra/llvfs/llpidlock.cpp +++ b/linden/indra/llvfs/llpidlock.cpp @@ -39,6 +39,7 @@ #include "llsdserialize.h" #include "llnametable.h" #include "llframetimer.h" +#include "llapp.h" #if LL_WINDOWS //For windows platform. bool isProcessAlive(U32 pid) @@ -60,7 +61,7 @@ class LLPidLockFile public: LLPidLockFile( ) : mSaving(FALSE), mWaiting(FALSE), - mClean(TRUE), mPID(getpid()) + mClean(TRUE), mPID(LLApp::getPid()) { mLockName = gDirUtilp->getTempDir() + "/savelock"; } diff --git a/linden/indra/llvfs/llpidlock.h b/linden/indra/llvfs/llpidlock.h index 42aee4dc4..efcfd9150 100755 --- a/linden/indra/llvfs/llpidlock.h +++ b/linden/indra/llvfs/llpidlock.h @@ -41,8 +41,6 @@ class LLFrameTimer; #include <windows.h> -#define getpid GetCurrentProcessId - #else //Everyone Else #include <signal.h> diff --git a/linden/indra/llvfs/llvfile.cpp b/linden/indra/llvfs/llvfile.cpp index 6b1563bab..630975a05 100644 --- a/linden/indra/llvfs/llvfile.cpp +++ b/linden/indra/llvfs/llvfile.cpp @@ -38,6 +38,7 @@ #include "llthread.h" #include "llstat.h" #include "llvfs.h" +#include "llfasttimer.h" const S32 LLVFile::READ = 0x00000001; const S32 LLVFile::WRITE = 0x00000002; diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp index 9bf5b5916..dea8c9ca1 100644 --- a/linden/indra/llvfs/llvfs.cpp +++ b/linden/indra/llvfs/llvfs.cpp @@ -47,6 +47,7 @@ #include "llvfs.h" #include "llstl.h" +#include "lltimer.h" const S32 FILE_BLOCK_MASK = 0x000003FF; // 1024-byte blocks const S32 VFS_CLEANUP_SIZE = 5242880; // how much space we free up in a single stroke diff --git a/linden/indra/llwindow/lldxhardware.cpp b/linden/indra/llwindow/lldxhardware.cpp index e0cb82d2b..d8058baf5 100644 --- a/linden/indra/llwindow/lldxhardware.cpp +++ b/linden/indra/llwindow/lldxhardware.cpp @@ -47,6 +47,7 @@ #include "llstring.h" #include "llstl.h" +#include "lltimer.h" void (*gWriteDebug)(const char* msg) = NULL; LLDXHardware gDXHardware; diff --git a/linden/indra/llwindow/llwindowmacosx.h b/linden/indra/llwindow/llwindowmacosx.h index 92c73e864..d4c1b44b8 100644 --- a/linden/indra/llwindow/llwindowmacosx.h +++ b/linden/indra/llwindow/llwindowmacosx.h @@ -34,6 +34,7 @@ #define LL_LLWINDOWMACOSX_H #include "llwindow.h" +#include "lltimer.h" #include <Carbon/Carbon.h> #include <AGL/agl.h> diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp index 16106af36..f7d758790 100644 --- a/linden/indra/llwindow/llwindowsdl.cpp +++ b/linden/indra/llwindow/llwindowsdl.cpp @@ -42,6 +42,7 @@ #include "llstring.h" #include "lldir.h" #include "llfindlocale.h" +#include "lltimer.h" #include "indra_constants.h" @@ -1940,11 +1941,6 @@ void LLWindowSDL::setCursor(ECursorType cursor) } } -ECursorType LLWindowSDL::getCursor() -{ - return mCurrentCursor; -} - void LLWindowSDL::initCursors() { int i; diff --git a/linden/indra/llwindow/llwindowsdl.h b/linden/indra/llwindow/llwindowsdl.h index 37b083519..e632dfebc 100644 --- a/linden/indra/llwindow/llwindowsdl.h +++ b/linden/indra/llwindow/llwindowsdl.h @@ -36,6 +36,7 @@ // Simple Directmedia Layer (http://libsdl.org/) implementation of LLWindow class #include "llwindow.h" +#include "lltimer.h" #include "SDL/SDL.h" #include "SDL/SDL_endian.h" @@ -77,7 +78,6 @@ class LLWindowSDL : public LLWindow /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); /*virtual*/ void setCursor(ECursorType cursor); - /*virtual*/ ECursorType getCursor(); /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); /*virtual*/ void setMouseClipping( BOOL b ); diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp index 12a488a6b..7bc9a3bf8 100644 --- a/linden/indra/llwindow/llwindowwin32.cpp +++ b/linden/indra/llwindow/llwindowwin32.cpp @@ -59,6 +59,8 @@ #include "llpreeditor.h" +#include "llfasttimer.h" + // culled from winuser.h #ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */ const S32 WM_MOUSEWHEEL = 0x020A; diff --git a/linden/indra/lscript/lscript_execute.h b/linden/indra/lscript/lscript_execute.h index 9a631c4c8..e2263fdbe 100644 --- a/linden/indra/lscript/lscript_execute.h +++ b/linden/indra/lscript/lscript_execute.h @@ -36,6 +36,7 @@ #include "lscript_byteconvert.h" #include "linked_lists.h" #include "lscript_library.h" +#include "lltimer.h" // Return values for run() methods const U32 NO_DELETE_FLAG = 0x0000; diff --git a/linden/indra/lscript/lscript_execute/llscriptresource.cpp b/linden/indra/lscript/lscript_execute/llscriptresource.cpp index 6c4776c2e..05ab8ebba 100644 --- a/linden/indra/lscript/lscript_execute/llscriptresource.cpp +++ b/linden/indra/lscript/lscript_execute/llscriptresource.cpp @@ -30,6 +30,7 @@ * $/LicenseInfo$ */ +#include "linden_common.h" #include "llscriptresource.h" #include "llerror.h" diff --git a/linden/indra/media_plugins/base/CMakeLists.txt b/linden/indra/media_plugins/base/CMakeLists.txt index dd0b0a0b0..8d620433a 100644 --- a/linden/indra/media_plugins/base/CMakeLists.txt +++ b/linden/indra/media_plugins/base/CMakeLists.txt @@ -2,10 +2,6 @@ project(media_plugin_base) -if(HAVE_64_BIT) - set(REQUIRE_PIC) -endif(HAVE_64_BIT) - include(00-Common) include(LLCommon) include(LLImage) diff --git a/linden/indra/media_plugins/example/CMakeLists.txt b/linden/indra/media_plugins/example/CMakeLists.txt index bac5fa2fe..7822300ba 100644 --- a/linden/indra/media_plugins/example/CMakeLists.txt +++ b/linden/indra/media_plugins/example/CMakeLists.txt @@ -2,10 +2,6 @@ project(media_plugin_example) -if(HAVE_64_BIT) - set(REQUIRE_PIC) -endif(HAVE_64_BIT) - include(00-Common) include(LLCommon) include(LLImage) diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt index a031157f2..4401e6407 100644 --- a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -2,10 +2,6 @@ project(media_plugin_gstreamer010) -if(HAVE_64_BIT) - set(REQUIRE_PIC) -endif(HAVE_64_BIT) - include(00-Common) include(LLCommon) include(LLImage) @@ -34,14 +30,6 @@ include_directories( ### media_plugin_gstreamer010 -if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) - if(WINDOWS) - add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) - set(media_plugin_gstreamer010_SOURCE_FILES media_plugin_gstreamer010.cpp llmediaimplgstreamervidplug.cpp diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h index 0ea096aab..bb90aa12f 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h @@ -38,31 +38,23 @@ #include <cstdio> -extern "C" { -#include <sys/types.h> -//#include <unistd.h> //fiuxme -} - -#define MSGMODULEFOO "(media plugin)" - -#ifdef LL_LINUX ///////////////////////////////////////////////////////////////////////// // Debug/Info/Warning macros. - -#define STDERRMSG(...) do{\ - fprintf(stderr, " pid:%d: ", (int)getpid());\ - fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\ - fprintf(stderr, __VA_ARGS__);\ - fputc('\n',stderr);\ - }while(0) +#if LL_WINDOWS +#include <process.h> +#define LL_GETPID GetCurrentProcessId #else +#include <sys/types.h> +#include <unistd.h> +#define LL_GETPID getpid +#endif +#define MSGMODULEFOO "(media plugin)" #define STDERRMSG(...) do{\ + fprintf(stderr, " pid:%d: ", (int)LL_GETPID());\ fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\ fprintf(stderr, __VA_ARGS__);\ fputc('\n',stderr);\ }while(0) -#endif - #define NULLMSG(...) do{}while(0) #define DEBUGMSG NULLMSG diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 44bc32eef..78e46ca2f 100755 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -175,7 +175,7 @@ MediaPluginGStreamer010::MediaPluginGStreamer010( mCommand ( COMMAND_NONE ) { std::ostringstream str; - INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid())); + INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(LL_GETPID())); } /////////////////////////////////////////////////////////////////////////////// diff --git a/linden/indra/media_plugins/webkit/CMakeLists.txt b/linden/indra/media_plugins/webkit/CMakeLists.txt index 2ab4a95fa..303a77437 100644 --- a/linden/indra/media_plugins/webkit/CMakeLists.txt +++ b/linden/indra/media_plugins/webkit/CMakeLists.txt @@ -2,10 +2,6 @@ project(media_plugin_webkit) -if(HAVE_64_BIT) - set(REQUIRE_PIC) -endif(HAVE_64_BIT) - include(00-Common) include(LLCommon) include(LLImage) @@ -34,20 +30,12 @@ include_directories( ${LLQTWEBKIT_INCLUDE_DIR} ) - ### media_plugin_webkit set(media_plugin_webkit_SOURCE_FILES media_plugin_webkit.cpp ) -if(NOT CMAKE_SIZEOF_VOID_P MATCHES 4) - if(WINDOWS) - add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) set(media_plugin_webkit_HEADER_FILES volume_catcher.h ) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index a4d99f232..8683bae45 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1538,11 +1538,23 @@ if (INSTALL) include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake) endif (INSTALL) -ADD_VIEWER_BUILD_TEST(llagentaccess viewer) +#ADD_VIEWER_BUILD_TEST(llagentaccess viewer) # Don't do these for DARWIN or LINUX here -- they're taken care of by viewer_manifest.py if (WINDOWS) + get_target_property(BUILT_LLCOMMON llcommon LOCATION) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${BUILT_LLCOMMON} + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + COMMENT "Copying llcommon.dll to the runtime folder." + ) + get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION) add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 81091967a..5a1700af0 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -5573,7 +5573,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode !input.has("body") ) { //what to do with badly formed message? - response->status(400); + response->statusUnknownError(400); response->result(LLSD("Invalid message parameters")); } @@ -5646,7 +5646,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode else { //what to do with badly formed message? - response->status(400); + response->statusUnknownError(400); response->result(LLSD("Invalid message parameters")); } } diff --git a/linden/indra/newview/llappviewer.h b/linden/indra/newview/llappviewer.h index 9d72457d9..7b3230a28 100644 --- a/linden/indra/newview/llappviewer.h +++ b/linden/indra/newview/llappviewer.h @@ -33,6 +33,8 @@ #ifndef LL_LLAPPVIEWER_H #define LL_LLAPPVIEWER_H +#include "llsys.h" // LLOSInfo + class LLTextureCache; class LLImageDecodeThread; class LLTextureFetch; diff --git a/linden/indra/newview/llfeaturemanager.cpp b/linden/indra/newview/llfeaturemanager.cpp index 54da31b93..bf43fcfeb 100644 --- a/linden/indra/newview/llfeaturemanager.cpp +++ b/linden/indra/newview/llfeaturemanager.cpp @@ -62,7 +62,6 @@ // externs // extern LLMemoryInfo gSysMemory; -extern LLCPUInfo gSysCPU; #if LL_DARWIN const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt"; diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 5c037d67a..f7163ee2e 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp @@ -68,7 +68,6 @@ #include "lldxhardware.h" #endif -extern LLCPUInfo gSysCPU; extern LLMemoryInfo gSysMemory; extern U32 gPacketsIn; diff --git a/linden/indra/newview/llhomelocationresponder.cpp b/linden/indra/newview/llhomelocationresponder.cpp index e60923700..c00d8e719 100644 --- a/linden/indra/newview/llhomelocationresponder.cpp +++ b/linden/indra/newview/llhomelocationresponder.cpp @@ -105,7 +105,8 @@ void LLHomeLocationResponder::result( const LLSD& content ) } } -void LLHomeLocationResponder::error( const LLSD& content ) +void LLHomeLocationResponder::error( U32 status, const std::string& reason ) { - llinfos << "received error(" << ll_pretty_print_sd( content ) << ")" << llendl; + llinfos << "received error(" << reason << ")" << llendl; } + diff --git a/linden/indra/newview/llhomelocationresponder.h b/linden/indra/newview/llhomelocationresponder.h index 1e222cd5b..3a1d8ebfe 100644 --- a/linden/indra/newview/llhomelocationresponder.h +++ b/linden/indra/newview/llhomelocationresponder.h @@ -42,7 +42,7 @@ class LLHomeLocationResponder : public LLHTTPClient::Responder { virtual void result( const LLSD& content ); - virtual void error( const LLSD& content ); + virtual void error( U32 status, const std::string& reason ); }; #endif diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index c1d5ff309..d9fa5b512 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp @@ -826,7 +826,7 @@ class LLSpatialSetStateDiff : public LLSpatialSetState public: LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } - virtual void traverse(const LLSpatialGroup::TreeNode* n) + virtual void traverse(const LLSpatialGroup::OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -885,7 +885,7 @@ class LLSpatialClearStateDiff : public LLSpatialClearState public: LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } - virtual void traverse(const LLSpatialGroup::TreeNode* n) + virtual void traverse(const LLSpatialGroup::OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -1519,7 +1519,7 @@ class LLOctreeCull : public LLSpatialGroup::OctreeTraveler return false; } - virtual void traverse(const LLSpatialGroup::TreeNode* n) + virtual void traverse(const LLSpatialGroup::OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); diff --git a/linden/indra/newview/llviewerassetstorage.h b/linden/indra/newview/llviewerassetstorage.h index 15c11c702..512b590a1 100644 --- a/linden/indra/newview/llviewerassetstorage.h +++ b/linden/indra/newview/llviewerassetstorage.h @@ -47,6 +47,7 @@ class LLViewerAssetStorage : public LLAssetStorage LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, LLVFS *vfs); + using LLAssetStorage::storeAssetData; virtual void storeAssetData( const LLTransactionID& tid, LLAssetType::EType atype, diff --git a/linden/indra/newview/llwatchdog.h b/linden/indra/newview/llwatchdog.h index ed7d5bdcf..1a10e331d 100644 --- a/linden/indra/newview/llwatchdog.h +++ b/linden/indra/newview/llwatchdog.h @@ -64,9 +64,10 @@ class LLWatchdogTimeout : public LLWatchdogEntry /* virtual */ bool isAlive() const; /* virtual */ void reset(); - /* virtual */ void start(const std::string& state); + /* virtual */ void start() { start(""); }; /* virtual */ void stop(); + void start(const std::string& state); void setTimeout(F32 d); void ping(const std::string& state); const std::string& getState() {return mPingState; } diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 41495ca01..a93e05839 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -248,6 +248,14 @@ def construct(self): # For spellchecking self.path("libhunspell.dll") + # Get llcommon and deps. + if self.prefix(src=self.args['configuration'], dst=""): + self.path('libapr-1.dll') + self.path('libaprutil-1.dll') + self.path('libapriconv-1.dll') + self.path('llcommon.dll') + self.end_prefix() + # For textures if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): self.path("openjpeg.dll") @@ -732,14 +740,51 @@ def construct(self): self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice") #self.path("vivox-runtime/universal-darwin/SLVoiceAgent.app", "SLVoiceAgent.app") + libdir = "../../libraries/universal-darwin/lib_release" + dylibs = {} + + #for lib in "llkdu", "llcommon": + for lib in "llcommon": + libfile = "lib%s.dylib" % lib + try: + self.path(self.find_existing_file(os.path.join(os.pardir, + lib, + self.args['configuration'], + libfile), + os.path.join(libdir, libfile)), + dst=libfile) + except RuntimeError: + print "Skipping %s" % libfile + dylibs[lib] = False + else: + dylibs[lib] = True + + for libfile in ("libapr-1.0.3.7.dylib", + "libaprutil-1.0.3.8.dylib", + "libexpat.0.5.0.dylib"): + self.path(os.path.join(libdir, libfile), libfile) + #libfmodwrapper.dylib #self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib") # our apps # self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") - - # plugin launcher + + # our apps dependencies on shared libs + mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") + mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") + for libfile in ("libllcommon.dylib", + "libapr-1.0.3.7.dylib", + "libaprutil-1.0.3.8.dylib", + "libexpat.0.5.0.dylib"): + target_lib = os.path.join('../../..', libfile) + self.run_command("ln -sf %(target)r %(link)r" % + {'target': target_lib, + 'link' : os.path.join(mac_crash_logger_res_path, libfile)} + ) + + # plugin launcher self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin") # plugins @@ -895,6 +940,8 @@ def construct(self): # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 self.path("skins/default/xui/en-us/mime_types_linux.xml", "skins/default/xui/en-us/mime_types.xml") + self.path("../llcommon/libllcommon.so", "lib/libllcommon.so") + self.path("featuretable_linux.txt") diff --git a/linden/install.xml b/linden/install.xml index fbb269a57..d61d07d65 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -99,9 +99,9 @@ <key>darwin</key> <map> <key>md5sum</key> - <string>abd07d760cdc7d23da3b861f34b09c92</string> + <string>115d8ac44a91efdb173e9b3e478c46b6</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.2.8-darwin-20080812.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.3.7-darwin-20090805.tar.bz2</uri> </map> <key>linux</key> <map> @@ -354,9 +354,9 @@ <key>darwin</key> <map> <key>md5sum</key> - <string>9c5603e328e9f543e0a599d6b25be973</string> + <string>c457a0a041ac4946265889a503d26c3d</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/expat-1.95.8-darwin-20080812.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/expat-1.95.8-darwin-20090805.tar.bz2</uri> </map> <key>linux</key> <map> From 38d4ef2f26545c630fe80e7edc59b0a77641938a Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 7 Nov 2010 18:38:46 +0100 Subject: [PATCH 163/239] IMP-692: SNOW-713: Fixed compile bug fixes. Changes: * Added changes from snowglobe 1.5 to indra/llcommon/llstring.h (compile errors as a result of a missing include, but I copied everything else too). * Added #include "linden_common.h" to emeraldboobutils.cpp. Really it's one the header files that needed that, but that's how this header works: every source file should include it as first header anyway, then there is no need for other headers to do that. * Renamed LLPanelRegionOpenSettingsInfo::sendUpdate(void*) to LLPanelRegionOpenSettingsInfo::onClickOrs because it was hiding a virtual function (BOOL sendUpdate(void)). * Made cutToClipboard more equal to copyToClipboard (was also hiding a virtual function). * Install libllcommon.so in lib64 on Linux_x86_64, instead of lib. --- linden/indra/llcommon/llstring.h | 25 ++++++++++++++++---- linden/indra/newview/emeraldboobutils.cpp | 1 + linden/indra/newview/llfloaterregioninfo.cpp | 6 ++--- linden/indra/newview/llfloaterregioninfo.h | 2 +- linden/indra/newview/llfolderview.h | 2 +- linden/indra/newview/llinventorybridge.h | 2 +- linden/indra/newview/llpanelinventory.cpp | 5 ++-- linden/indra/newview/viewer_manifest.py | 10 ++++---- 8 files changed, 36 insertions(+), 17 deletions(-) diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index 3f2c8d85d..44f5f07ea 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -34,12 +34,13 @@ #define LL_LLSTRING_H #include <string> +#include <cstdio> +#include <algorithm> #if LL_LINUX || LL_SOLARIS #include <wctype.h> #include <wchar.h> #endif -#include "linden_common.h" #include <string.h> @@ -173,6 +174,8 @@ class LL_COMMON_API LLStringOps static S32 collate(const char* a, const char* b) { return strcoll(a, b); } static S32 collate(const llwchar* a, const llwchar* b); + + static bool isHexString(const std::string& str); }; /** @@ -236,7 +239,8 @@ class LLStringUtilBase static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab ); static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement ); static void replaceChar( std::basic_string<T>& string, T target, T replacement ); - + static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement ); + static BOOL containsNonprintable(const std::basic_string<T>& string); static void stripNonprintable(std::basic_string<T>& string); @@ -908,11 +912,22 @@ template<class T> void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement ) { size_type found_pos = 0; - for (found_pos = string.find(target, found_pos); - found_pos != std::basic_string<T>::npos; - found_pos = string.find(target, found_pos)) + while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos ) { string[found_pos] = replacement; + found_pos++; // avoid infinite defeat if target == replacement + } +} + +//static +template<class T> +void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement ) +{ + size_type found_pos = 0; + while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos ) + { + string.replace( found_pos, target.length(), replacement ); + found_pos += replacement.length(); // avoid infinite defeat if replacement contains target } } diff --git a/linden/indra/newview/emeraldboobutils.cpp b/linden/indra/newview/emeraldboobutils.cpp index f68d6a7b8..f4409407f 100644 --- a/linden/indra/newview/emeraldboobutils.cpp +++ b/linden/indra/newview/emeraldboobutils.cpp @@ -1,3 +1,4 @@ +#include "linden_common.h" #include "emeraldboobutils.h" std::ostream &operator<<(std::ostream &os, const EmeraldGlobalBoobConfig &v) diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index 8ae3fa2a5..d4ffe22bb 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -908,7 +908,7 @@ BOOL LLPanelRegionOpenSettingsInfo::postBuild() initHelpBtn("show_tags_help", "HelpShowTags"); initHelpBtn("allow_parcel_windlight_help", "HelpAllowParcelWindLight"); - childSetAction("apply_ors_btn", sendUpdate, this); + childSetAction("apply_ors_btn", onClickOrs, this); refreshFromRegion(gAgent.getRegion()); @@ -926,12 +926,12 @@ BOOL LLPanelRegionOpenSettingsInfo::postBuild() // strings[7] = restrict pushobject // strings[8] = 'Y' - allow parcel subdivide, 'N' - not // strings[9] = 'Y' - block parcel search, 'N' - allow -void LLPanelRegionOpenSettingsInfo::sendUpdate(void* userdata) +void LLPanelRegionOpenSettingsInfo::onClickOrs(void* userdata) { LLPanelRegionOpenSettingsInfo* self; self = (LLPanelRegionOpenSettingsInfo*)userdata; - llinfos << "LLPanelRegionOpenSettingsInfo::sendUpdate()" << llendl; + llinfos << "LLPanelRegionOpenSettingsInfo::onClickOrs()" << llendl; LLSD body; std::string url = gAgent.getRegion()->getCapability("DispatchOpenRegionSettings"); diff --git a/linden/indra/newview/llfloaterregioninfo.h b/linden/indra/newview/llfloaterregioninfo.h index ee01c7c58..ae0c99360 100644 --- a/linden/indra/newview/llfloaterregioninfo.h +++ b/linden/indra/newview/llfloaterregioninfo.h @@ -188,7 +188,7 @@ class LLPanelRegionOpenSettingsInfo : public LLPanelRegionInfo virtual BOOL postBuild(); protected: - static void sendUpdate(void* userdata); + static void onClickOrs(void* userdata); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/linden/indra/newview/llfolderview.h b/linden/indra/newview/llfolderview.h index 9fad72e7c..40da66942 100644 --- a/linden/indra/newview/llfolderview.h +++ b/linden/indra/newview/llfolderview.h @@ -97,7 +97,7 @@ class LLFolderViewEventListener virtual void move( LLFolderViewEventListener* parent_listener ) = 0; virtual BOOL isItemCopyable() const = 0; virtual BOOL copyToClipboard() const = 0; - virtual void cutToClipboard() = 0; + virtual BOOL cutToClipboard() const = 0; virtual BOOL isClipboardPasteable() const = 0; virtual void pasteFromClipboard() = 0; virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; diff --git a/linden/indra/newview/llinventorybridge.h b/linden/indra/newview/llinventorybridge.h index 2004678f7..5a53aa5b4 100644 --- a/linden/indra/newview/llinventorybridge.h +++ b/linden/indra/newview/llinventorybridge.h @@ -221,7 +221,7 @@ class LLInvFVBridge : public LLFolderViewEventListener virtual void move(LLFolderViewEventListener* new_parent_bridge) {} virtual BOOL isItemCopyable() const { return FALSE; } virtual BOOL copyToClipboard() const { return FALSE; } - virtual void cutToClipboard() {} + virtual BOOL cutToClipboard() const { return FALSE; } virtual BOOL isClipboardPasteable() const; virtual void pasteFromClipboard() {} void getClipboardEntries(bool show_asset_id, std::vector<std::string> &items, diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index 9cd2759c5..277ab150e 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp @@ -145,7 +145,7 @@ class LLTaskInvFVBridge : public LLFolderViewEventListener virtual void move(LLFolderViewEventListener* parent_listener); virtual BOOL isItemCopyable() const; virtual BOOL copyToClipboard() const; - virtual void cutToClipboard(); + virtual BOOL cutToClipboard() const; virtual BOOL isClipboardPasteable() const; virtual void pasteFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); @@ -594,8 +594,9 @@ BOOL LLTaskInvFVBridge::copyToClipboard() const return FALSE; } -void LLTaskInvFVBridge::cutToClipboard() +BOOL LLTaskInvFVBridge::cutToClipboard() const { + return FALSE; } BOOL LLTaskInvFVBridge::isClipboardPasteable() const diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index a93e05839..f631d1f20 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -228,7 +228,7 @@ def construct(self): self.path("LICENSE-libraries.txt") self.end_prefix("../..") - + self.path("imprudence.url") # Plugin host application @@ -741,7 +741,7 @@ def construct(self): #self.path("vivox-runtime/universal-darwin/SLVoiceAgent.app", "SLVoiceAgent.app") libdir = "../../libraries/universal-darwin/lib_release" - dylibs = {} + dylibs = {} #for lib in "llkdu", "llcommon": for lib in "llcommon": @@ -940,8 +940,6 @@ def construct(self): # Per platform MIME config on the cheap. See SNOW-307 / DEV-41388 self.path("skins/default/xui/en-us/mime_types_linux.xml", "skins/default/xui/en-us/mime_types.xml") - self.path("../llcommon/libllcommon.so", "lib/libllcommon.so") - self.path("featuretable_linux.txt") @@ -997,6 +995,8 @@ def construct(self): super(Linux_i686Manifest, self).construct() self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") + self.path("../llcommon/libllcommon.so", "lib/libllcommon.so") + if (not self.standalone()) and self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"): self.path("libapr-1.so.0") self.path("libaprutil-1.so.0") @@ -1114,6 +1114,8 @@ def construct(self): self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") # self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin") + self.path("../llcommon/libllcommon.so", "lib64/libllcommon.so") + self.path("linux_tools/launch_url.sh","launch_url.sh") if self.prefix("res-sdl"): self.path("*") From a23a8d225262891b6fe68298a1fd6cf658c3c349 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sun, 7 Nov 2010 10:45:56 -0700 Subject: [PATCH 164/239] Use the LGPL version of the quicktime media plugin. This allows us to use quicktime without violating the GPL --- .../quicktime/media_plugin_quicktime.cpp | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 68b9679d3..999f754dc 100755 --- a/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/linden/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -3,33 +3,26 @@ * @brief QuickTime plugin for LLMedia API plugin system * * @cond - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * - * Copyright (c) 2008-2010, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ + * 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$ * @endcond */ From a6f08b61c9303325687be756e1e980245f9d17cc Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sun, 7 Nov 2010 11:32:57 -0700 Subject: [PATCH 165/239] Ported media_plugin_webkit changes from Snowglobe2, which are identical to SL2.3. This includes a more stable version of llqtwebkit for Windows --- .../indra/media_plugins/webkit/media_plugin_webkit.cpp | 10 ++++++++-- linden/install.xml | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp index eed59a24d..4a0055792 100755 --- a/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/linden/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -37,7 +37,6 @@ #include "linden_common.h" #include "indra_constants.h" // for indra keyboard codes -#include <iomanip> #include "llgl.h" @@ -45,10 +44,10 @@ #include "llpluginmessage.h" #include "llpluginmessageclasses.h" #include "media_plugin_base.h" +#include <iomanip> // set to 1 if you're using the version of llqtwebkit that's QPixmap-ified #if LL_LINUX -# include <iomanip> # define LL_QTWEBKIT_USES_PIXMAPS 0 extern "C" { # include <glib.h> @@ -341,6 +340,12 @@ class MediaPluginWebKit : // append details to agent string LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); +// Viewer 2+ -- MC +#if LL_WINDOWS + // Set up window open behavior + LLQtWebKit::getInstance()->setWindowOpenBehavior(mBrowserWindowId, LLQtWebKit::WOB_SIMULATE_BLANK_HREF_CLICK); +#endif + #if !LL_QTWEBKIT_USES_PIXMAPS // don't flip bitmap LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); @@ -539,6 +544,7 @@ class MediaPluginWebKit : // This will work as long as we don't need "uuid", which will be needed for MoaP. message.setValue("uri", event.getStringValue()); message.setValue("target", event.getStringValue2()); + message.setValueU32("target_type", event.getLinkType()); #endif sendMessage(message); } diff --git a/linden/install.xml b/linden/install.xml index fbb269a57..ec57a7bdc 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -1057,9 +1057,9 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <key>windows</key> <map> <key>md5sum</key> - <string>4b8412833c00f8cdaba26808f0ddb404</string> + <string>df1bdd683128e060d60e435f65d8f7e8</string> <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100916.tar.bz2</uri> + <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100617.tar.bz2</uri> </map> </map> </map> From 022227e7ffc2754a4a0ac9590e9d49e0dca52edb Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 7 Nov 2010 19:43:43 +0000 Subject: [PATCH 166/239] Use apr_suite-1.3.8 for windows in order to get the dll version of libapr. Required for a DSO libllcommon --- linden/install.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index d61d07d65..af31d31f1 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -120,9 +120,9 @@ <key>windows</key> <map> <key>md5sum</key> - <string>b9d23a69a25fdeed96dcc3bf696b6514</string> + <string>a02619c1e30a3db02d3883bf1ad7a1e6</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.2.12-windows-20080806.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/apr_suite-1.3.8-windows-20090911.tar.bz2</uri> </map> </map> </map> From eeb08e9b2abd3ec1404dce77151899d90908df6a Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Sun, 7 Nov 2010 21:17:11 +0100 Subject: [PATCH 167/239] IMP-692: SNOW-713: Removed isHexString again, since it is not defined anywhere. --- linden/indra/llcommon/llstring.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index 44f5f07ea..ae5d84cee 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -174,8 +174,6 @@ class LL_COMMON_API LLStringOps static S32 collate(const char* a, const char* b) { return strcoll(a, b); } static S32 collate(const llwchar* a, const llwchar* b); - - static bool isHexString(const std::string& str); }; /** From 346e88760c55921ca474886168a89b104fd3f4cc Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 7 Nov 2010 20:28:12 +0000 Subject: [PATCH 168/239] Correctly stage libhunspell.dll in viewer_manifest.py --- linden/indra/newview/viewer_manifest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index f631d1f20..1383bba14 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -246,7 +246,9 @@ def construct(self): #self.path("fmod.dll") # For spellchecking - self.path("libhunspell.dll") + if self.prefix(src=self.args['configuration'], dst=""): + self.path("libhunspell.dll") + self.end_prefix() # Get llcommon and deps. if self.prefix(src=self.args['configuration'], dst=""): From c722768ddd66c4bf07d562517953ee520a2a10d0 Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 7 Nov 2010 20:29:53 +0000 Subject: [PATCH 169/239] As we currently do not build the gstreamer plugin for windows, do not try to stage it in viewer_manifest.py --- linden/indra/newview/viewer_manifest.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 1383bba14..30c0271c1 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -278,12 +278,7 @@ def construct(self): if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"): self.path("media_plugin_webkit.dll") self.end_prefix() - - # Media plugins - Gstreamer - if self.prefix(src='../media_plugins/gstreamer/%s' % self.args['configuration'], dst="llplugin"): - self.path("media_plugin_gstreamer010.dll", "media_plugin_gstreamer.dll") - self.end_prefix() - + # For WebKit/Qt plugin runtimes if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"): self.path("libeay32.dll") From 4f471ff939d1ad9b62280f11c5cf597cfc2c8596 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Mon, 8 Nov 2010 00:58:07 -0600 Subject: [PATCH 170/239] Transferred the new linux32 gtk-etc package to our server. --- linden/install.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/install.xml b/linden/install.xml index 95c7cec34..88b6ef3ef 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -702,7 +702,7 @@ cairo: Copyright © 2002 University of Southern California, Copyright © 2005 Re <key>md5sum</key> <string>349ee367e0ac1e878b24b66e449c6ff8</string> <key>url</key> - <uri>http://github.com/downloads/AlericInglewood/imprudence/gtk-etc-linux-20101106.1.tar.bz2</uri> + <uri>http://imprudenceviewer.org/download/libs/gtk-etc-linux-20101106.1.tar.bz2</uri> </map> <key>linux64</key> <map> From 6ae81eabfcaba2a989b5a0da5eac71ec7a9a39bc Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 7 Nov 2010 20:28:12 +0000 Subject: [PATCH 171/239] Correctly stage libhunspell.dll in viewer_manifest.py --- linden/indra/newview/viewer_manifest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 41495ca01..b1bb25064 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -246,7 +246,9 @@ def construct(self): #self.path("fmod.dll") # For spellchecking - self.path("libhunspell.dll") + if self.prefix(src=self.args['configuration'], dst=""): + self.path("libhunspell.dll") + self.end_prefix() # For textures if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""): From 257a706943a31507388c3a34fa0a744b409b1a4f Mon Sep 17 00:00:00 2001 From: Robin Cornelius <robin.cornelius@gmail.com> Date: Sun, 7 Nov 2010 20:29:53 +0000 Subject: [PATCH 172/239] As we currently do not build the gstreamer plugin for windows, do not try to stage it in viewer_manifest.py --- linden/indra/newview/viewer_manifest.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index b1bb25064..6dcd97765 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -270,12 +270,7 @@ def construct(self): if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"): self.path("media_plugin_webkit.dll") self.end_prefix() - - # Media plugins - Gstreamer - if self.prefix(src='../media_plugins/gstreamer/%s' % self.args['configuration'], dst="llplugin"): - self.path("media_plugin_gstreamer010.dll", "media_plugin_gstreamer.dll") - self.end_prefix() - + # For WebKit/Qt plugin runtimes if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"): self.path("libeay32.dll") From b305d2fcb6979e3e76c542710b37e2bfa4259277 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 9 Nov 2010 20:05:00 +0100 Subject: [PATCH 173/239] Install unstripped binary in packaged when --type=Debug This only affects linux. When one compiles the viewer with --type=Debug you want to be able to actually debug it, so you need debug symbols in the binary. Until now I manually copied imprudence-bin over the installed bin/do-not-directly-run-imprudence-bin, but this seems a more convient solution ;) --- linden/indra/lib/python/indra/util/llmanifest.py | 3 +++ linden/indra/newview/CMakeLists.txt | 3 +++ linden/indra/newview/viewer_manifest.py | 12 ++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/linden/indra/lib/python/indra/util/llmanifest.py b/linden/indra/lib/python/indra/util/llmanifest.py index 3444a1585..fc777b27a 100644 --- a/linden/indra/lib/python/indra/util/llmanifest.py +++ b/linden/indra/lib/python/indra/util/llmanifest.py @@ -121,6 +121,9 @@ def get_channel(srctree): default=""), dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE), dict(name='build', description='Build directory.', default=DEFAULT_SRCTREE), + dict(name='buildtype', + description='Set to DEBUG if this is a debug build.', + default="RELEASE"), dict(name='channel', description="""The channel to use for updates, packaging, settings name, etc.""", default=get_channel), diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index a4d99f232..77de749ca 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1356,6 +1356,7 @@ if (WINDOWS) --channel=${VIEWER_CHANNEL} --login_channel=${VIEWER_LOGIN_CHANNEL} --standalone=${STANDALONE} + --buildtype=${CMAKE_BUILD_TYPE} --grid=${GRID} --source=${CMAKE_CURRENT_SOURCE_DIR} --artwork=${ARTWORK_DIR} @@ -1434,6 +1435,7 @@ if (LINUX) ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py --standalone=${STANDALONE} + --buildtype=${CMAKE_BUILD_TYPE} --grid=${GRID} --channel=${VIEWER_CHANNEL} --login_channel=${VIEWER_LOGIN_CHANNEL} @@ -1498,6 +1500,7 @@ if (DARWIN) ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py --standalone=${STANDALONE} + --buildtype=${CMAKE_BUILD_TYPE} --grid=${GRID} --configuration=${CMAKE_CFG_INTDIR} --channel=${VIEWER_CHANNEL} diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 6dcd97765..cc22748fb 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -162,6 +162,8 @@ def login_channel(self): def standalone(self): return self.args['standalone'] == "ON" + def debug(self): + return self.args['buildtype'] == "DEBUG" def grid(self): return self.args['grid'] def channel(self): @@ -945,7 +947,10 @@ def package_finish(self): class Linux_i686Manifest(LinuxManifest): def construct(self): super(Linux_i686Manifest, self).construct() - self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") + if self.debug(): + self.path("imprudence-bin","bin/do-not-directly-run-imprudence-bin") + else: + self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") if (not self.standalone()) and self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"): self.path("libapr-1.so.0") @@ -1061,7 +1066,10 @@ def construct(self): class Linux_x86_64Manifest(LinuxManifest): def construct(self): super(Linux_x86_64Manifest, self).construct() - self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") + if self.debug(): + self.path("imprudence-bin","bin/do-not-directly-run-imprudence-bin") + else: + self.path("imprudence-stripped","bin/do-not-directly-run-imprudence-bin") # self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin") self.path("linux_tools/launch_url.sh","launch_url.sh") From 44c07eb2c58c4898752ad813d46c224ccd7229f1 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Mon, 8 Nov 2010 19:51:32 +0100 Subject: [PATCH 174/239] feature: add a tiny context menu to areasearch scroll list items rightclick one of the results and teleport or cam to the object or bring it in edit mode --- linden/indra/llui/llscrolllistctrl.cpp | 38 ++++++ linden/indra/llui/llscrolllistctrl.h | 4 + linden/indra/newview/jcfloaterareasearch.cpp | 117 ++++++++++++++++++ linden/indra/newview/jcfloaterareasearch.h | 17 +++ .../default/xui/en-us/menu_areasearch.xml | 16 +++ 5 files changed, 192 insertions(+) create mode 100644 linden/indra/newview/skins/default/xui/en-us/menu_areasearch.xml diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index 9635f99f7..1248a9a49 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp @@ -605,6 +605,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), mBorderThickness( 2 ), mOnDoubleClickCallback( NULL ), + mOnRightMouseDownCallback( NULL ), mOnMaximumSelectCallback( NULL ), mOnSortChangedCallback( NULL ), mHighlightedItem(-1), @@ -2082,6 +2083,27 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } +BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + //BOOL handled = FALSE; + BOOL handled = handleClick(x, y, mask); + + if (!handled) + { + // Offer the click to the children, even if we aren't enabled + // so the scroll bars will work. + if (NULL == LLView::childrenHandleRightMouseDown(x, y, mask)) + { + if( mCanSelect && mOnRightMouseDownCallback ) + { + mOnRightMouseDownCallback( x, y, mCallbackUserData ); + } + } + } + + return TRUE; +} + BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) { // which row was clicked on? @@ -3631,6 +3653,22 @@ BOOL LLColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } +BOOL LLColumnHeader::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if (canResize() && mResizeBar->getRect().pointInRect(x, y)) + { + // reshape column to max content width + LLRect column_rect = getRect(); + column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; + userSetShape(column_rect); + } + else + { + onClick(this); + } + return TRUE; +} + void LLColumnHeader::setImage(const std::string &image_name) { if (mButton) diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index e875d7a52..4be7ff7e2 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h @@ -241,6 +241,7 @@ class LLColumnHeader : public LLComboBox /*virtual*/ void draw(); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ void showList(); /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding); @@ -431,6 +432,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, void highlightNthItem( S32 index ); void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; } + void setRightMouseDownCallback( void (*cb)(S32 x, S32 y, void*) ) { mOnRightMouseDownCallback = cb; } void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; } void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; } @@ -517,6 +519,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); @@ -660,6 +663,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, S32 mBorderThickness; void (*mOnDoubleClickCallback)(void* userdata); + void (*mOnRightMouseDownCallback)(S32 x, S32 y, void* userdata); void (*mOnMaximumSelectCallback)(void* userdata ); void (*mOnSortChangedCallback)(void* userdata); diff --git a/linden/indra/newview/jcfloaterareasearch.cpp b/linden/indra/newview/jcfloaterareasearch.cpp index ed00447df..0918431ba 100644 --- a/linden/indra/newview/jcfloaterareasearch.cpp +++ b/linden/indra/newview/jcfloaterareasearch.cpp @@ -38,7 +38,14 @@ #include "llscrolllistctrl.h" #include "llagent.h" + +#include "llfloatertools.h" +#include "llmenugl.h" +#include "llselectmgr.h" +#include "lltoolcomp.h" +#include "lltoolmgr.h" #include "lltracker.h" +#include "llviewerjoystick.h" #include "llviewerobjectlist.h" #include "llviewercontrol.h" #include "jcfloaterareasearch.h" @@ -63,6 +70,19 @@ mResultList(0) llassert_always(sInstance == NULL); sInstance = this; mLastUpdateTimer.reset(); + + + // Register event listeners for popup menu + mPopupMenuHandler = new PopupMenuHandler(this); + mPopupMenuHandler->registerListener(this, "Popup.HandleMenu"); + + LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_areasearch.xml", this); + if (!menu) + { + menu = new LLMenuGL(LLStringUtil::null); + } + menu->setVisible(FALSE); + mPopupMenuHandle = menu->getHandle(); } JCFloaterAreaSearch::~JCFloaterAreaSearch() @@ -90,6 +110,7 @@ BOOL JCFloaterAreaSearch::postBuild() mResultList = getChild<LLScrollListCtrl>("result_list"); mResultList->setCallbackUserData(this); mResultList->setDoubleClickCallback(onDoubleClick); + mResultList->setRightMouseDownCallback(onRightMouseDown); mResultList->sortByColumn("Name", TRUE); mCounterText = getChild<LLTextBox>("counter"); @@ -159,6 +180,102 @@ void JCFloaterAreaSearch::onDoubleClick(void *userdata) } } +//static +void JCFloaterAreaSearch::onRightMouseDown(S32 x, S32 y, void *userdata) +{ + JCFloaterAreaSearch* self = (JCFloaterAreaSearch*)userdata; + + self->setFocus( TRUE ); + LLMenuGL* menu = (LLMenuGL*)self->mPopupMenuHandle.get(); + if(menu) + { + if(menu->getVisible()) + { + menu->setVisible(FALSE); + } + else + { + LLScrollListItem *item = self->mResultList->getFirstSelected(); + if (item) + { + self->mSelectedItem = item; + menu->setVisible(TRUE); + menu->setFocus(TRUE); + menu->arrange(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(self, menu, x, y+50); + } + else + { + self->mSelectedItem = NULL; + } + } + } + +} + +JCFloaterAreaSearch::PopupMenuHandler::PopupMenuHandler(const JCFloaterAreaSearch* instance) + : mInstance(instance) +{ + +} + +// static +bool JCFloaterAreaSearch::PopupMenuHandler::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) +{ + std::string command = userdata.asString(); + JCFloaterAreaSearch* self = (JCFloaterAreaSearch*)mInstance; + + if (self && self->mSelectedItem && !command.empty()) + { + LLUUID object_id = self->mSelectedItem->getUUID(); + LLViewerObject* object = gObjectList.findObject(object_id); + + if (object && !object->isAvatar()) + { + + + if ("teleport" == command) + { + LLVector3d pos = object->getPositionGlobal(); + gAgent.teleportViaLocation(pos); + + } + else + { + if ("cam" || "edit" == command) + { + + gAgent.setFocusOnAvatar(FALSE, FALSE); + gAgent.changeCameraToThirdPerson(); + gAgent.setFocusGlobal(object->getPositionGlobal(), object_id); + gAgent.setCameraPosAndFocusGlobal(object->getPositionGlobal() + + LLVector3d(3.5,1.35,0.75) * object->getRotation(), + object->getPositionGlobal(), + object_id ); + if ("edit" == command) + { + if(!object->isSelected()) + { + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(object); + } + + gFloaterTools->open(); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); + + LLViewerJoystick::getInstance()->moveObjects(true); + LLViewerJoystick::getInstance()->setNeedsReset(true); + } + } + } + } + } + + return true; +} + // static void JCFloaterAreaSearch::cancel(void* data) { diff --git a/linden/indra/newview/jcfloaterareasearch.h b/linden/indra/newview/jcfloaterareasearch.h index 151203052..5bceb5988 100644 --- a/linden/indra/newview/jcfloaterareasearch.h +++ b/linden/indra/newview/jcfloaterareasearch.h @@ -35,9 +35,11 @@ #include "lluuid.h" #include "llstring.h" #include "llframetimer.h" +#include "llmemberlistener.h" class LLTextBox; class LLScrollListCtrl; +class LLScrollListItem; class LLViewerRegion; struct AObjectDetails @@ -71,6 +73,7 @@ class JCFloaterAreaSearch : public LLFloater static void onCommitLine(LLLineEditor* line, void* user_data); static void requestIfNeeded(LLViewerObject *objectp); static void onDoubleClick(void *userdata); + static void onRightMouseDown(S32 x, S32 y, void *userdata); enum OBJECT_COLUMN_ORDER { @@ -86,6 +89,7 @@ class JCFloaterAreaSearch : public LLFloater LLTextBox* mCounterText; LLScrollListCtrl* mResultList; + LLScrollListItem* mSelectedItem; LLFrameTimer mLastUpdateTimer; static std::map<LLUUID, AObjectDetails> sObjectDetails; @@ -96,4 +100,17 @@ class JCFloaterAreaSearch : public LLFloater static std::string sSearchedGroup; static LLViewerRegion* sLastRegion; + + LLHandle<LLView> mPopupMenuHandle; + + class PopupMenuHandler : public LLMemberListener<JCFloaterAreaSearch> + { + public: PopupMenuHandler(const JCFloaterAreaSearch* instance); + + /*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata); + + const JCFloaterAreaSearch* mInstance; + }; + + class PopupMenuHandler* mPopupMenuHandler; }; diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_areasearch.xml b/linden/indra/newview/skins/default/xui/en-us/menu_areasearch.xml new file mode 100644 index 000000000..c55d1b36a --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/menu_areasearch.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu bottom="100" color="MenuDefaultBgColor" drop_shadow="true" height="101" left="100" + mouse_opaque="false" name="popup" opaque="true" width="128"> + <menu_item_call bottom_delta="-18" height="18" label="Teleport to" left="0" + mouse_opaque="true" name="teleport" width="128"> + <on_click function="Popup.HandleMenu" userdata="teleport" /> + </menu_item_call> + <menu_item_call bottom_delta="-18" height="18" label="Cam to" left="0" + mouse_opaque="true" name="cam" width="128"> + <on_click function="Popup.HandleMenu" userdata="cam" /> + </menu_item_call> + <menu_item_call bottom_delta="-18" height="18" label="Edit" left="0" + mouse_opaque="true" name="edit" width="128"> + <on_click function="Popup.HandleMenu" userdata="edit" /> + </menu_item_call> +</menu> From 88df6cce7308b86b1526bd253440a6538e337d44 Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Tue, 9 Nov 2010 23:34:29 +0100 Subject: [PATCH 175/239] fix: add missing settings for logging into Aurora Sim --- .../indra/newview/app_settings/settings.xml | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 22e4aa5e7..2f29b17ae 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -1,7 +1,43 @@ <?xml version="1.0" ?> <llsd> <map> - + +<!-- for Aurora Sim --> + + <key>TimeOffset</key> + <map> + <key>Comment</key> + <string>difference in hours to UTC time</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>UseTimeOffset</key> + <map> + <key>Comment</key> + <string>Use debug setting TimeOffset</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>TimeOffsetDST</key> + <map> + <key>Comment</key> + <string>TimeOffset has Day Light Savings</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <!-- Imprudence-specific settings --> <!-- begin name highlighting --> From 1e88050a4ab2d5e517fdb2cea4c0e2727791cffb Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Tue, 9 Nov 2010 23:54:35 +0100 Subject: [PATCH 176/239] fix: add missing AllowEditingOfTrees setting --- linden/indra/newview/app_settings/settings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 2f29b17ae..33299ba00 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -40,6 +40,18 @@ <!-- Imprudence-specific settings --> + <key>AllowEditingOfTrees</key> + <map> + <key>Comment</key> + <string>Allow editing of trees and grass</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <!-- begin name highlighting --> <key>HighlightNickname01</key> From c96a895861c6c81b486c3e2c2cc46adcdba11cea Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Tue, 9 Nov 2010 21:52:45 -0600 Subject: [PATCH 177/239] llstring.h directly depends on #include <map>. --- linden/indra/llcommon/llstring.h | 1 + 1 file changed, 1 insertion(+) diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index ae5d84cee..61767ace5 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h @@ -36,6 +36,7 @@ #include <string> #include <cstdio> #include <algorithm> +#include <map> #if LL_LINUX || LL_SOLARIS #include <wctype.h> From 5c181529a528f5f80737652b914fca42205ac92e Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Wed, 10 Nov 2010 16:43:49 +0200 Subject: [PATCH 178/239] Fix #699: Can't drag prims with translate manipulator --- linden/indra/newview/hippolimits.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/hippolimits.cpp b/linden/indra/newview/hippolimits.cpp index 851e191ee..3368ba4c4 100644 --- a/linden/indra/newview/hippolimits.cpp +++ b/linden/indra/newview/hippolimits.cpp @@ -21,7 +21,8 @@ HippoLimits::HippoLimits() mMaxHollow(0.95f), mMinPrimScale(0.001f), mMaxPrimScale(256.0f), - mMaxLinkedPrims(-1) + mMaxLinkedPrims(-1), + mMaxDragDistance(0.f) { setLimits(); } @@ -207,7 +208,7 @@ F32 HippoLimits::getMinPrimZPos() const F32 HippoLimits::getMaxDragDistance() const { - if (mMaxDragDistance == 0) + if (mMaxDragDistance == 0.f) { return FLT_MAX; } @@ -215,9 +216,9 @@ F32 HippoLimits::getMaxDragDistance() const { F32 max_drag_distance = gSavedSettings.getBOOL("LimitDragDistance") ? gSavedSettings.getF32("MaxDragDistance") : FLT_MAX; - if(max_drag_distance > mMaxDragDistance) //Chose the more restrictive - { - max_drag_distance = mMaxDragDistance; + if(max_drag_distance > mMaxDragDistance) //Chose the more restrictive + { + max_drag_distance = mMaxDragDistance; } return max_drag_distance; } From 7b5e0f297726bf58fd4dfd3ed2725af891952835 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Wed, 10 Nov 2010 20:10:13 +0200 Subject: [PATCH 179/239] Fix #700: View -> Web Browser does nothing Also made the "Home" and "Set Home" buttons work. "Send current URL to parcel" is still broken in SL, since it relies on the ParcelNavigateMedia capability which was never implemented by LL. --- .../indra/newview/llfloatermediabrowser.cpp | 43 ++++++++++++++++++- linden/indra/newview/llfloatermediabrowser.h | 2 + linden/indra/newview/llviewermenu.cpp | 8 ++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/linden/indra/newview/llfloatermediabrowser.cpp b/linden/indra/newview/llfloatermediabrowser.cpp index def015943..d658a1158 100644 --- a/linden/indra/newview/llfloatermediabrowser.cpp +++ b/linden/indra/newview/llfloatermediabrowser.cpp @@ -35,6 +35,8 @@ #include "llfloatermediabrowser.h" #include "llfloaterhtml.h" +#include "llchat.h" +#include "llfloaterchat.h" #include "llparcel.h" #include "llpluginclassmedia.h" #include "lluictrlfactory.h" @@ -43,6 +45,7 @@ #include "llviewercontrol.h" #include "llviewerparcelmgr.h" #include "llweb.h" +#include "lltrans.h" #include "llui.h" #include "roles_constants.h" @@ -64,12 +67,14 @@ LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) void LLFloaterMediaBrowser::draw() { - childSetEnabled("go", !mAddressCombo->getValue().asString().empty()); + BOOL url_exists = !mAddressCombo->getValue().asString().empty(); + childSetEnabled("go", url_exists); + childSetEnabled("set_home", url_exists); LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if(parcel) { childSetVisible("parcel_owner_controls", LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA)); - childSetEnabled("assign", !mAddressCombo->getValue().asString().empty()); + childSetEnabled("assign", url_exists); } bool show_time_controls = false; bool media_playing = false; @@ -118,8 +123,11 @@ BOOL LLFloaterMediaBrowser::postBuild() childSetAction("close", onClickClose, this); childSetAction("open_browser", onClickOpenWebBrowser, this); childSetAction("assign", onClickAssign, this); + childSetAction("home", onClickHome, this); + childSetAction("set_home", onClickSetHome, this); buildURLHistory(); + return TRUE; } @@ -283,6 +291,37 @@ void LLFloaterMediaBrowser::onClickAssign(void* user_data) } LLViewerParcelMedia::sendMediaNavigateMessage(media_url); } + +// static +void LLFloaterMediaBrowser::onClickHome(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + if (self) + { + if (self->mBrowser) + { + std::string home_url = gSavedSettings.getString("BrowserHome"); + self->mBrowser->navigateTo(home_url); + } + } +} + +// static +void LLFloaterMediaBrowser::onClickSetHome(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + std::string url = self->mCurrentURL; + if(!url.empty()) + { + LLChat chat; + std::string log_message = LLTrans::getString("new_home_page") + " "; + log_message += url; + chat.mText = log_message; + LLFloaterChat::addChat(chat, FALSE, FALSE); + gSavedSettings.setString("BrowserHome", url); + } +} + //static void LLFloaterMediaBrowser::onClickRewind(void* user_data) { diff --git a/linden/indra/newview/llfloatermediabrowser.h b/linden/indra/newview/llfloatermediabrowser.h index 8a78df833..7de190064 100644 --- a/linden/indra/newview/llfloatermediabrowser.h +++ b/linden/indra/newview/llfloatermediabrowser.h @@ -85,6 +85,8 @@ class LLFloaterMediaBrowser : static void onClickClose(void* user_data); static void onClickOpenWebBrowser(void* user_data); static void onClickAssign(void* user_data); + static void onClickHome(void* user_data); + static void onClickSetHome(void* user_data); static void onClickRewind(void* user_data); static void onClickPlay(void* user_data); static void onClickStop(void* user_data); diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index a663e60d9..b81a2a29a 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -6091,10 +6091,10 @@ class LLShowFloater : public view_listener_t { JCFloaterAnimList::toggleInstance(LLSD()); } -//imprudence fixme else if (floater_name == "inworld browser") -// { -// LLFloaterMediaBrowser::toggle(); -// } + else if (floater_name == "inworld browser") + { + LLWeb::loadURL(gSavedSettings.getString("BrowserHome")); + } else if (floater_name == "beacons") { LLFloaterBeacons::toggleInstance(LLSD()); From 37aca802374aabd3932f49e8fd7b6bdee70069ca Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Wed, 10 Nov 2010 20:18:37 +0200 Subject: [PATCH 180/239] More #700: remove llfloaterhtmlhelp.cpp This file is media plugin a merge leftover. It was renamed to llfloatermediabrowser.cpp, but somehow this got left behind. --- linden/indra/newview/llfloaterhtmlhelp.cpp | 562 --------------------- 1 file changed, 562 deletions(-) delete mode 100644 linden/indra/newview/llfloaterhtmlhelp.cpp diff --git a/linden/indra/newview/llfloaterhtmlhelp.cpp b/linden/indra/newview/llfloaterhtmlhelp.cpp deleted file mode 100644 index c89c2e283..000000000 --- a/linden/indra/newview/llfloaterhtmlhelp.cpp +++ /dev/null @@ -1,562 +0,0 @@ -/** - * @file llfloaterhtmlhelp.cpp - * @brief HTML Help floater - uses embedded web browser control - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterhtmlhelp.h" -#include "llfloaterhtml.h" - -#include "llchat.h" -#include "llfloaterchat.h" -#include "llparcel.h" -#include "lluictrlfactory.h" -#include "llwebbrowserctrl.h" -#include "llviewerwindow.h" -#include "llviewercontrol.h" -#include "llviewerparcelmgr.h" -#include "llweb.h" -#include "lltrans.h" -#include "llui.h" -#include "roles_constants.h" - -#include "llurlhistory.h" -#include "llwebbrowserctrl.h" -#include "llviewermedia.h" -#include "llviewerparcelmedia.h" -#include "llcombobox.h" - -#include "hippogridmanager.h" - -LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_browser.xml"); -} - -void LLFloaterMediaBrowser::draw() -{ - BOOL url_exists = !mAddressCombo->getValue().asString().empty(); - childSetEnabled("go", url_exists); - childSetEnabled("set_home", url_exists); - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if(parcel) - { - childSetVisible("parcel_owner_controls", LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA)); - childSetEnabled("assign", !mAddressCombo->getValue().asString().empty()); - } - LLFloater::draw(); -} - -BOOL LLFloaterMediaBrowser::postBuild() -{ - mBrowser = getChild<LLWebBrowserCtrl>("browser"); - mBrowser->addObserver(this); - - mAddressCombo = getChild<LLComboBox>("address"); - mAddressCombo->setCommitCallback(onEnterAddress); - mAddressCombo->setCallbackUserData(this); - - childSetAction("back", onClickBack, this); - childSetAction("forward", onClickForward, this); - childSetAction("reload", onClickRefresh, this); - childSetAction("go", onClickGo, this); - childSetAction("close", onClickClose, this); - childSetAction("open_browser", onClickOpenWebBrowser, this); - childSetAction("assign", onClickAssign, this); - childSetAction("home", onClickHome, this); - childSetAction("set_home", onClickSetHome, this); - - buildURLHistory(); - - //Show home url if new session, last visited if not - std::string last_url = gSavedSettings.getString("BrowserLastVisited"); - if (last_url.empty()) - { - last_url = gSavedSettings.getString("BrowserHome"); - } - openMedia(last_url); - - return TRUE; -} - -void LLFloaterMediaBrowser::buildURLHistory() -{ - LLCtrlListInterface* url_list = childGetListInterface("address"); - if (url_list) - { - url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); - } - - // Get all of the entries in the "parcel" collection - LLSD parcel_history = LLURLHistory::getURLHistory("browser"); - - LLSD::array_iterator iter_history = - parcel_history.beginArray(); - LLSD::array_iterator end_history = - parcel_history.endArray(); - for(; iter_history != end_history; ++iter_history) - { - std::string url = (*iter_history).asString(); - if(! url.empty()) - url_list->addSimpleElement(url); - } -} - -void LLFloaterMediaBrowser::onClose(bool app_quitting) -{ - //setVisible(FALSE); - destroy(); -} - -void LLFloaterMediaBrowser::onLocationChange( const EventType& eventIn ) -{ - // hitting the refresh button will navigate to same URL, so don't add to address history - mCurrentURL = eventIn.getStringValue(); - std::string::size_type string_start = mCurrentURL.find("://"); - std::string truncated_url; - if ((string_start == std::string::npos) || (1)) // NOTE: this conditional is forced true to disable truncation DEV-9834 - { - truncated_url = mCurrentURL; - } - else - { - truncated_url = mCurrentURL.substr(string_start + 3); - } - // redirects will navigate momentarily to about:blank, don't add to history - if (truncated_url != "about:blank") - { - mAddressCombo->remove(truncated_url); - mAddressCombo->add(truncated_url, ADD_SORTED); - mAddressCombo->selectByValue(truncated_url); - - // Serialize url history - LLURLHistory::removeURL("browser", truncated_url); - LLURLHistory::addURL("browser", truncated_url); - } - childSetEnabled("back", mBrowser->canNavigateBack()); - childSetEnabled("forward", mBrowser->canNavigateForward()); - childSetEnabled("reload", TRUE); - gSavedSettings.setString("BrowserLastVisited", truncated_url); -} - -//static -void LLFloaterMediaBrowser::helpF1() -{ - std::string url = gSavedSettings.getString("HelpSupportURL"); - LLSD payload; - payload["url"] = url; - - LLNotifications::instance().add("ClickOpenF1Help", LLSD(), payload, onClickF1HelpLoadURL); -} - -// static -bool LLFloaterMediaBrowser::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option == 0) - { - LLWeb::loadURL(notification["payload"]["url"].asString()); - } - return false; -} - -//static -void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); -} - -//static -void LLFloaterMediaBrowser::onClickRefresh(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - - self->mAddressCombo->remove(0); - self->mBrowser->navigateTo(self->mCurrentURL); -} - -//static -void LLFloaterMediaBrowser::onClickForward(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - - self->mBrowser->navigateForward(); -} - -//static -void LLFloaterMediaBrowser::onClickBack(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - - self->mBrowser->navigateBack(); -} - -//static -void LLFloaterMediaBrowser::onClickGo(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - - self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); -} - -//static -void LLFloaterMediaBrowser::onClickClose(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - - self->close(); -} - -//static -void LLFloaterMediaBrowser::onClickOpenWebBrowser(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - - std::string url = self->mCurrentURL.empty() ? - self->mBrowser->getHomePageUrl() : - self->mCurrentURL; - LLWeb::loadURLExternal(url); -} - -void LLFloaterMediaBrowser::onClickAssign(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (!parcel) - { - return; - } - std::string media_url = self->mAddressCombo->getValue().asString(); - LLStringUtil::trim(media_url); - - parcel->setMediaURL(media_url); - parcel->setMediaType(std::string("text/html")); - - // Send current parcel data upstream to server - LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel, true ); - // now check for video - LLViewerParcelMedia::update( parcel ); -} - -// static -void LLFloaterMediaBrowser::onClickHome(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - if (self) - { - if (self->mBrowser) - { - std::string home_url = gSavedSettings.getString("BrowserHome"); - self->mBrowser->navigateTo(home_url); - } - } -} - -void LLFloaterMediaBrowser::onClickSetHome(void* user_data) -{ - LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; - std::string url = self->mCurrentURL; - if(!url.empty()) - { - LLChat chat; - std::string log_message = LLTrans::getString("new_home_page") + " "; - log_message += url; - chat.mText = log_message; - LLFloaterChat::addChat(chat, FALSE, FALSE); - gSavedSettings.setString("BrowserHome", url); - } -} - -void LLFloaterMediaBrowser::openMedia(const std::string& media_url) -{ - mBrowser->setHomePageUrl(media_url); - mBrowser->navigateTo(media_url); -} - -LLViewerHtmlHelp gViewerHtmlHelp; - -class LLFloaterHtmlHelp : - public LLFloater, - public LLWebBrowserCtrlObserver -{ -public: - LLFloaterHtmlHelp(std::string start_url, std::string title); - virtual ~LLFloaterHtmlHelp(); - - virtual void onClose( bool app_quitting ); - virtual void draw(); - - static void show(std::string url, std::string title); - -private: - static void onClickBack( void* data ); - //static void onClickHome( void* data ); - static void onClickForward( void* data ); - static void onClickClose( void* data ); - - // browser observer impls - virtual void onStatusTextChange( const EventType& eventIn ); - virtual void onLocationChange( const EventType& eventIn ); - - // used for some stats logging - will be removed at some point - static BOOL sFloaterOpened; - - static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response); - - LLWebBrowserCtrl* mWebBrowser; - static LLFloaterHtmlHelp* sInstance; - LLButton* mBackButton; - LLButton* mForwardButton; - LLButton* mCloseButton; - LLTextBox* mStatusText; - std::string mStatusTextContents; - std::string mCurrentUrl; - std::string mSupportUrl; -}; - -LLFloaterHtmlHelp* LLFloaterHtmlHelp::sInstance = 0; - -BOOL LLFloaterHtmlHelp::sFloaterOpened = FALSE; - -//////////////////////////////////////////////////////////////////////////////// -// -LLFloaterHtmlHelp::LLFloaterHtmlHelp(std::string start_url, std::string title) -: LLFloater( std::string("HTML Help") ), - mWebBrowser( 0 ), - mStatusTextContents( LLStringUtil::null ), - mCurrentUrl( LLStringUtil::null ) -{ - sInstance = this; - - // create floater from its XML definition - LLUICtrlFactory::getInstance()->buildFloater( this, "floater_html_help.xml" ); - - childSetAction("back_btn", onClickBack, this); - //childSetAction("home_btn", onClickHome, this); - childSetAction("forward_btn", onClickForward, this); - - if (!title.empty()) - { - setTitle(title); - } - - mWebBrowser = getChild<LLWebBrowserCtrl>("html_help_browser" ); - if ( mWebBrowser ) - { - // observe browser control events - mWebBrowser->addObserver( this ); - - if (start_url != "") - { - mWebBrowser->navigateTo( start_url ); - } - else - { - // if the last page we were at before the client was closed is valid, go there and - // override what is in the XML file - // (not when the window was closed - it's only ever hidden - not closed) - std::string lastPageUrl = gSavedSettings.getString( "HtmlHelpLastPage" ); - if ( lastPageUrl != "" ) - { - mWebBrowser->navigateTo( lastPageUrl ); - }; - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLFloaterHtmlHelp::~LLFloaterHtmlHelp() -{ - // stop observing browser events - if ( mWebBrowser ) - { - mWebBrowser->remObserver( this ); - }; - - // save position of floater - gSavedSettings.setRect( "HtmlHelpRect", getRect() ); - - // save the location we were at when SL closed - gSavedSettings.setString( "HtmlHelpLastPage", mCurrentUrl ); - - sInstance = 0; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -void LLFloaterHtmlHelp::draw() -{ - // enable/disable buttons depending on state - if ( mWebBrowser ) - { - bool enable_back = mWebBrowser->canNavigateBack(); - childSetEnabled( "back_btn", enable_back ); - - bool enable_forward = mWebBrowser->canNavigateForward(); - childSetEnabled( "forward_btn", enable_forward ); - }; - - LLFloater::draw(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterHtmlHelp::show(std::string url, std::string title) -{ - LLFloaterHtml* floater_html = LLFloaterHtml::getInstance(); - floater_html->setVisible(FALSE); - - url = gHippoGridManager->getConnectedGrid()->getSupportUrl(); - if (!url.empty()) - { - if (gSavedSettings.getBOOL("UseExternalBrowser")) - { - LLSD payload; - payload["url"] = url; - LLNotifications::instance().add("ClickOpenF1Help", LLSD(), payload, onClickF1HelpLoadURL); - } - else - { - // don't wait, just do it - LLWeb::loadURLInternal(url); - } - } - else - { - LLNotifications::instance().add("NoSupportUrl"); - } -} - -// static -bool LLFloaterHtmlHelp::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - if (option == 0) - { - const std::string& url = notification["payload"]["url"].asString(); - if (!url.empty()) - { - LLWeb::loadURLExternal(url); - } - else - { - llwarns << "Support URL not available." << llendl; - } - } - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterHtmlHelp::onClose( bool app_quitting ) -{ - setVisible( false ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterHtmlHelp::onClickClose( void* data ) -{ - LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; - - self->setVisible( false ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterHtmlHelp::onClickBack( void* data ) -{ - LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; - if ( self ) - { - if ( self->mWebBrowser ) - { - self->mWebBrowser->navigateBack(); - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterHtmlHelp::onClickForward( void* data ) -{ - LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; - if ( self ) - { - if ( self->mWebBrowser ) - { - self->mWebBrowser->navigateForward(); - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterHtmlHelp::onStatusTextChange( const EventType& eventIn ) -{ - mStatusTextContents = std::string( eventIn.getStringValue() ); - - childSetText("status_text", mStatusTextContents); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterHtmlHelp::onLocationChange( const EventType& eventIn ) -{ - llinfos << "WEB> Location changed to " << eventIn.getStringValue() << llendl; - mCurrentUrl = std::string( eventIn.getStringValue() ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLViewerHtmlHelp::LLViewerHtmlHelp() -{ - LLUI::setHtmlHelp(this); -} - -LLViewerHtmlHelp::~LLViewerHtmlHelp() -{ - LLUI::setHtmlHelp(NULL); -} - -void LLViewerHtmlHelp::show() -{ - LLFloaterHtmlHelp::show("", ""); -} - -void LLViewerHtmlHelp::show(std::string url) -{ - std::string title; // empty - LLFloaterHtmlHelp::show(url, title); -} From a99afc222d2e01d64663698740d1a9f937e8559b Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Wed, 10 Nov 2010 21:50:02 -0700 Subject: [PATCH 181/239] Added missing 'Plugin' entry in logcontrol.xml --- linden/indra/newview/app_settings/logcontrol.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/linden/indra/newview/app_settings/logcontrol.xml b/linden/indra/newview/app_settings/logcontrol.xml index 682bf6492..c94fc5143 100644 --- a/linden/indra/newview/app_settings/logcontrol.xml +++ b/linden/indra/newview/app_settings/logcontrol.xml @@ -66,6 +66,7 @@ <!--<string>Messaging</string>--> <!--<string>Notifications</string>--> + <!--<string>Plugin</string>--> <!--<string>Radar</string>--> <!--<string>ShaderLoading</string>--> From 9720f46f1a4e5b40d34c1e899df66cf317ff13db Mon Sep 17 00:00:00 2001 From: Nicky Perian <nickyperian@yahoo.com> Date: Fri, 12 Nov 2010 09:29:44 -0600 Subject: [PATCH 182/239] contributions --- linden/doc/contributions.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index cd6544a98..e8e91a1d5 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -465,6 +465,9 @@ Nicholaz Beresford VWR-2412 VWR-2682 VWR-2684 +Nicky Perian + IMP-680 + IMP-685 Nounouch Hapmouche VWR-238 Patric Mills From 3660a161226dde0153fa5c59a468969ab7f1613b Mon Sep 17 00:00:00 2001 From: Nicky Perian <nickyperian@yahoo.com> Date: Fri, 12 Nov 2010 10:13:00 -0600 Subject: [PATCH 183/239] tabs required in contributions.txt --- linden/doc/contributions.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index e8e91a1d5..d390a43d0 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -466,8 +466,8 @@ Nicholaz Beresford VWR-2682 VWR-2684 Nicky Perian - IMP-680 - IMP-685 + IMP-680 + IMP-685 Nounouch Hapmouche VWR-238 Patric Mills From 86c2b6fd2a17f575998bd6efdcab5aa4bafc86b9 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 12 Nov 2010 21:39:40 +0100 Subject: [PATCH 184/239] Add support for using ld.gold on linux. To use ld.gold configure with: -DCMAKE_EXE_LINKER_FLAGS:STRING="-Wl,-use-gold". ld.gold links the viewer on my machine in 8 seconds, as opposed to 19 seconds with ld.bfd. Moreover, it uses a LOT less memory during linking (about 750 MB instead of 2.5 GB!). Thanks to Siana Gearz for pointing out that ld.gold is so much faster. --- linden/indra/cmake/BerkeleyDB.cmake | 7 ++++++- linden/indra/cmake/LLCommon.cmake | 10 ++++++++-- linden/indra/llwindow/CMakeLists.txt | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/linden/indra/cmake/BerkeleyDB.cmake b/linden/indra/cmake/BerkeleyDB.cmake index d98e79179..de627638a 100644 --- a/linden/indra/cmake/BerkeleyDB.cmake +++ b/linden/indra/cmake/BerkeleyDB.cmake @@ -6,6 +6,11 @@ set(DB_FIND_REQUIRED ON) if (STANDALONE) include(FindBerkeleyDB) else (STANDALONE) - set(DB_LIBRARIES db-4.2) + if (LINUX) + # Need to add dependency pthread explicitely to support ld.gold. + set(DB_LIBRARIES db-4.2 pthread) + else (LINUX) + set(DB_LIBRARIES db-4.2) + endif (LINUX) set(DB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) endif (STANDALONE) diff --git a/linden/indra/cmake/LLCommon.cmake b/linden/indra/cmake/LLCommon.cmake index 410766e4f..d87d3c015 100644 --- a/linden/indra/cmake/LLCommon.cmake +++ b/linden/indra/cmake/LLCommon.cmake @@ -7,9 +7,15 @@ include(ZLIB) set(LLCOMMON_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llcommon - ${APRUTIL_INCLUDE_DIR} ${APR_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ) -set(LLCOMMON_LIBRARIES llcommon) +if (LINUX) + # In order to support using ld.gold on linux, we need to explicitely + # specify all libraries that llcommon uses. + # llcommon uses `clock_gettime' which is provided by librt on linux. + set(LLCOMMON_LIBRARIES llcommon rt) +else (LINUX) + set(LLCOMMON_LIBRARIES llcommon) +endif (LINUX) diff --git a/linden/indra/llwindow/CMakeLists.txt b/linden/indra/llwindow/CMakeLists.txt index 522416349..ea81abf19 100644 --- a/linden/indra/llwindow/CMakeLists.txt +++ b/linden/indra/llwindow/CMakeLists.txt @@ -59,6 +59,7 @@ set(viewer_HEADER_FILES set(llwindow_LINK_LIBRARIES ${UI_LIBRARIES} # for GTK ${SDL_LIBRARY} + fontconfig # For FCInit and other FC* functions. ) if (DARWIN) From 46a23d417168dcd11be75825ace7ff4ff3110c03 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 13 Nov 2010 00:21:19 +0200 Subject: [PATCH 185/239] Partial fix #614: wrong calculation of thread run time Use gFrameIntervalSeconds instead of gFrameTimeSeconds - which is what the original author tried to do. Also, clean up some dead code. *However*, there is still the issue of texture fetch workers staying alive after finishing partial fetches, which falsly manifests here as pending work. --- linden/indra/newview/llappviewer.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 38985d30c..8aea22111 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -1085,9 +1085,7 @@ bool LLAppViewer::mainLoop() } - const F64 min_frame_time = 0.0; //(.0333 - .0010); // max video frame rate = 30 fps - const F64 min_idle_time = 0.0; //(.0010); // min idle time = 1 ms - const F64 max_idle_time = run_multiple_threads ? min_idle_time : llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second + const F64 max_idle_time = run_multiple_threads ? 0.0 : llmin(.005*10.0*gFrameIntervalSeconds, 0.005); // 50ms/second, no more than 5ms/frame idleTimer.reset(); while(1) { @@ -1103,11 +1101,8 @@ bool LLAppViewer::mainLoop() ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up } - F64 frame_time = frameTimer.getElapsedTimeF64(); F64 idle_time = idleTimer.getElapsedTimeF64(); - if (frame_time >= min_frame_time && - idle_time >= min_idle_time && - (!work_pending || idle_time >= max_idle_time)) + if (!work_pending || idle_time >= max_idle_time) { break; } From 7ada43ada084f347648afa7bd5bec362ee04db54 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 20:29:33 -0700 Subject: [PATCH 186/239] Fixed fontconfig library not being set for Linux-only --- linden/indra/cmake/ViewerMiscLibs.cmake | 8 +++++--- linden/indra/llwindow/CMakeLists.txt | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/linden/indra/cmake/ViewerMiscLibs.cmake b/linden/indra/cmake/ViewerMiscLibs.cmake index 35f4e3aaf..38d044473 100644 --- a/linden/indra/cmake/ViewerMiscLibs.cmake +++ b/linden/indra/cmake/ViewerMiscLibs.cmake @@ -4,10 +4,12 @@ include(Prebuilt) if (NOT STANDALONE) use_prebuilt_binary(libuuid) use_prebuilt_binary(vivox) - if(LINUX AND ${ARCH} STREQUAL "x86_64") + if(LINUX) + if (${ARCH} STREQUAL "x86_64") use_prebuilt_binary(32bitcompatibilitylibs) - endif(LINUX AND ${ARCH} STREQUAL "x86_64") - use_prebuilt_binary(fontconfig) + endif (${ARCH} STREQUAL "x86_64") + use_prebuilt_binary(fontconfig) + endif(LINUX) else (NOT STANDALONE) # Download there even when using standalone. set(STANDALONE OFF) diff --git a/linden/indra/llwindow/CMakeLists.txt b/linden/indra/llwindow/CMakeLists.txt index ea81abf19..98da751d3 100644 --- a/linden/indra/llwindow/CMakeLists.txt +++ b/linden/indra/llwindow/CMakeLists.txt @@ -56,11 +56,18 @@ set(viewer_HEADER_FILES # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level -set(llwindow_LINK_LIBRARIES - ${UI_LIBRARIES} # for GTK - ${SDL_LIBRARY} - fontconfig # For FCInit and other FC* functions. - ) +if (LINUX) + set(llwindow_LINK_LIBRARIES + ${UI_LIBRARIES} # for GTK + ${SDL_LIBRARY} + fontconfig # For FCInit and other FC* functions. + ) +else (LINUX) + set(llwindow_LINK_LIBRARIES + ${UI_LIBRARIES} # for GTK + ${SDL_LIBRARY} + ) +endif (LINUX) if (DARWIN) list(APPEND llwindow_SOURCE_FILES From c5ae48b07410a977eb8799201225c5e58c4d8864 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 20:43:06 -0700 Subject: [PATCH 187/239] Applied 8th batch of German translations from Eryn --- .../default/xui/de/floater_command_line.xml | 42 +++ .../skins/default/xui/de/floater_telehub.xml | 6 +- .../xui/de/floater_teleport_history.xml | 35 +++ .../default/xui/de/floater_texture_ctrl.xml | 28 +- .../skins/default/xui/de/floater_tools.xml | 288 +++++++++++------- .../default/xui/de/floater_top_objects.xml | 2 +- .../skins/default/xui/de/floater_tos.xml | 19 +- .../default/xui/de/floater_voice_license.xml | 18 ++ .../skins/default/xui/de/floater_water.xml | 12 +- .../xui/de/floater_wearable_save_as.xml | 2 +- .../xui/de/floater_windlight_options.xml | 13 +- .../default/xui/de/floater_world_map.xml | 26 +- 12 files changed, 348 insertions(+), 143 deletions(-) create mode 100644 linden/indra/newview/skins/default/xui/de/floater_command_line.xml create mode 100644 linden/indra/newview/skins/default/xui/de/floater_teleport_history.xml create mode 100644 linden/indra/newview/skins/default/xui/de/floater_voice_license.xml diff --git a/linden/indra/newview/skins/default/xui/de/floater_command_line.xml b/linden/indra/newview/skins/default/xui/de/floater_command_line.xml new file mode 100644 index 000000000..e3b2ec31a --- /dev/null +++ b/linden/indra/newview/skins/default/xui/de/floater_command_line.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="busy" title="Chatleisten-Befehle"> + <text name="loltxt2"> Innerhalb des Sims teleportieren (Nutzung: cmd x y z)</text> + <line_editor tool_tip="" name="CmdLineChatbarPos"/> + <text name="loltxt3"> Zum Boden teleportieren (Nutzung: cmd)</text> + <line_editor tool_tip="" name="CmdLineChatbarGround"/> + <text name="loltxt4"> In Höhe teleportieren (Nutzung: cmd z)</text> + <line_editor tool_tip="" name="CmdLineChatbarHeight"/> + <text name="loltxt5"> Nach Hause teleportieren (Nutzung: cmd)</text> + <line_editor tool_tip="" name="CmdLineChatbarTeleportHome"/> + <text name="loltxt6"> Eine Plattform schaffen (Nutzung: cmd 0 - 30)</text> + <line_editor tool_tip="" name="CmdLineChatbarRezPlatform"/> + <slider name="CmdLineChatbarPlatformSize" label="Breite" tool_tip="Wie groß soll die Plattform sein?"/> + <text name="loltxt7"> Zu Sim x teleportieren (Nutzung: cmd simname)</text> + <line_editor tool_tip="" name="CmdLineChatbarMapTo"/> + <check_box label="Gleiche Position nutzen" name="toggle"/> + <text name="loltxt8"> math. Ausdruck rechnen (Nutzung: cmd SIN(2+2))</text> + <line_editor tool_tip="" name="CmdLineChatbarCalc"/> + <text name="add_autokorrect">Wort zu Autokorrekt zufügen(Nutzung: cmd list|bad|good)</text> + <line_editor tool_tip="" name="CmdLineChatbarAutocorrect"/> + <text name="loltxt9"> Sichtweite ändern (Nutzung: cmd meters)</text> + <line_editor tool_tip="" name="CmdLineChatbarDrawDistance"/> + <text name="loltxt10"> Zur Kameraposition teleportieren (Nutzung: cmd)</text> + <line_editor tool_tip="" name="CmdLineChatbarTeleportToCam"/> + <text name="loltxt11"> Avatarname von Schlüssel beziehen (Nutzung: cmd key)</text> + <line_editor tool_tip="" name="CmdLineChatbarKeyToName"/> + <text name="loltxt12"> Avatar Teleport anbieten (Nutzung: cmd key)</text> + <line_editor tool_tip="" name="CmdLineChatbarOfferTp"/> + <text name="loltxt13"> Zu Avatar teleportieren (Nutzung: cmd name)</text> + <line_editor tool_tip="Die syntax dieses Befehls erlaubt partielle Namen (ohne Groß-/Kleinschreibung). Bessere Resultate bei Nutzung mit offenem Radar." + name="CmdLineChatbarTP2"/> + <text name="loltxt14"> AO an/aus (Nutzung: cmd on/off)</text> + <line_editor tool_tip="" name="CmdLineChatbarAO"/> + <text name="loltxt15"> Chat-Historie löschen (Nutzung: cmd)</text> + <line_editor tool_tip="Löscht die Chat-Historie, um Lag-Effekte von Chat-Spammern zu verhindern." name="CmdLineChatbarClearChat"/> + <text name="loltxt15"> Medien-URL bestimmen (Nutzung: cmd url type)</text> + <line_editor tool_tip="Bestimmt und spielt Ihren Medienstrom auf die eingegebene URL" name="CmdLineChatbarMedia"/> + <text name="loltxt15"> Musik-URL bestimmen (Nutzung: cmd url)</text> + <line_editor tool_tip="Bestimmt und spielt Ihren Musikstrom auf die eingegebene URL" name="CmdLineChatbarMusic"/> + <button label="?" name="Help_CmdLine" +tool_tip="Hier für Hilfe betreffend der Einstellungen dieser Seite klicken."/> +</floater> \ No newline at end of file diff --git a/linden/indra/newview/skins/default/xui/de/floater_telehub.xml b/linden/indra/newview/skins/default/xui/de/floater_telehub.xml index 264411c16..fef4fcd95 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_telehub.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_telehub.xml @@ -23,10 +23,10 @@ <text name="spawn_point_help"> Wählen Sie ein Objekt und klicken zur Positionsangabe auf „Hinzufügen“. Anschließend -können sie das Objekt verschieben oder löschen. +können Sie das Objekt verschieben oder löschen. Positionsangaben sind relativ zum Telehub-Mittelpunkt. -Wählen Sie ein Objekt aus, um seine Position in -der Welt anzuzeigen. +Wählen Sie ein Objekt der Liste aus, um seine +Position in der Welt anzuzeigen. </text> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_teleport_history.xml b/linden/indra/newview/skins/default/xui/de/floater_teleport_history.xml new file mode 100644 index 000000000..7980f1edb --- /dev/null +++ b/linden/indra/newview/skins/default/xui/de/floater_teleport_history.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="teleporthistory" title="Teleportier-Historie"> + <tab_container label="TP-Listenregister" name="tplisttabs"> + <panel label="Teleportiert nach" name="TP-in"> + <scroll_list name="places_list_in"> + <column label="Region" name="region" /> + <column label="Position" name="position" /> + <column label="Besucht" name="visited" /> + <!--Hidden fields, used as storage for prebuilt strings, please keep at width 0--> + <column label="SLURL" name="slurl" /> + <column label="Sim String" name="simstring" /> + </scroll_list> + </panel> + <panel label="Teleportiert von" name="TP-out"> + <scroll_list name="places_list_out"> + <column label="Region" name="region" /> + <column label="Position" name="position" /> + <column label="Besucht" name="visited" /> + <!--Hidden fields, used as storage for prebuilt strings, please keep at width 0--> + <column label="SLURL" name="slurl" /> + <column label="Sim String" name="simstring" /> + </scroll_list> + </panel> + </tab_container> + <button label="Teleportieren" label_selected="Teleportieren" + name="teleport" tool_tip="Teleportiert zum ausgewählten Ort" /> + <button label="Auf Karte zeigen" label_selected="Auf Karte zeigen" + name="show_on_map" + tool_tip="Zentriert die Karte auf diesen Ort" /> + <button label="Historie löschen" + name="clear_history" + tool_tip="Gesicherte Teleportier-Historie löschen" /> + <button label="SLURL auf Zwischenablage kopieren" name="copy_slurl" + tool_tip="Kopiert den aktuellen Ort als SLURL, um ihn im Internet zu nutzen." /> +</floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml b/linden/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml index 4aa7db4d3..efa21fd26 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml @@ -9,16 +9,38 @@ <text type="string" length="1" name="unknown"> Maße: [DIMENSIONS] </text> + <button label="Standard" label_selected="Standard" name="Default" /> <button label="Keine" label_selected="Keine" name="None" /> <button label="Leer" label_selected="Leer" name="Blank" /> + <button label="Unsichtbar" label_selected="Unsichtbar" name="Invisible" /> <check_box label="Ordner anzeigen" name="show_folders_check" /> - <search_editor label="Suchanfrage hier eintippen" name="inventory search editor" /> <check_box label="Sofort übernehmen" name="apply_immediate_check" /> <button label="" label_selected="" name="Pipette" /> <button label="Abbrechen" label_selected="Abbrechen" name="Cancel" /> <button label="Auswählen" label_selected="Auswählen" name="Select" /> - <text name="pick title"> + <string name="pick title"> Auswählen: - </text> + </string> + + <tab_container name="actions_tab_container"> + <panel label="Inventar" name="server_tab"> + <search_editor label="Suchanfrage hier eintippen" name="inventory search editor" /> + <inventory_panel name="inventory panel" /> + </panel> + <panel label="Computer" name="local_tab"> + <!-- tag: vaa emerald local_asset_browser [begin] --> + <text name="select_local"> + Textur auf Ihrem Computer für Vorschau in-welt auswählen + </text> + <button label="Hinzufügen" name="Add" width="70" /> + <button label="Entfernen" name="Remove" /> + <button label="Eigenschaften..." name="Browser" /> + <scroll_list name="local_name_list" > + <column name="unit_name" label="Name" /> + <column name="unit_id_HIDDEN" label="ID" /> + </scroll_list> + <!-- tag: vaa emerald local_asset_browser [end] --> + </panel> + </tab_container> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_tools.xml b/linden/indra/newview/skins/default/xui/de/floater_tools.xml index 165d0a71c..aa8170b5c 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_tools.xml @@ -1,21 +1,38 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="toolbox floater" title="" short_title="Bauen"> +<floater name="toolbox floater" title="" short_title="Bauen" width="282"> + +<!-- Main floater tabs --> + <button label="" label_selected="" name="button focus" tool_tip="Fokus"/> <button label="" label_selected="" name="button move" tool_tip="Verschieben"/> <button label="" label_selected="" name="button edit" tool_tip="Bearbeiten"/> <button label="" label_selected="" name="button create" tool_tip="Erstellen"/> <button label="" label_selected="" name="button land" tool_tip="Land"/> - <check_box label="Zoom" name="radio zoom"/> + +<!-- Focus panel --> + + <check_box label="Zoom:" name="radio zoom"/> <check_box label="Orbit (Strg)" name="radio orbit"/> <check_box label="Schwenken (Strg-Umschalt)" name="radio pan"/> + +<!-- Move panel --> + <check_box label="Verschieben" name="radio move"/> <check_box label="Heben (Strg)" name="radio lift"/> <check_box label="Rotieren (Strg-Umschalt)" name="radio spin"/> + +<!-- Edit panel --> + <check_box label="Position" name="radio position"/> <check_box label="Drehen (Strg)" name="radio rotate"/> <check_box label="Dehnen (Strg-Umschalt)" name="radio stretch"/> <check_box label="Textur auswählen" name="radio select face"/> <check_box label="Verknüpfte Teile bearbeiten" name="checkbox edit linked parts"/> + <button label="Verknüpfen" label_selected="Verknüpfen" + left="10" name="link_btn" width="68" /> + <button label="Trennen" label_selected="Trennen" + name="unlink_btn" width="68" /> + <text name="text ruler mode"> Lineal: </text> @@ -33,10 +50,16 @@ <check_box label="Beide Seiten dehnen" name="checkbox uniform"/> <check_box label="Texturen dehnen" name="checkbox stretch textures"/> <check_box label="Raster verwenden" name="checkbox snap to grid"/> - <button label="Optionen..." label_selected="Optionen..." name="Options..."/> + <button label="Bauoptionen..." label_selected="Bauoptionen..." name="Options..."/> + +<!-- Help text --> + <text name="text status"> Zum Verschieben ziehen, zum Kopieren Umschalttaste-Ziehen </text> + +<!-- Create panel --> + <button label="" label_selected="" name="ToolCube" tool_tip="Würfel"/> <button label="" label_selected="" name="ToolPrism" tool_tip="Prisma"/> <button label="" label_selected="" name="ToolPyramid" tool_tip="Pyramide"/> @@ -52,10 +75,15 @@ <button label="" label_selected="" name="ToolRing" tool_tip="Ring"/> <button label="" label_selected="" name="ToolTree" tool_tip="Baum"/> <button label="" label_selected="" name="ToolGrass" tool_tip="Gras"/> + <text name="tree_grass_label" /> + <combo_box name="trees_grass" /> <check_box label="Auswahl behalten" name="checkbox sticky"/> <check_box label="Auswahl kopieren" name="checkbox copy selection"/> <check_box label="Zentrieren" name="checkbox copy centers"/> <check_box label="Drehen" name="checkbox copy rotates"/> + +<!-- Land panel --> + <check_box label="Land auswählen" name="radio select land"/> <check_box label="Einebnen" name="radio flatten"/> <check_box label="Anheben" name="radio raise"/> @@ -68,10 +96,10 @@ Planierraupe: </text> <text name="Dozer Size:"> - Größe + Größe: </text> <text name="Strength:"> - Stärke + Stärke: </text> <text name="obj_count"> Ausgewählte Objekte: [COUNT] @@ -79,7 +107,13 @@ <text name="prim_count"> Primitive: [COUNT] </text> - <tab_container name="Object Info Tabs" tab_max_width="150" tab_min_width="30"> + <text name="link_num"> + Linknummer: [NUMBER] + </text> + +<!-- Sub-tabs --> + + <tab_container name="Object Info Tabs" tab_max_width="150" tab_min_width="30" width="280"> <panel label="Allgemein" name="General"> <text name="Name:"> Name: @@ -91,16 +125,20 @@ Ersteller: </text> <text name="Creator Name"> - Thrax Linden + Imprudent Linden </text> - <button label="Profil..." label_selected="Profil..." name="button creator profile"/> <text name="Owner:"> Eigentümer: </text> <text name="Owner Name"> - Thrax Linden - </text> - <button label="Profil..." label_selected="Profil..." name="button owner profile"/> + Imprudent Linden + </text> + <text name="Last Owner:"> + Last Owner: + </text> + <text name="Last Owner Name"> + Imprudent Linden + </text> <text name="Group:"> Gruppe: </text> @@ -116,33 +154,35 @@ </text> <check_box label="Mit Gruppe teilen" left="6" name="checkbox share with group" tool_tip="Allen Mitgliedern der zugeordneten Gruppe die Erlaubnis erteilen, Ihre Berechtigungen für dieses Objekt zu teilen und zu verwenden. Sie müssen Übereignen, um Rollenbeschränkungen zu aktivieren."/> <string name="text deed continued"> - Übertragung... + Übereignung... </string> <string name="text deed"> - Übertragung + Übereignung </string> - <button label="Übertragung..." label_selected="Übertragung..." name="button deed" tool_tip="In der Gruppe gemeinsam verwendete Objekte können von einem Gruppenfunktionär übertragen werden."/> - <text name="Anyone can:"> - Jeder: - </text> - <check_box label="Bewegen" name="checkbox allow everyone move"/> - <check_box label="Kopieren" name="checkbox allow everyone copy"/> + <button label="Übereignung..." label_selected="Übereignung..." name="button deed" tool_tip="In der Gruppe gemeinsam verwendete Objekte können von einem Gruppenoffizier übereignet werden."/> <check_box label="In Suche anzeigen" left="6" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/> - <check_box label="Zu verkaufen" left="6" name="checkbox for sale"/> + <check_box label="Zu verkaufen:" left="6" name="checkbox for sale"/> <text name="Cost"> - Preis:L$ + Preis: [CURRENCY] </text> <radio_group name="sale type"> <radio_item name="Original"> Original </radio_item> <radio_item name="Copy"> - Kopieren + Kopie </radio_item> <radio_item name="Contents"> Inhalt </radio_item> </radio_group> + <button label="Schlüssel kopieren" label_selected="Schlüsselkopie" name="button copy key" width="78" + tool_tip="Den/die Schlüssel eines Objekts in die Zwischenablage kopieren" /> + <text name="Anyone can:"> + Jeder: + </text> + <check_box label="Bewegen" name="checkbox allow everyone move"/> + <check_box label="Kopieren" name="checkbox allow everyone copy"/> <text name="Next owner can:"> Nächster Eigentümer kann: </text> @@ -152,6 +192,8 @@ <text name="label click action"> Bei Linksklicken: </text> + <!-- Do not reorder these items, the index numbers are + used internally. JC --> <combo_box name="clickaction" width="178"> <combo_item name="Touch/grab(default)"> Berühren/Greifen (Standard) @@ -209,13 +251,13 @@ Gesamtes Objekt muss gewählt werden, um Berechtigungen festzulegen. </string> <string name="Cost Default"> - Preis:L$ + Preis: [CURRENCY] </string> <string name="Cost Total"> - Summe:L$ + Summe: [CURRENCY] </string> <string name="Cost Per Unit"> - Stückpreis:L$ + Stückpreis: [CURRENCY] </string> <string name="Cost Mixed"> Mischpreis @@ -224,31 +266,43 @@ Mischverkauf </string> </panel> - <panel label="Objekt" name="Object"> + +<!-- Object sub-tab --> + + <panel label="Objekt" name="Object" width="272"> <text name="select_single"> - Wählen Sie nur ein Primitivum aus, um Parameter zu bearbeiten. + Nur einzelne Primitiva bearbeiten. </text> <text name="edit_object"> Objektparameter bearbeiten: </text> - <check_box label="Gesperrt" name="checkbox locked" tool_tip="Verhindert, dass Objekt verschoben oder gelöscht wird. Oft beim Bauen nützlich, um unbeabsichtigte Bearbeitungen zu vermeiden."/> - <check_box label="Physisch" name="Physical Checkbox Ctrl" tool_tip="Gestattet, das Objekt geschoben und von Schwerkraft beeinflusst wird"/> - <check_box label="Temporär" name="Temporary Checkbox Ctrl" tool_tip="Verursacht, dass Objekt 1 Minute nach Erstellung gelöscht wird."/> + <check_box label="Gesperrt" name="checkbox locked" tool_tip="Verhindert, dass das Objekt verschoben oder gelöscht wird. Oft beim Bauen nützlich, um unbeabsichtigte Bearbeitungen zu vermeiden."/> + <check_box label="Physisch" name="Physical Checkbox Ctrl" tool_tip="Gestattet, dass das Objekt geschoben und von Schwerkraft beeinflusst wird"/> + <check_box label="Temporär" name="Temporary Checkbox Ctrl" tool_tip="Verursacht, dass das Objekt 1 Minute nach Erstellung gelöscht wird."/> <check_box label="Phantom" name="Phantom Checkbox Ctrl" tool_tip="Verursacht, dass Objekt nicht mit anderen Objekten oder Avataren kollidiert"/> + <text name="label position"> - Position (Meter) + Position (Meter): </text> <spinner label="X" name="Pos X"/> <spinner label="Y" name="Pos Y"/> <spinner label="Z" name="Pos Z"/> + <button label="C" name="copypos" tool_tip="Position kopieren" /> + <button label="P" name="pastepos" tool_tip="Position einfügen" /> + <button label="p" name="pasteposclip" tool_tip="Position von Zwischenablage einfügen" /> + <text name="label size"> - Größe (Meter) + Größe (Meter): </text> <spinner label="X" name="Scale X"/> <spinner label="Y" name="Scale Y"/> <spinner label="Z" name="Scale Z"/> + <button label="C" name="copysize" tool_tip="Größe kopieren" /> + <button label="P" name="pastesize" tool_tip="Größe einfügen" /> + <button label="p" name="pastesizeclip" tool_tip="Größe von Zwischenablage einfügen" /> + <text name="label rotation"> - Rotation (Grad) + Rotation (Grad): </text> <spinner label="X" name="Rot X"/> <spinner label="Y" name="Rot Y"/> @@ -256,6 +310,14 @@ <text name="label material"> Material </text> + <button label="C" name="copyrot" +tool_tip="Rotation kopieren" /> + <button label="P" name="pasterot" tool_tip="Rotation einfügen" /> + <button label="p" name="pasterotclip" tool_tip="Rotation von Zwischenablage einfügen" /> + + <text name="label material"> + Material: + </text> <combo_box name="material"> <combo_item name="Stone"> Stein @@ -279,10 +341,11 @@ Gummi </combo_item> </combo_box> - <text left="115" name="label basetype"> + <button label="Bau-Mathe" label_selected="Bau-Mathe" tool_tip="mathem. Konstanten des Objekts" name="build_math_constants" /> + <text left="130" name="label basetype"> Bausteintyp </text> - <combo_box left="115" name="comboBaseType"> + <combo_box left="130" name="comboBaseType"> <combo_item name="Box"> Quader </combo_item> @@ -308,23 +371,23 @@ Geformt </combo_item> </combo_box> - <text left="115" name="text cut" width="146"> - Pfadschnitt Beginn und Ende + <text left="130" name="text cut" width="146"> + Pfadschnitt Beginn und Ende: </text> - <spinner label="B" left="115" name="cut begin"/> - <spinner label="E" left="115" name="cut end"/> - <text left="115" name="text hollow"> - Hohl + <spinner label="B" left="130" name="cut begin"/> + <spinner label="E" left="130" name="cut end"/> + <text left="130" name="text hollow"> + Hohl: </text> - <text left="115" name="text skew"> - Versatz + <text left="130" name="text skew"> + Versatz: </text> - <spinner left="115" name="Scale 1"/> - <spinner left="115" name="Skew"/> - <text left="115" name="Hollow Shape"> - Hohlform + <spinner left="130" name="Scale 1"/> + <spinner left="130" name="Skew"/> + <text left="130" name="Hollow Shape"> + Hohlform: </text> - <combo_box left="115" name="hole"> + <combo_box left="130" name="hole"> <combo_item name="Default"> Standard </combo_item> @@ -338,57 +401,59 @@ Dreieck </combo_item> </combo_box> - <text left="115" name="text twist"> - Torsion + <text left="130" name="text twist"> + Torsion Beginn und Ende: </text> - <spinner label="B" left="115" name="Twist Begin"/> - <spinner label="E" left="115" name="Twist End"/> - <text left="115" name="scale_taper"> - Verjüngung + <spinner label="B" left="130" name="Twist Begin"/> + <spinner label="E" left="130" name="Twist End"/> + <text left="130" name="scale_taper"> + Verjüngung: </text> - <text left="115" name="scale_hole"> - Lochgröße + <text left="130" name="scale_hole"> + Lochgröße: </text> - <spinner label="X" left="115" name="Taper Scale X"/> - <spinner label="Y" left="115" name="Taper Scale Y"/> - <text left="115" name="text topshear"> - Verscherung + <spinner label="X" left="130" name="Taper Scale X"/> + <spinner label="Y" left="130" name="Taper Scale Y"/> + <text left="130" name="text topshear"> + Verscherung: </text> - <spinner label="X" left="115" name="Shear X"/> - <spinner label="Y" left="115" name="Shear Y"/> - <text left="115" name="advanced_cut" width="153"> - Profilschnitt-Beginn und Ende + <spinner label="X" left="130" name="Shear X"/> + <spinner label="Y" left="130" name="Shear Y"/> + <text left="130" name="advanced_cut" width="153"> + Profilschnitt-Beginn und Ende: </text> - <text left="115" name="advanced_dimple"> - Vertiefung-Beginn und Ende + <text left="130" name="advanced_dimple"> + Vertiefung-Beginn und Ende: </text> - <text name="advanced_slice"> - Anfang/Ende abschneiden + <text left="130" name="advanced_slice"> + Anfang/Ende abschneiden: </text> - <spinner label="B" left="115" name="Path Limit Begin"/> + <spinner label="B" left="130" name="Path Limit Begin"/> <spinner label="E" name="Path Limit End"/> - <text left="115" name="text taper2"> - Verjüngung + <text left="130" name="text taper2"> + Verjüngung: </text> - <spinner label="X" left="115" name="Taper X"/> + <spinner label="X" left="130" name="Taper X"/> <spinner label="Y" name="Taper Y"/> - <text left="115" name="text radius delta"> - Radius + <text left="130" name="text radius delta"> + Radius: </text> <text name="text revolutions" width="74"> - Umdrehungen + Umdrehungen: </text> - <spinner left="115" name="Radius Offset"/> + <spinner left="130" name="Radius Offset"/> + <spinner name="Revolutions" /> + <texture_picker label="Textur für gestaltetes -Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> +Primitiv:" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> <check_box bottom_delta="-34" label="Spiegeln" name="sculpt mirror control" tool_tip="Geformtes Primitiv entlang der X-Achse spiegeln."/> <check_box label="Wenden" name="sculpt invert control" tool_tip="Dreht die Normalen des geformten Primitivs von innen nach außen."/> <text name="label sculpt type"> - Naht + Naht: </text> <combo_box name="sculpt type control"> <combo_item name="None"> - (keiner) + (keine) </combo_item> <combo_item name="Sphere"> Kugel @@ -404,31 +469,38 @@ Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild </combo_item> </combo_box> </panel> - <panel label="Eigenschaften" name="Features"> + +<!-- Features sub-tab --> + + <panel label="Eigenschaften" name="Features" height="25" > <text name="select_single"> - Wählen Sie nur einen einzelnen Baustein aus, um Eigenschaften zu bearbeiten. + Wählen Sie nur einen einzelnen Baustein aus, +um Eigenschaften zu bearbeiten. </text> - <text name="edit_object"> + <text name="edit_object" bottom_delta="-10" > Objekteigenschaften bearbeiten: </text> <check_box label="Flexibler Weg" name="Flexible1D Checkbox Ctrl" tool_tip="Gestattet, dass Objekt um die Z-Achse gebogen wird. (nur Client-Seite)"/> - <spinner label="Weichheit" name="FlexNumSections"/> - <spinner label="Schwerkraft" name="FlexGravity"/> - <spinner label="Ziehen" name="FlexFriction"/> - <spinner label="Wind" name="FlexWind"/> - <spinner label="Spannung" name="FlexTension"/> - <spinner label="Erzwingen X" name="FlexForceX"/> - <spinner label="Erzwingen Y" name="FlexForceY"/> - <spinner label="Erzwingen Z" name="FlexForceZ"/> - <check_box label="Licht" name="Light Checkbox Ctrl" tool_tip="Verursacht, dass Objekt Licht emittiert"/> + <spinner label="Weichheit:" name="FlexNumSections"/> + <spinner label="Schwerkraft:" name="FlexGravity"/> + <spinner label="Ziehen:" name="FlexFriction"/> + <spinner label="Wind:" name="FlexWind"/> + <spinner label="Spannung:" name="FlexTension"/> + <spinner label="Erzwingen X:" name="FlexForceX"/> + <spinner label="Erzwingen Y:" name="FlexForceY"/> + <spinner label="Erzwingen Z:" name="FlexForceZ"/> + <check_box label="Licht" name="Light Checkbox Ctrl" tool_tip="Verursacht, dass das Objekt Licht ausstrahlt"/> <text name="label color"> - Farbe + Farbe: </text> <color_swatch label="" name="colorswatch" tool_tip="Klicken, um Farbauswahl zu öffnen"/> - <spinner label="Intensität" name="Light Intensity"/> - <spinner label="Radius" name="Light Radius"/> - <spinner label="Abnehmend" name="Light Falloff"/> + <spinner label="Intensität:" name="Light Intensity"/> + <spinner label="Radius:" name="Light Radius"/> + <spinner label="Abnehmend:" name="Light Falloff"/> </panel> + +<!-- Texture sub-tab --> + <panel label="Textur" name="Texture"> <texture_picker label="Textur" name="texture control" tool_tip="Klicken, um ein Bild zu wählen"/> <color_swatch label="Farbe" name="colorswatch" tool_tip="Klicken, um Farbauswahl zu öffnen"/> @@ -520,12 +592,14 @@ Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild Stuck </combo_item> <combo_item name="suction"> - Saugen + Sog </combo_item> <combo_item name="weave"> - gewoben + Gewebe </combo_item> </combo_box> + <check_box label="Ebene Texturen ausrichten" + name="checkbox planar align" tool_tip="Richtet Texturen auf allen ausgewählten Flächen nach der letzten Fläche aus. Benötigt ebene Texturzuordnung." /> <text name="tex scale"> Wiederholungen </text> @@ -556,32 +630,40 @@ Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild (zuerst laden) </text> <button label="Ausrichten" label_selected="Ausrichten" name="button align"/> + <button label="Textur Mathe" label_selected="Textur Mathe" tool_tip="Texture math constants" name="texture_math_constants" /> </panel> <panel label="Inhalt" name="Contents"> <button label="Neues Skript" label_selected="Neues Skript..." name="button new script"/> <button label="Berechtigungen..." name="button permissions" width="118"/> + <panel name="ContentsInventory" /> </panel> </tab_container> + +<!-- Land Info sub-tab --> + <panel name="land info panel"> + <!-- Parcel Information --> <text name="label_parcel_info"> - Parzelleninformation + Parzelleninformation: </text> <text name="label_area_price"> - Preis: L$ [PRICE] für [AREA] m2. + Preis: [CURRENCY][PRICE] für [AREA] m2. </text> <text name="label_area"> Fläche: [AREA] m2 </text> - <button label="Info zu Land..." label_selected="Info zu Land..." name="button about land" width="110"/> + <button label="Landinfo..." label_selected="Landinfo..." name="button about land" width="110" /> <check_box label="Eigentümer anzeigen" name="checkbox show owners" tool_tip="Parzellen nach Eigentümer farbig kennzeichnen"/> <button label="?" label_selected="?" name="button show owners help" left_delta="130"/> + <!-- Modify Parcel --> <text name="label_parcel_modify"> - Parzelle ändern + Parzelle ändern: </text> <button label="Unterteilen..." label_selected="Unterteilen..." name="button subdivide land" width="110"/> <button label="Zusammenlegen" label_selected="Zusammenlegen" name="button join land" width="110"/> + <!-- Land Transactions --> <text name="label_parcel_trans"> - Land-Transaktionen + Land-Transaktionen: </text> <button label="Land kaufen..." label_selected="Land kaufen..." name="button buy land" width="110"/> <button label="Land aufgeben..." label_selected="Land aufgeben..." name="button abandon land" width="110"/> @@ -605,7 +687,7 @@ Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild Ziehen, um Objekte zu verschieben, Strg zum Heben, Strg-Umschalt zum Drehen </string> <string name="status_place"> - Inworld klicken, um zu bauen. + In-Welt klicken, um zu bauen </string> <string name="status_selectland"> Klicken und ziehen, um Land auszuwählen diff --git a/linden/indra/newview/skins/default/xui/de/floater_top_objects.xml b/linden/indra/newview/skins/default/xui/de/floater_top_objects.xml index f9e7becee..8a196b1fd 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_top_objects.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_top_objects.xml @@ -41,7 +41,7 @@ Zeit </string> <string name="scripts_mono_time_label"> - Mono-Uhrzeit: + Mono-Uhrzeit </string> <string name="top_colliders_title"> Top-Kollisionsobjekte diff --git a/linden/indra/newview/skins/default/xui/de/floater_tos.xml b/linden/indra/newview/skins/default/xui/de/floater_tos.xml index 42f48fad4..b3fa2a4ed 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_tos.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_tos.xml @@ -2,18 +2,8 @@ <floater name="modal container" title=" "> <button label="Weiter" label_selected="Weiter" name="Continue" /> <button label="Abbrechen" label_selected="Abbrechen" name="Cancel" /> - <radio_group name="tos_agreement"> - <radio_item name="radio_disagree"> - Ich stimme den Nutzungsbedingungen nicht zu - </radio_item> - <radio_item name="radio_agree"> - Ich stimme den Nutzungsbedingungen zu - </radio_item> - </radio_group> - <text name="tos_title"> - Nutzungsvereinbarung - </text> - <check_box label="Ich stimme den Nutzungsbedingungen zu" name="agree_chk" /> + <check_box label="Ich stimme den Nutzungsbedingungen zu" + name="agree_chk" /> <text name="tos_heading"> Lesen Sie die folgenden Nutzungsbedingungen sorgfältig durch. Sie müssen dieser Vereinbarung zustimmen, um Second Life benutzen zu können. @@ -21,7 +11,8 @@ zustimmen, um Second Life benutzen zu können. <text_editor name="tos_text"> TOS_TEXT </text_editor> - <text name="real_url"> + + <string name="real_url"> http://secondlife.com/app/tos/ - </text> + </string> </floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_voice_license.xml b/linden/indra/newview/skins/default/xui/de/floater_voice_license.xml new file mode 100644 index 000000000..a79224b5b --- /dev/null +++ b/linden/indra/newview/skins/default/xui/de/floater_voice_license.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater name="modal container" title=""> + <button label="Weiter" label_selected="Weiter" name="Continue" /> + <button label="Abbrechen" label_selected="Abbrechen" name="Cancel" /> + <check_box label="Ich stimme den Bedingungen der Vivox-Richtlinie zur akzeptieren Nutzung zu" +name="agree_chk" /> + <text name="license_heading"> +Bitte lesen Sie das folgende Dokument sorgfältig durch. +Um Vivox Sprach-Chat nutzen zu können, müssen Sie den Bedingungen zustimmen. + </text> + <text_editor name="license_text"> + LICENSE_TEXT + </text_editor> + + <string name="real_url"> + http://www.vivox.com/vivox_aup.html + </string> +</floater> diff --git a/linden/indra/newview/skins/default/xui/de/floater_water.xml b/linden/indra/newview/skins/default/xui/de/floater_water.xml index 95b469434..b768a1285 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_water.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_water.xml @@ -4,7 +4,15 @@ Voreinstellungen: </text> <button label="Neu" label_selected="Neu" name="WaterNewPreset" /> - <button label="Speichern" label_selected="Speichern" name="WaterSavePreset" /> + <flyout_button label="Auf Platte speichern" + name="WaterSavePreset"> + <flyout_button_item name="save_inventory_item"> + In Inventar speichern + </flyout_button_item> + <flyout_button_item name="save_disk_item"> + Auf Platte speichern + </flyout_button_item> + </flyout_button> <button label="Löschen" label_selected="Löschen" name="WaterDeletePreset" /> <tab_container name="Water Tabs"> <panel label="Einstellungen" name="Settings"> @@ -12,7 +20,7 @@ Wassertrübungsfarbe </text> <button label=" ?" name="WaterFogColorHelp" left="175" /> - <color_swatch name="WaterFogColor" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen" /> + <color_swatch name="WaterFogColor" tool_tip="Hier klicken, um die Farbauswahl zu öffnen" /> <text name="WaterFogDensText"> Wassertrübungsdichte </text> diff --git a/linden/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml b/linden/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml index 89e351e49..5ca57e428 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="modal container" title=" "> +<floater name="modal container" title=""> <button label="Speichern" label_selected="Speichern" name="Save" /> <button label="Abbrechen" label_selected="Abbrechen" name="Cancel" /> <text type="string" length="1" name="Save item as:"> diff --git a/linden/indra/newview/skins/default/xui/de/floater_windlight_options.xml b/linden/indra/newview/skins/default/xui/de/floater_windlight_options.xml index 8df412dab..09ffcd291 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_windlight_options.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_windlight_options.xml @@ -4,10 +4,15 @@ Voreinstellungen: </text> <button label="Neu" label_selected="Neu" name="WLNewPreset" /> - <button label="Speichern" label_selected="Speichern" name="WLSavePreset" /> + <flyout_button label="Auf Platte speichern" name="WLSavePreset"> + <flyout_button_item name="save_inventory_item"> + In Inventar speichern + </flyout_button_item> + <flyout_button_item name="save_disk_item"> + Auf Platte speichern + </flyout_button_item> + </flyout_button> <button label="Löschen" label_selected="Löschen" name="WLDeletePreset" /> - <button label="Tageszyklus-Editor" label_selected="Tageszyklus-Editor" - name="WLDayCycleMenuButton" /> <tab_container name="WindLight Tabs"> <panel label="Atmosphäre" name="Atmosphere"> <text name="BHText"> @@ -184,6 +189,8 @@ <button label=" ?" name="WLClassicCloudsHelp" /> </panel> </tab_container> + <button label="Tageszyklus-Editor" label_selected="Tageszyklus-Editor" + name="WLDayCycleMenuButton" /> <string name="WLDefaultSkyNames"> A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality </string> diff --git a/linden/indra/newview/skins/default/xui/de/floater_world_map.xml b/linden/indra/newview/skins/default/xui/de/floater_world_map.xml index d28b55e8a..e0d95e6f6 100644 --- a/linden/indra/newview/skins/default/xui/de/floater_world_map.xml +++ b/linden/indra/newview/skins/default/xui/de/floater_world_map.xml @@ -14,19 +14,19 @@ Auktion </text> <text font="SansSerifSmall" name="land_for_sale_label"> - Land erhaeltlich + Land zum Verkauf </text> - <button label="Nach Hause" label_selected="Nach Hause" name="Go Home" tool_tip="Nach Hause teleportieren"/> + <button label="Nach Hause" label_selected="Nach Hause" name="Go Home" tool_tip="Zu Ihrem Zuhause teleportieren"/> <check_box label="Einwohner" name="people_chk"/> <check_box label="Infohub" name="infohub_chk"/> <check_box label="Telehub" name="telehubchk"/> - <check_box label="Land zu verkaufen" name="land_for_sale_chk"/> + <check_box label="Land zum Verkauf" name="land_for_sale_chk"/> <text name="events_label"> Events: </text> <check_box label="PG" name="event_chk"/> - <check_box label="Mature" name="event_mature_chk"/> - <check_box label="Adult" name="event_adult_chk"/> + <check_box label="Reif" name="event_mature_chk"/> + <check_box label="Erwachsen" name="event_adult_chk"/> <combo_box label="Online-Freunde" name="friend combo" tool_tip="Freund, der auf Karte angezeigt werden soll"> <combo_item name="none_selected"> Online-Freunde @@ -47,15 +47,15 @@ <column label="" name="sim_name"/> </scroll_list> <text name="location_label"> - Standort: + Ort: </text> - <spinner name="spin x" tool_tip="X-Koordinate der Position auf der Karte"/> - <spinner name="spin y" tool_tip="Y-Koordinate der Position auf der Karte"/> - <spinner name="spin z" tool_tip="Z-Koordinate der Position auf der Karte"/> - <button label="Teleportieren" label_selected="Teleportieren" name="Teleport" tool_tip="Zu ausgewählter Position teleportieren"/> - <button label="Gesuchte Position" label_selected="Ziel anzeigen" name="Show Destination" tool_tip="Karte auf ausgewählte Position zentrieren"/> + <spinner name="spin x" tool_tip="X-Koordinate des Ortes auf der Karte"/> + <spinner name="spin y" tool_tip="Y-Koordinate des Ortes auf der Karte"/> + <spinner name="spin z" tool_tip="Z-Koordinate des Ortes auf der Karte"/> + <button label="Teleportieren" label_selected="Teleportieren" name="Teleport" tool_tip="Zu ausgewähltem Ort teleportieren"/> + <button label="Ziel anzeigen" label_selected="Ziel anzeigen" name="Show Destination" tool_tip="Karte auf ausgewählten Ort zentrieren"/> <button label="Löschen" label_selected="Löschen" name="Clear" tool_tip="Verfolgung abschalten"/> - <button label="Meine Position" label_selected="Wo bin ich?" name="Show My Location" tool_tip="Karte auf Position Ihres Avatars zentrieren"/> - <button font="SansSerifSmall" label="SLURL in die Zwischenablage kopieren" name="copy_slurl" tool_tip="Kopiert die aktuelle Position als SLURL zur Verwendung im Web."/> + <button label="Meine Position" label_selected="Meine Position" name="Show My Location" tool_tip="Karte auf Position Ihres Avatars zentrieren"/> + <button font="SansSerifSmall" label="SLURL in Zwischenablage kopieren" name="copy_slurl" tool_tip="Kopiert die aktuelle Position als SLURL zur Verwendung im Internet."/> <slider label="Zoom" name="zoom slider"/> </floater> From 740666ad49eaa34456648b5df5aa6c7e97cc6348 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 20:50:35 -0700 Subject: [PATCH 188/239] Patch by Eryn: fixed the tools window not having enough room to display the ruler after applying Qarl's align patch --- .../indra/newview/skins/default/xui/en-us/floater_tools.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index d7a201312..fd9ec996d 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater bottom="-374" can_close="true" can_drag_on_left="false" can_minimize="true" - can_resize="false" follows="left|top" height="565" + can_resize="false" follows="left|top" height="575" left="308" min_height="100" min_width="100" mouse_opaque="true" name="toolbox floater" rect_control="ToolboxRect" sound_flags="0" title="" short_title="Build" width="272"> @@ -334,7 +334,7 @@ <!-- Sub-tabs --> - <tab_container bottom="-565" follows="left|top" height="384" left="0" mouse_opaque="false" + <tab_container bottom="-575" follows="left|top" height="384" left="0" mouse_opaque="false" name="Object Info Tabs" tab_max_width="52" tab_min_width="40" tab_position="top" width="272"> <panel border="true" bottom="-383" follows="left|top|right|bottom" height="367" From 9dec640eaf83700346e84de872d3e4a45a3e9126 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 20:57:20 -0700 Subject: [PATCH 189/239] Fixed the align tool label not hiding when switching tabs in the tools window --- linden/indra/newview/llfloatertools.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 683ebd4ba..4e9a83781 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -425,6 +425,7 @@ LLFloaterTools::LLFloaterTools() mRadioRotate(NULL), mRadioStretch(NULL), mRadioSelectFace(NULL), + mRadioAlign(NULL), mCheckSelectIndividual(NULL), mCheckSnapToGrid(NULL), @@ -705,6 +706,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioPosition ->setVisible( edit_visible ); mRadioRotate ->setVisible( edit_visible ); mRadioStretch ->setVisible( edit_visible ); + mRadioAlign ->setVisible( edit_visible ); if (mRadioSelectFace) { mRadioSelectFace->setVisible( edit_visible ); From ff01376fbe48d8265ba1f56a34e9934595a9699b Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 21:21:22 -0700 Subject: [PATCH 190/239] Fixed View > Web Browser sometimes loading the external browser and made it a menu item check rather than a call --- linden/indra/newview/llviewermenu.cpp | 13 ++++++++++++- .../newview/skins/default/xui/en-us/menu_viewer.xml | 5 +++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index b81a2a29a..7f003826c 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -6093,7 +6093,14 @@ class LLShowFloater : public view_listener_t } else if (floater_name == "inworld browser") { - LLWeb::loadURL(gSavedSettings.getString("BrowserHome")); + if (LLFloaterMediaBrowser::instanceVisible()) + { + LLFloaterMediaBrowser::getInstance()->close(); + } + else + { + LLWeb::loadURLInternal(gSavedSettings.getString("BrowserHome")); + } } else if (floater_name == "beacons") { @@ -6163,6 +6170,10 @@ class LLFloaterVisible : public view_listener_t LLInventoryView* iv = LLInventoryView::getActiveInventory(); new_value = (NULL != iv && TRUE == iv->getVisible()); } + else if (floater_name == "inworld browser") + { + new_value = LLFloaterMediaBrowser::instanceVisible(); + } else if (floater_name == "areasearch") { JCFloaterAreaSearch* instn = JCFloaterAreaSearch::getInstance(); diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 53e9e2d02..268ae2b01 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -311,10 +311,11 @@ <on_enable function="View.EnableLastChatter" /> </menu_item_call> <menu_item_separator /> - <menu_item_call name="Web Browser" label="Web Browser" + <menu_item_check name="Web Browser" label="Web Browser" shortcut="control|B"> <on_click function="ShowFloater" userdata="inworld browser" /> - </menu_item_call> + <on_check function="FloaterVisible" userdata="inworld browser" /> + </menu_item_check> <menu_item_separator /> <menu_item_check name="Toolbar" label="Toolbar"> <on_click function="ShowFloater" userdata="toolbar" /> From 7cb97df1cd8f61b25d033468c18951847076452d Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 21:29:28 -0700 Subject: [PATCH 191/239] Applied patch by Ansariel Hiller for #689: Optionally disable internal hover (fly) up animation --- linden/indra/newview/app_settings/settings.xml | 11 +++++++++++ linden/indra/newview/llvoavatar.cpp | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 33299ba00..ff90c86ff 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -364,6 +364,17 @@ <key>Value</key> <integer>3</integer> </map> + <key>DisableInternalFlyUpAnimation</key> + <map> + <key>Comment</key> + <string>Disables the internal hover up animation. Enable if you use an AO and wear hand attachments like rings, prim nails etc. that often loose their correct position while flying.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DisableLoginLogoutScreens</key> <map> <key>Comment</key> diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 54aed5406..6904bb20b 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -5490,6 +5490,15 @@ void LLVOAvatar::resetAnimations() //----------------------------------------------------------------------------- BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) { + // [Ansariel Hiller]: Disable pesky hover up animation that changes + // hand and finger position and often breaks correct + // fit of prim nails, rings etc. when flying and + // using an AO. + if ("62c5de58-cb33-5743-3d07-9e4cd4352864" == id.getString() && gSavedSettings.getBOOL("DisableInternalFlyUpAnimation")) + { + return TRUE; + } + LLMemType mt(LLMemType::MTYPE_AVATAR); // start special case female walk for female avatars From 7c009fc087bc156c56e330337d41009543e6d69c Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 21:32:24 -0700 Subject: [PATCH 192/239] Added info to DisableInternalFlyUpAnimation to clarify it's local machine only --- linden/indra/newview/app_settings/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index ff90c86ff..c946f40f0 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -367,7 +367,7 @@ <key>DisableInternalFlyUpAnimation</key> <map> <key>Comment</key> - <string>Disables the internal hover up animation. Enable if you use an AO and wear hand attachments like rings, prim nails etc. that often loose their correct position while flying.</string> + <string>Disables the internal hover up animation (on your local computer only). Enable if you use an AO and wear hand attachments like rings, prim nails etc. that often loose their correct position while flying.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> From a2fe83a4b8788f78c7f35b3b7e56ce38b628dd15 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 22:37:16 -0700 Subject: [PATCH 193/239] Fixed command line window missing a name for translation (patch by Eryn) --- .../newview/skins/default/xui/en-us/floater_command_line.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_command_line.xml b/linden/indra/newview/skins/default/xui/en-us/floater_command_line.xml index 35f47b5b5..13b334b2f 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_command_line.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_command_line.xml @@ -47,7 +47,7 @@ <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-20" follows="left|top" font="SansSerifSmall" height="20" left_delta="0" max_length="256" mouse_opaque="true" tool_tip="" name="CmdLineChatbarCalc" control_name="CmdLineChatbarCalc" width="200"/> - <text bottom_delta="-20" follows="left|top" font="SansSerifSmall" height="16" left_delta="0" + <text bottom_delta="-20" follows="left|top" font="SansSerifSmall" height="16" left_delta="0" name="add_autokorrect" width="512">Add autocorrect word(cmd list|bad|good)</text> <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-20" follows="left|top" font="SansSerifSmall" height="20" left_delta="0" max_length="256" mouse_opaque="true" @@ -105,4 +105,4 @@ <button bottom="-40" follows="left|top" font="SansSerifSmall" height="18" label="?" name="Help_CmdLine" tool_tip="Click here for help regarding the settings in this page." right="-10" width="18"/> -</floater> \ No newline at end of file +</floater> From d6357d0ddc7898b3f7bd1ac33419f25047f103cf Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Fri, 12 Nov 2010 22:59:29 -0700 Subject: [PATCH 194/239] Revert "Reduced the max width and height for the snapshot window to hopefully lower the crash rate a little" as it's a poor fix, and many photographers find the higher sizes useful This reverts commit 2819c9ae3652e913ea2d2da1c1ed8ef0d2175e00. --- .../newview/skins/default/xui/en-us/floater_snapshot.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_snapshot.xml b/linden/indra/newview/skins/default/xui/en-us/floater_snapshot.xml index db4d1e12f..3b039de03 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_snapshot.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_snapshot.xml @@ -136,10 +136,10 @@ </combo_box> <spinner bottom_delta="-25" decimal_digits="0" follows="left|top" height="20" - increment="32" label="Width" label_width="30" left="10" max_val="4096" + increment="32" label="Width" label_width="30" left="10" max_val="6016" min_val="32" name="snapshot_width" width="95" allow_text_entry="false"/> <spinner bottom_delta="0" decimal_digits="0" follows="left|top" height="20" - increment="32" label="Height" label_width="35" left="110" max_val="4096" + increment="32" label="Height" label_width="35" left="110" max_val="6016" min_val="32" name="snapshot_height" width="95" allow_text_entry="false"/> <check_box bottom_delta="-20" follows="left|top" label="Constrain Proportions" left="10" name="keep_aspect_check" /> From 00778fadf118ad6a9cdb0880b548f2129c696790 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 00:01:09 -0700 Subject: [PATCH 195/239] Added updated French translations for several preferences panels from Eddi Decosta --- .../xui/fr/panel_preferences_advanced.xml | 187 +++++++++++++++++- .../xui/fr/panel_preferences_audio.xml | 4 +- .../default/xui/fr/panel_preferences_im.xml | 18 +- 3 files changed, 199 insertions(+), 10 deletions(-) diff --git a/linden/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml b/linden/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml index 0c30199ac..4f33ae4ef 100644 --- a/linden/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml +++ b/linden/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml @@ -1,4 +1,183 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="advanced_panel"> - <check_box label="Partager la langue avec les objets" name="language_is_public" tool_tip="Cette option permet de faire connaître aux objets du Monde votre langue favorite."/> -</panel> +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" + height="408" label="Avancé" left="102" mouse_opaque="true" + name="advanced_panel" width="517"> + <!-- Start organizing these when we get enough of 'em - MC --> + <tab_container label="Page 2" bottom="0" height="450" left="0" mouse_opaque="false" + name="tab2" tab_min_width="50" tab_position="top" width="495" bg_opaque_color="0,0,0,0.0"> + + <panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom" + height="408" label="Main" left="102" mouse_opaque="true" + name="main_panel" width="517"> + <check_box label="Désactiver l'écrant de Connexion/Déconnexion" name="disable_log_screen_check" /> + <check_box label="Désactiver l'écrant de téléportation" name="disable_tp_screen_check" /> + <check_box label="Afficher les noms de clients dans les titres" name="client_name_tag_check"/> + <check_box label="Afficher les noms de clients avec la couleur" name="client_name_color_check"/> + <check_box label="Afficher les noms de clients dans les infos-bulles" name="client_name_hover_check" /> + <check_box label="Afficher le nom de votre clien pour les residents" name="client_name_tag_broadcast_check" radio_style="false" width="217" /> + <check_box label="Activer les Ombres (ATTENTION: instable et les graphiques Ultra sont requis)" name="shadows_check"/> + <text bottom_delta="-25" left="16" height="15" width="300" + follows="top|left"> + Laisser la région gèrer le WindLight (LightShare): + </text> + <combo_box name="lightshare_combo" + bottom_delta="-2" left_delta="250" height="18" width="135" + allow_text_entry="false" follows="left|top"> + <combo_item type="string" name="never" value="0"> + Jamais + </combo_item> + <combo_item type="string" name="ask" value="1"> + Toujours me le demander + </combo_item> + <combo_item type="string" name="always" value="2"> + Toujours + </combo_item> + </combo_box> + <check_box label="Utiliser le raffraichissement de texture HTTP (experimental)" name="http_texture_check" /> + <check_box label="Augmenter la vitesse de rez par une vue moins progressive" name="speed_rez_check"/> + <spinner label="Intervalle de chaque étapes:" name="speed_rez_interval_spinner" /> + <text bottom_delta="0" follows="top|left" height="15" left_delta="150" + name="speed_rez_seconds_text" width="115"> + secondes + </text> + <check_box label="Animer votre avatar quand vous êtes en mode apparence" name="appearance_anim_check"/> + <check_box label="Utiliser l'ancien menu de sélection" name="legacy_pie_menu_checkbox"/> + <check_box label="Partager la langue de votre client avec l'objet" name="language_is_public"/> + <check_box bottom_delta="-25" enabled="true" + follows="left|top" font="SansSerifSmall" height="16" hidden="false" + initial_value="false" label="Use MU* pose style chat and IM" left="12" + mouse_opaque="true" name="allow_mupose" + radio_style="false" tool_tip="Use MU* pose style in chat and IM (with ':' as a synonymous to '/me ')." + width="256" /> + <check_box bottom_delta="0" enabled="true" + follows="left|top" font="SansSerifSmall" height="16" hidden="false" + initial_value="false" label="Auto-close OOC (( )) chat" left_delta="250" + mouse_opaque="true" name="auto_close_ooc" + radio_style="false" tool_tip="Auto-close OOC chat (i.e. add )) if not found and (( was used)." + width="256" /> + <check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall" height="16" + initial_value="false" label="Use the chatbar as a command line" left="12" + mouse_opaque="true" name="command_line_check" radio_style="false" width="270"/> + <button bottom_delta="-20" follows="left|top" font="SansSerif" height="20" width="150" + label="Chatbar Commands" name="command_line_btn" left="12" + tool_tip="Set specific chatbar command line commands here" /> + + <!-- Uncomment when we start using the crash logger - MC --> + <!--<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom_delta="-30" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="18" left="12" + mouse_opaque="true" name="crash_report_textbox" v_pad="0" width="394"> + Crash reports: + </text> + <combo_box allow_text_entry="false" bottom_delta="0" enabled="true" follows="left|top" + height="18" left="153" max_chars="20" mouse_opaque="true" + name="crash_behavior_combobox" width="146"> + <combo_item type="string" length="1" enabled="true" name="Askbeforesending" value="Ask before sending"> + Ask before sending + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Alwayssend" value="Always send"> + Always send + </combo_item> + <combo_item type="string" length="1" enabled="true" name="Neversend" value="Never send"> + Never send + </combo_item> + </combo_box>--> + + <button bottom="10" follows="left|bottom" font="SansSerif" height="20" width="250" + label="Reset All Preferences To Default" name="reset_btn" left="12" + tool_tip="Reset all preferences to their default values (requires a restart)" /> + </panel> + + <panel border="true" bottom="-580" follows="left|top|right|bottom" height="525" label="SpellCheck" + left="1" mouse_opaque="true" name="SpellCheck" width="418"> + <button bottom="-25" follows="left|top" font="SansSerifSmall" height="18" label="?" + name="EmeraldHelp_SpellCheck" tool_tip="Click here for help regarding the settings in this page." + right="490" width="18"/> + <check_box bottom="-25" enabled="true" follows="left|top" font="SansSerifSmall" height="16" + label="Show misspelled words in red" left="12" mouse_opaque="true" name="EmeraldSpellDisplay" + control_name="EmeraldSpellDisplay" width="126"/> + <text bottom_delta="-30" follows="left|top" font="SansSerifSmall" height="16" left="12" + name="EmSpell_txt1" width="512"> + Current language (dictionary): + </text> + <combo_box allow_text_entry="false" bottom_delta="-20" left_delta="0" follows="left|top" height="18" + max_chars="200" mouse_opaque="true" name="EmeraldSpellBase" width="250" + control_name="EmeraldSpellBase" tool_tip=""/> + <text bottom_delta="-30" follows="left|top" font="SansSerifSmall" height="16" left="12" + name="EmSpell_txt3" width="512"> + Downloaded languages (dictionaries): + </text> + <combo_box allow_text_entry="false" bottom_delta="-20" left_delta="0" follows="left|top" height="18" + max_chars="200" mouse_opaque="true" name="EmSpell_Avail" width="250" + control_name="EmSpell_Avail" tool_tip=""/> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="20" label="Install" + name="EmSpell_Add" tool_tip="" left_delta="255" width="80"/> + <button bottom_delta="-22" follows="left|top" font="SansSerifSmall" height="20" label="Download More..." + name="EmSpell_GetMore" tool_tip="Get more dictionaries availabe online" left="12" width="250"/> + <text bottom_delta="-30" follows="left|top" font="SansSerifSmall" height="16" left="12" + name="EmSpell_txt2" width="512"> + Additional custom languages (dictionaries): + </text> + <combo_box allow_text_entry="false" bottom_delta="-20" left_delta="0" follows="left|top" height="18" + max_chars="200" mouse_opaque="true" name="EmSpell_Installed" width="250" + control_name="EmSpell_Installed" tool_tip=""/> + <button bottom_delta="0" follows="left|top" font="SansSerifSmall" height="20" label="Remove" + name="EmSpell_Remove" tool_tip="" left_delta="255" width="80"/> + <!--<button bottom_delta="-20" follows="left|top" font="SansSerifSmall" height="18" label="Edit Custom dictionary" + name="EmSpell_EditCustom" tool_tip="" left_delta="20" width="130"/>--> + <text bottom_delta="-30" follows="left|top" font="SansSerifSmall" height="16" left="12" + name="EmSpell_txt4" width="512"> +To use spellcheck, right-click a misspelled word +(red or otherwise) and select its replacement + </text> + <button name="ac_button" label="AutoCorrect Options..." halign="center" + tool_tip="Modify the AutoCorrect word list and settings" left="12" + bottom_delta="-50" width="180" height="20" font="SansSerifSmall" follows="left|top"/> + </panel> + + <panel border="true" bottom="-580" follows="left|top|right|bottom" height="525" label="Extra" + left="1" mouse_opaque="true" name="Extra" width="418"> + + <check_box bottom_delta="-30" enabled="true" follows="left|top" font="SansSerifSmall" height="16" + initial_value="true" label="Show chat messages from friends in a different color" left="12" + mouse_opaque="true" name="HighlightFriendsChat" radio_style="false" width="270"/> + + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-100" + can_apply_immediately="true" color="1 1 1 1" control_name="FriendsChatColor" + enabled="true" follows="left|top" height="67" label="Friends" left_delta="68" + mouse_opaque="true" name="FriendsChatColor" width="65" /> + + <check_box bottom_delta="-30" enabled="true" follows="left|top" + font="SansSerifSmall" height="16" initial_value="true" + label="Show chat messages containing your name in a different color" left="12" mouse_opaque="true" + name="HighlightOwnNameInChat" radio_style="false" width="217" /> + + <check_box bottom_delta="-30" enabled="true" follows="left|top" font="SansSerifSmall" height="16" + initial_value="true" label="Show GroupIM messages containing your name in a different color" left="12" + mouse_opaque="true" name="HighlightOwnNameInIM" radio_style="false" width="270"/> + + <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-230" + can_apply_immediately="true" color="1 1 1 1" control_name="OwnNameChatColor" + enabled="true" follows="left|top" height="67" label="Own Name" left_delta="68" + mouse_opaque="true" name="OwnNameChatColor" width="65" /> + + <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-50" + enabled="true" follows="left|top" font="SansSerif" + handle_edit_keys_directly="true" height="20" left_delta="0" + max_length="50" mouse_opaque="true" name="nick01" + select_all_on_focus_received="true" width="400" word_wrap="false" /> + + <text bottom_delta="-3" follows="left|top" font="SansSerifSmall" height="20" left="20" name="nick01_text" width="70">Nick 1</text> + + <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-30" + enabled="true" follows="left|top" font="SansSerif" + handle_edit_keys_directly="true" height="20" left_delta="60" + max_length="50" mouse_opaque="true" name="nick02" + select_all_on_focus_received="true" width="400" word_wrap="false" /> + + <text bottom_delta="-3" follows="left|top" font="SansSerifSmall" height="20" left="20" name="nick02_text" width="70">Nick 2</text> + + <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-30" + enabled="true" follows="left|top" font="SansSerif" + handle_edit_keys_directly="true" height="20" left_delta="60" + max_length="50" mouse_opaque="true" name="nick03" diff --git a/linden/indra/newview/skins/default/xui/fr/panel_preferences_audio.xml b/linden/indra/newview/skins/default/xui/fr/panel_preferences_audio.xml index 78475bd34..d4574d107 100644 --- a/linden/indra/newview/skins/default/xui/fr/panel_preferences_audio.xml +++ b/linden/indra/newview/skins/default/xui/fr/panel_preferences_audio.xml @@ -15,6 +15,7 @@ <check_box label="Couper le son lorsque la fenêtre est minimisée" name="mute_when_minimized"/> <check_box bottom="-200" height="32" label="Jouer la musique disponible (consommateur en bande passante)" name="streaming_music"/> + <check_box bottom_delta="-30" label="Afficher le titre de la chanson" name="show_stream_title"/> <check_box bottom_delta="-32" height="32" label="Jouer le média disponible (consommateur en bande passante)" name="streaming_video"/> <check_box bottom_delta="-32" label="Lire automatiquement le média" name="auto_streaming_video"/> @@ -22,5 +23,6 @@ <slider label="Facteur d'éloignement" label_width="115" name="Distance Factor"/> <slider label="Facteur d'atténuation" label_width="115" name="Rolloff Factor"/> <spinner label="Alerte L$" name="L$ Change Threshold"/> - <spinner label="Alerte santé" name="Health Change Threshold"/> + <spinner label="Alerte santé" name="Health change threshold"/> + <check_box label="Desactiver le bruit du vent" name="mute_wind_check"/> </panel> diff --git a/linden/indra/newview/skins/default/xui/fr/panel_preferences_im.xml b/linden/indra/newview/skins/default/xui/fr/panel_preferences_im.xml index 2e7efd31e..af5f846a9 100644 --- a/linden/indra/newview/skins/default/xui/fr/panel_preferences_im.xml +++ b/linden/indra/newview/skins/default/xui/fr/panel_preferences_im.xml @@ -8,9 +8,17 @@ se connecter pour changer </text> <check_box label="Envoyer les IM à mon adresse e-mail ([EMAIL])" name="send_im_to_email"/> - <check_box label="Afficher les IM dans la console du chat" name="include_im_in_chat_console"/> - <check_box label="Afficher l'heure dans les IM" name="show_timestamps_check"/> - <check_box label="Me prévenir quand des amis se connectent" name="friends_online_notify_checkbox"/> + <check_box bottom="-90" label="La console chat" name="include_im_in_chat_console" left="160"/> + <check_box bottom="-90" label="La fenêtre communiquer" name="include_im_in_chat_history" left="260" /> + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + bottom="-60" drop_shadow_visible="true" enabled="true" follows="left|top" + font="SansSerifSmall" h_pad="0" halign="left" height="10" left="160" + mouse_opaque="false" name="show_ims_label" v_pad="0" width="100"> + Afficher les IMs dans: + </text> + <check_box bottom="-120" label="Afficher l'heure dans les IM" name="show_timestamps_check"/> + <check_box bottom="-140" label="Me prévenir quand des amis se connectent" name="friends_online_notify_checkbox"/> + <check_box label="Afficher les IMs verticalement (redémarrage requis)" name="vertical-imtabs-toggle"/> <text name="text_box3"> Réponse si occupé(e) : </text> @@ -24,8 +32,8 @@ <check_box label="Inclure les heures" name="log_chat_timestamp"/> <check_box label="Inclure les IM reçus" name="log_chat_IM"/> <check_box label="Inclure la date avec les heures" name="log_date_timestamp"/> - <button label="Changer d'emplacement" label_selected="Changer d'emplacement" name="log_path_button" width="150"/> - <line_editor left="308" name="log_path_string" right="-20"/> + <button label="Changer d'emplacement" label_selected="Changer d'emplacement" name="log_path_button" left="145" width="170"/> + <line_editor left="320" name="log_path_string" right="-20"/> <text length="1" name="text_box2" type="string"> IM : </text> From b11fcc642f65d022011244b0fe2e3d1a7c741a28 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 00:05:10 -0700 Subject: [PATCH 196/239] Added default_grids.xml to cmake --- linden/indra/newview/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index dff759e00..e6c17678d 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -1186,6 +1186,7 @@ set(viewer_APPSETTINGS_FILES app_settings/anim.ini app_settings/ao_template.ini app_settings/cmd_line.xml + app_settings/default_grids.xml app_settings/grass.xml app_settings/high_graphics.xml app_settings/keys.ini From 6ce31af828b80a61c09fc8223dd1494d6c2912de Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 00:07:17 -0700 Subject: [PATCH 197/239] Applied patch by tx Oh for #647: loginuri of osgrid changed --- linden/indra/newview/app_settings/default_grids.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/app_settings/default_grids.xml b/linden/indra/newview/app_settings/default_grids.xml index 2c52fa1b7..745ec65ee 100644 --- a/linden/indra/newview/app_settings/default_grids.xml +++ b/linden/indra/newview/app_settings/default_grids.xml @@ -50,7 +50,7 @@ <key>gridnick</key><string>osgrid</string> <key>gridname</key><string>OSGrid</string> <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://osgrid.org:8002/</string> + <key>loginuri</key><string>http://login.osgrid.org/</string> <key>loginpage</key><string>http://osgrid.org/loginscreen.php</string> <key>helperuri</key><string>http://osgrid.org/</string> <key>website</key><string>http://osgrid.org/</string> From cf368d0a0492a3825f63ac5539f61fe9ae77b870 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 00:16:53 -0700 Subject: [PATCH 198/239] Updated local copy of default_grids.xml with the latest osgrid register/password urls and science sim name --- linden/indra/newview/app_settings/default_grids.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/app_settings/default_grids.xml b/linden/indra/newview/app_settings/default_grids.xml index 745ec65ee..3f44e4b90 100644 --- a/linden/indra/newview/app_settings/default_grids.xml +++ b/linden/indra/newview/app_settings/default_grids.xml @@ -51,12 +51,12 @@ <key>gridname</key><string>OSGrid</string> <key>platform</key><string>OpenSim</string> <key>loginuri</key><string>http://login.osgrid.org/</string> - <key>loginpage</key><string>http://osgrid.org/loginscreen.php</string> - <key>helperuri</key><string>http://osgrid.org/</string> + <key>loginpage</key><string>http://osgrid.org/splash/</string> + <key>helperuri</key><string>http://helper.osgrid.org/</string> <key>website</key><string>http://osgrid.org/</string> <key>support</key><string>http://osgrid.org/</string> - <key>register</key><string>http://osgrid.org/elgg/account/register.php</string> - <key>password</key><string>http://osgrid.org/elgg/account/forgotten_password.php</string> + <key>register</key><string>http://www.osgrid.org/index.php/auth/register</string> + <key>password</key><string>http://www.osgrid.org/index.php/auth/forgot_password</string> <key>version</key><string>1</string> </map> @@ -219,7 +219,7 @@ <!-- ScienceSim --> <map> - <key>gridname</key> <string>ScienceSim</string> + <key>gridname</key> <string>IEEE/ACM ScienceSim Virtual World</string> <key>gridnick</key> <string>sciencesim</string> <key>platform</key> <string>OpenSim</string> <key>loginuri</key> <string>http://grid.sciencesim.com/</string> From 2b8bfabcefbd00c9f23af55c2db150abed16e644 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 00:17:34 -0700 Subject: [PATCH 199/239] Changed version to Experimental 2010.11.13 --- linden/indra/newview/app_settings/viewerversion.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/app_settings/viewerversion.xml b/linden/indra/newview/app_settings/viewerversion.xml index ab4b720e4..f9b0ba2b3 100644 --- a/linden/indra/newview/app_settings/viewerversion.xml +++ b/linden/indra/newview/app_settings/viewerversion.xml @@ -20,6 +20,6 @@ need to be changed manually - MC <viewer version_patch="0" /> <!--string--> - <viewer version_test="Experimental 2010.10.23" /> + <viewer version_test="Experimental 2010.11.13" /> </viewer_version> From bbf1f41550945ff25cd2f021b42c235702941ae1 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 00:41:25 -0700 Subject: [PATCH 200/239] Added some status text for the new align tool --- linden/indra/newview/llfloatertools.cpp | 1 + linden/indra/newview/qtoolalign.cpp | 3 ++- linden/indra/newview/skins/default/xui/en-us/floater_tools.xml | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 4e9a83781..0cb35e3ff 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -393,6 +393,7 @@ BOOL LLFloaterTools::postBuild() mStatusText["rotate"] = getString("status_rotate"); mStatusText["scale"] = getString("status_scale"); mStatusText["move"] = getString("status_move"); + mStatusText["align"] = getString("status_align"); mStatusText["modifyland"] = getString("status_modifyland"); mStatusText["camera"] = getString("status_camera"); mStatusText["grab"] = getString("status_grab"); diff --git a/linden/indra/newview/qtoolalign.cpp b/linden/indra/newview/qtoolalign.cpp index d7f7ad011..ac6a0bb8f 100644 --- a/linden/indra/newview/qtoolalign.cpp +++ b/linden/indra/newview/qtoolalign.cpp @@ -110,8 +110,9 @@ void QToolAlign::handleSelect() { // no parts, please - llwarns << "in select" << llendl; + //llwarns << "in select" << llendl; LLSelectMgr::getInstance()->promoteSelectionToRoot(); + gFloaterTools->setStatusText("align"); } diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index fd9ec996d..18e0274d6 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -1363,6 +1363,9 @@ <string name="status_move"> Drag to Move, Shift-Drag to Copy </string> + <string name="status_align"> + Aligns objects along an axis, hold Shift to Pack + </string> <string name="status_modifyland"> Click and Hold to Modify Land </string> From 3c51d5f2171fba704eea9c36bf9a476f5f7a59ae Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 01:01:08 -0700 Subject: [PATCH 201/239] Ported fix from Ascent: disable align tool controls if you can't move the object, by Beeks --- linden/indra/newview/qtoolalign.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/qtoolalign.cpp b/linden/indra/newview/qtoolalign.cpp index ac6a0bb8f..3fe31f7e3 100644 --- a/linden/indra/newview/qtoolalign.cpp +++ b/linden/indra/newview/qtoolalign.cpp @@ -387,8 +387,24 @@ void QToolAlign::render() LLColor4 default_normal_color( 0.7f, 0.7f, 0.7f, 0.1f ); gGL.color4fv( default_normal_color.mV ); - render_bbox(mBBox); - renderManipulators(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getEditSelection(); + BOOL can_move = selection->getObjectCount() != 0; + if (can_move) + { + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* objectp) + { + return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); + } + } func; + can_move = selection->applyToObjects(&func); + } + if (can_move) + { + render_bbox(mBBox); + renderManipulators(); + } } // only works for our specialized (AABB, position centered) bboxes From 21d5c3e85bbb3cdc556918c6699df768e6f01637 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Sat, 13 Nov 2010 01:54:21 -0700 Subject: [PATCH 202/239] Ported keyboard shortcut for align tool from Ascent, by Beeks. Has the followingrepercussions: * CTRL-A while a prim is selected switches to the align tool * CTRL-SHIFT-A while a prim is selected switches to the pack tool * Area Object Search shortcut has been changed from CTRL-SHIFT-A to ALT-A --- linden/indra/newview/lltoolcomp.cpp | 22 ++++++++++++++++--- .../skins/default/xui/en-us/floater_tools.xml | 2 +- .../skins/default/xui/en-us/menu_viewer.xml | 3 ++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/linden/indra/newview/lltoolcomp.cpp b/linden/indra/newview/lltoolcomp.cpp index 16e0136b8..7bf99f050 100644 --- a/linden/indra/newview/lltoolcomp.cpp +++ b/linden/indra/newview/lltoolcomp.cpp @@ -55,6 +55,7 @@ #include "llagent.h" #include "llfloatertools.h" #include "llviewercontrol.h" +#include "qtoolalign.h" const S32 BUTTON_HEIGHT = 16; const S32 BUTTON_WIDTH_SMALL = 32; @@ -278,7 +279,12 @@ BOOL LLToolCompTranslate::handleMouseUp(S32 x, S32 y, MASK mask) LLTool* LLToolCompTranslate::getOverrideTool(MASK mask) { - if (mask == MASK_CONTROL) + if (gKeyboard->getKeyDown('A') && + ((mask & MASK_CONTROL) || (mask == (MASK_CONTROL | MASK_SHIFT)))) + { + return QToolAlign::getInstance(); + } + else if (mask == MASK_CONTROL) { return LLToolCompRotate::getInstance(); } @@ -397,7 +403,12 @@ BOOL LLToolCompScale::handleMouseUp(S32 x, S32 y, MASK mask) LLTool* LLToolCompScale::getOverrideTool(MASK mask) { - if (mask == MASK_CONTROL) + if (gKeyboard->getKeyDown('A') && + ((mask & MASK_CONTROL) || (mask == (MASK_CONTROL | MASK_SHIFT)))) + { + return QToolAlign::getInstance(); + } + else if (mask == MASK_CONTROL) { return LLToolCompRotate::getInstance(); } @@ -597,7 +608,12 @@ BOOL LLToolCompRotate::handleMouseUp(S32 x, S32 y, MASK mask) LLTool* LLToolCompRotate::getOverrideTool(MASK mask) { - if (mask == (MASK_CONTROL | MASK_SHIFT)) + if (gKeyboard->getKeyDown('A') && + ((mask & MASK_CONTROL) || (mask == (MASK_CONTROL | MASK_SHIFT)))) + { + return QToolAlign::getInstance(); + } + else if (mask == (MASK_CONTROL | MASK_SHIFT)) { return LLToolCompScale::getInstance(); } diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index 18e0274d6..c665563aa 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -1364,7 +1364,7 @@ Drag to Move, Shift-Drag to Copy </string> <string name="status_align"> - Aligns objects along an axis, hold Shift to Pack + CTRL-A to align on an axis, CTRL-Shift-A to Pack </string> <string name="status_modifyland"> Click and Hold to Modify Land diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 268ae2b01..31e730a8a 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -996,7 +996,8 @@ <on_click function="ShowFloater" userdata="animation list" /> <on_check function="FloaterVisible" userdata="animation list" /> </menu_item_check> - <menu_item_check label="Area Object Search" name="Area Object Search" shortcut="control|shift|A"> + <menu_item_check label="Area Object Search" name="Area Object Search" + shortcut="alt|A"> <on_click function="ShowFloater" userdata="areasearch" /> <on_check function="FloaterVisible" userdata="areasearch" /> </menu_item_check> From 0bd60279fe449c9c08b144213d497eda89fd4ded Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 15:28:17 -0600 Subject: [PATCH 203/239] Disable SSE4 on Mac (temporarily). GCC 4.0 on Mac OS X 10.5 can't handle SSE4, GCC 4.2 fails. --- linden/indra/cmake/00-Common.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/indra/cmake/00-Common.cmake b/linden/indra/cmake/00-Common.cmake index c3aa9eafb..7e85ce0c0 100644 --- a/linden/indra/cmake/00-Common.cmake +++ b/linden/indra/cmake/00-Common.cmake @@ -194,8 +194,8 @@ if (DARWIN) add_definitions(-DLL_DARWIN=1) set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch -msse3 -msse4.1 -msse4.2 -mssse3 -w") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch -msse3 -msse4.1 -msse4.2 -mssse3 -w") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch -msse3 -mssse3 -w") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch -msse3 -mssse3 -w") # NOTE: it's critical that the optimization flag is put in front. # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") From 43f6513eaf38d3c21dcf0aef8cb1cd61a6860f18 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 15:29:51 -0600 Subject: [PATCH 204/239] GStreamer010 plugin needs Carbon.h on Mac. --- .../media_plugins/gstreamer010/media_plugin_gstreamer010.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 78e46ca2f..ed6d920d5 100755 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -42,6 +42,10 @@ #include <stdio.h> #endif +#ifdef LL_DARWIN +#include <Carbon/Carbon.h> +#endif + #include "llgl.h" #include "llplugininstance.h" From 99817b5eaf819ad689192eab5adf1589ca38afa6 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 15:30:07 -0600 Subject: [PATCH 205/239] Use Quicktime plugin on Mac, not GStreamer. --- linden/indra/media_plugins/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linden/indra/media_plugins/CMakeLists.txt b/linden/indra/media_plugins/CMakeLists.txt index c4f255527..a4c6b1845 100755 --- a/linden/indra/media_plugins/CMakeLists.txt +++ b/linden/indra/media_plugins/CMakeLists.txt @@ -4,12 +4,12 @@ add_subdirectory(base) add_subdirectory(webkit) -if (LINUX OR DARWIN) +if (LINUX) add_subdirectory(gstreamer010) -endif (LINUX OR DARWIN) +endif (LINUX) -if (WINDOWS) +if (WINDOWS OR DARWIN) add_subdirectory(quicktime) -endif (WINDOWS) +endif (WINDOWS OR DARWIN) add_subdirectory(example) From ecd500422dcd1e6f06fc22019070b6ffe6944123 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 16:22:02 -0600 Subject: [PATCH 206/239] Ported some LLWindowMacOSX changes from Snowglobe 2. Fixes missing definition for LLWindowMacOSX::getNativeKeyData(). --- linden/indra/llwindow/llwindowmacosx-objc.h | 2 +- linden/indra/llwindow/llwindowmacosx-objc.mm | 2 +- linden/indra/llwindow/llwindowmacosx.cpp | 94 ++++++++++++++++++-- linden/indra/llwindow/llwindowmacosx.h | 12 +-- 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/linden/indra/llwindow/llwindowmacosx-objc.h b/linden/indra/llwindow/llwindowmacosx-objc.h index a96246e62..9821698ec 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.h +++ b/linden/indra/llwindow/llwindowmacosx-objc.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2006&license=viewergpl$ * - * Copyright (c) 2006-2009, Linden Research, Inc. + * Copyright (c) 2006-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab diff --git a/linden/indra/llwindow/llwindowmacosx-objc.mm b/linden/indra/llwindow/llwindowmacosx-objc.mm index 80ad0871e..34ec4453b 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.mm +++ b/linden/indra/llwindow/llwindowmacosx-objc.mm @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2006&license=viewergpl$ * - * Copyright (c) 2006-2009, Linden Research, Inc. + * Copyright (c) 2006-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab diff --git a/linden/indra/llwindow/llwindowmacosx.cpp b/linden/indra/llwindow/llwindowmacosx.cpp index d68d4df58..99daa4d46 100644 --- a/linden/indra/llwindow/llwindowmacosx.cpp +++ b/linden/indra/llwindow/llwindowmacosx.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -250,6 +250,7 @@ LLWindowMacOSX::LLWindowMacOSX(const std::string& title, const std::string& name mTSMScriptCode = 0; mTSMLangCode = 0; mPreeditor = NULL; + mRawKeyEvent = NULL; mFSAASamples = fsaa_samples; mForceRebuild = FALSE; @@ -1029,6 +1030,7 @@ void LLWindowMacOSX::hide() HideWindow(mWindow); } +//virtual void LLWindowMacOSX::minimize() { setMouseClipping(FALSE); @@ -1036,6 +1038,7 @@ void LLWindowMacOSX::minimize() CollapseWindow(mWindow, true); } +//virtual void LLWindowMacOSX::restore() { show(); @@ -1436,7 +1439,7 @@ static void fixOrigin(void) ::GetPortBounds(port, &portrect); if((portrect.left != 0) || (portrect.top != 0)) { - // Mozilla sometimes changes our port origin. Fuckers. + // Mozilla sometimes changes our port origin. ::SetOrigin(0,0); } } @@ -2128,10 +2131,11 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e { UInt32 modifiers = 0; + // First, process the raw event. { - EventRef rawEvent; - + EventRef rawEvent = NULL; + // Get the original event and extract the modifier keys, so we can ignore command-key events. if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr) { @@ -2140,6 +2144,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e // and call this function recursively to handle the raw key event. eventHandler (myHandler, rawEvent); + + // save the raw event until we're done processing the unicode input as well. + mRawKeyEvent = rawEvent; } } @@ -2167,11 +2174,8 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e } else { - MASK mask = 0; - if(modifiers & shiftKey) { mask |= MASK_SHIFT; } - if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; } - if(modifiers & optionKey) { mask |= MASK_ALT; } - + MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); + llassert( actualType == typeUnicodeText ); // The result is a UTF16 buffer. Pass the characters in turn to handleUnicodeChar. @@ -2193,6 +2197,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e delete[] buffer; } + mRawKeyEvent = NULL; result = err; } break; @@ -2267,6 +2272,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); + // save the raw event so getNativeKeyData can use it. + mRawKeyEvent = event; + // printf("key event, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", keyCode, charCode, (char)charCode, modifiers); // fflush(stdout); @@ -2362,6 +2370,8 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e result = eventNotHandledErr; break; } + + mRawKeyEvent = NULL; } break; @@ -3162,6 +3172,8 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url) OSStatus result = noErr; CFURLRef urlRef = NULL; + llinfos << "Opening URL " << escaped_url << llendl; + CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url.c_str(), kCFStringEncodingUTF8); if (stringRef) { @@ -3191,6 +3203,60 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url) } } +LLSD LLWindowMacOSX::getNativeKeyData() +{ + LLSD result = LLSD::emptyMap(); + + if(mRawKeyEvent) + { + char char_code = 0; + UInt32 key_code = 0; + UInt32 modifiers = 0; + UInt32 keyboard_type = 0; + + GetEventParameter (mRawKeyEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &char_code); + GetEventParameter (mRawKeyEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code); + GetEventParameter (mRawKeyEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); + GetEventParameter (mRawKeyEvent, kEventParamKeyboardType, typeUInt32, NULL, sizeof(UInt32), NULL, &keyboard_type); + + result["char_code"] = (S32)char_code; + result["key_code"] = (S32)key_code; + result["modifiers"] = (S32)modifiers; + result["keyboard_type"] = (S32)keyboard_type; + +#if 0 + // This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc) + // cause llsd serialization to create XML that the llsd deserializer won't parse! + std::string unicode; + OSStatus err = noErr; + EventParamType actualType = typeUTF8Text; + UInt32 actualSize = 0; + char *buffer = NULL; + + err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, 0, &actualSize, NULL); + if(err == noErr) + { + // allocate a buffer and get the actual data. + buffer = new char[actualSize]; + err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, actualSize, &actualSize, buffer); + if(err == noErr) + { + unicode.assign(buffer, actualSize); + } + delete[] buffer; + } + + result["unicode"] = unicode; +#endif + + } + + + lldebugs << "native key data is: " << result << llendl; + + return result; +} + void LLWindowMacOSX::ShellEx(const std::string& command) { OSStatus result = noErr; @@ -3392,3 +3458,13 @@ std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList() return std::vector<std::string>(); } +// static +MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers) +{ + MASK mask = 0; + if(modifiers & shiftKey) { mask |= MASK_SHIFT; } + if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; } + if(modifiers & optionKey) { mask |= MASK_ALT; } + return mask; +} + diff --git a/linden/indra/llwindow/llwindowmacosx.h b/linden/indra/llwindow/llwindowmacosx.h index d4c1b44b8..8213b6913 100644 --- a/linden/indra/llwindow/llwindowmacosx.h +++ b/linden/indra/llwindow/llwindowmacosx.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewergpl$ * - * Copyright (c) 2001-2009, Linden Research, Inc. + * Copyright (c) 2001-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -56,6 +56,8 @@ class LLWindowMacOSX : public LLWindow /*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); @@ -144,9 +146,6 @@ class LLWindowMacOSX : public LLWindow // Restore the display resolution to its value before we ran the app. BOOL resetDisplayResolution(); - void minimize(); - void restore(); - BOOL shouldPostQuit() { return mPostQuit; } @@ -165,8 +164,8 @@ class LLWindowMacOSX : public LLWindow void adjustCursorDecouple(bool warpingMouse = false); void fixWindowSize(void); void stopDockTileBounce(); - - + static MASK modifiersToMask(SInt16 modifiers); + // // Platform specific variables // @@ -214,6 +213,7 @@ class LLWindowMacOSX : public LLWindow friend class LLWindowManager; static WindowRef sMediaWindow; + EventRef mRawKeyEvent; }; From dfc585e4c1608c6f24912d9eb9587242a9e43335 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 21:42:29 -0600 Subject: [PATCH 207/239] Roll back llqtwebkit package to 20100617 on Mac. Bandaid for this compile error when linking media_plugin_webkit.dylib: Undefined symbols: "LLEmbeddedBrowserWindowObserver::onRequestFilePicker(LLEmbeddedBrowserWindowEvent const&)", referenced from: vtable for MediaPluginWebKitin media_plugin_webkit.o --- linden/install.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/install.xml b/linden/install.xml index 1df31e245..e8c8b54e4 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -1036,9 +1036,9 @@ Portions copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura <key>darwin</key> <map> <key>md5sum</key> - <string>34d9e4c93678a422cf80521bf0cd7628</string> + <string>becffca6bd8dcb239de284ea2a8b485b</string> <key>url</key> - <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100914.tar.bz2</uri> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6+cookies-darwin-20100617.tar.bz2</uri> </map> <key>linux</key> <map> From 385be943dc214692d9590fc6a1df328197d3f98e Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 21:54:46 -0600 Subject: [PATCH 208/239] Disable packaging of mac-updater.app. --- linden/indra/newview/viewer_manifest.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index f9c34d68f..75272445e 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -768,20 +768,20 @@ def construct(self): # our apps # self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") - self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") + # self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") # our apps dependencies on shared libs - mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") - mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") - for libfile in ("libllcommon.dylib", - "libapr-1.0.3.7.dylib", - "libaprutil-1.0.3.8.dylib", - "libexpat.0.5.0.dylib"): - target_lib = os.path.join('../../..', libfile) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(mac_crash_logger_res_path, libfile)} - ) + # mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") + # mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") + # for libfile in ("libllcommon.dylib", + # "libapr-1.0.3.7.dylib", + # "libaprutil-1.0.3.8.dylib", + # "libexpat.0.5.0.dylib"): + # target_lib = os.path.join('../../..', libfile) + # self.run_command("ln -sf %(target)r %(link)r" % + # {'target': target_lib, + # 'link' : os.path.join(mac_crash_logger_res_path, libfile)} + # ) # plugin launcher self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin") From f179eb876d478b84e9ab5e88ce9302fbb34cc9ac Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 23:01:34 -0600 Subject: [PATCH 209/239] Commented out gstreamer libs from Mac manifest. --- linden/indra/newview/viewer_manifest.py | 184 ++++++++++++------------ 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 75272445e..aa7450240 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -582,28 +582,28 @@ def construct(self): self.path("libgobject-2.0.dylib") self.path("libgthread-2.0.dylib") - self.path("libgstreamer-0.10.dylib") - self.path("libgstapp-0.10.dylib") - self.path("libgstaudio-0.10.dylib") - self.path("libgstbase-0.10.dylib") - self.path("libgstcdda-0.10.dylib") - self.path("libgstcontroller-0.10.dylib") - self.path("libgstdataprotocol-0.10.dylib") - self.path("libgstfft-0.10.dylib") - self.path("libgstinterfaces-0.10.dylib") - self.path("libgstnet-0.10.dylib") - self.path("libgstnetbuffer-0.10.dylib") - self.path("libgstpbutils-0.10.dylib") - self.path("libgstriff-0.10.dylib") - self.path("libgstrtp-0.10.dylib") - self.path("libgstrtsp-0.10.dylib") - self.path("libgstsdp-0.10.dylib") - self.path("libgsttag-0.10.dylib") - self.path("libgstvideo-0.10.dylib") + # self.path("libgstreamer-0.10.dylib") + # self.path("libgstapp-0.10.dylib") + # self.path("libgstaudio-0.10.dylib") + # self.path("libgstbase-0.10.dylib") + # self.path("libgstcdda-0.10.dylib") + # self.path("libgstcontroller-0.10.dylib") + # self.path("libgstdataprotocol-0.10.dylib") + # self.path("libgstfft-0.10.dylib") + # self.path("libgstinterfaces-0.10.dylib") + # self.path("libgstnet-0.10.dylib") + # self.path("libgstnetbuffer-0.10.dylib") + # self.path("libgstpbutils-0.10.dylib") + # self.path("libgstriff-0.10.dylib") + # self.path("libgstrtp-0.10.dylib") + # self.path("libgstrtsp-0.10.dylib") + # self.path("libgstsdp-0.10.dylib") + # self.path("libgsttag-0.10.dylib") + # self.path("libgstvideo-0.10.dylib") self.path("libxml2.2.dylib") - self.path("libfaad.2.dylib") - self.path("libFLAC.8.dylib") + # self.path("libfaad.2.dylib") + # self.path("libFLAC.8.dylib") self.path("libintl.3.dylib") self.path("libjpeg.62.dylib") self.path("libpng12.0.dylib") @@ -611,7 +611,7 @@ def construct(self): self.path("libogg.0.dylib") self.path("liboil-0.3.0.dylib") self.path("libopenjpeg.1.4.dylib") - self.path("libtheora.0.dylib") + # self.path("libtheora.0.dylib") self.path("libvorbis.0.dylib") self.path("libvorbisenc.2.dylib") self.path("libvorbisfile.3.dylib") @@ -657,78 +657,78 @@ def construct(self): self.path("zh-Hans.lproj") - if (not self.standalone()) and self.prefix(src="../../libraries/universal-darwin/lib_release/gstreamer-plugins", dst="lib/gstreamer-plugins"): - self.path("libgstaacparse.so") - self.path("libgstadder.so") - self.path("libgstaiffparse.so") - self.path("libgstamrparse.so") - self.path("libgstapp.so") - self.path("libgstaudioconvert.so") - self.path("libgstaudiorate.so") - self.path("libgstaudioresample.so") - self.path("libgstautodetect.so") - self.path("libgstavi.so") - self.path("libgstcoreelements.so") - self.path("libgstcoreindexers.so") - self.path("libgstdebug.so") - self.path("libgstdecodebin.so") - self.path("libgstdecodebin2.so") - self.path("libgstdeinterlace2.so") - self.path("libgstequalizer.so") - self.path("libgstfaad.so") - self.path("libgstffmpeg.so") - self.path("libgstffmpegcolorspace.so") - self.path("libgstffmpegscale.so") - self.path("libgstfilter.so") - self.path("libgstflac.so") - self.path("libgstflv.so") - self.path("libgstgdp.so") - self.path("libgsth264parse.so") - self.path("libgsticydemux.so") - self.path("libgstid3demux.so") - self.path("libgstinterleave.so") - self.path("libgstjpeg.so") - self.path("libgstlevel.so") - self.path("libgstmetadata.so") - self.path("libgstmpeg4videoparse.so") - self.path("libgstmpegdemux.so") - self.path("libgstmpegvideoparse.so") - self.path("libgstmultifile.so") - self.path("libgstmultipart.so") - self.path("libgstneonhttpsrc.so") - self.path("libgstogg.so") - self.path("libgstosxaudio.so") - self.path("libgstosxvideosink.so") - self.path("libgstplaybin.so") - self.path("libgstpng.so") - self.path("libgstpostproc.so") - self.path("libgstqtdemux.so") - #self.path("libgstqtwrapper.so") - self.path("libgstqueue2.so") - self.path("libgstreal.so") - self.path("libgstrtp.so") - self.path("libgstrtpmanager.so") - self.path("libgstrtsp.so") - self.path("libgstsdpelem.so") - self.path("libgstselector.so") - self.path("libgststereo.so") - self.path("libgsttcp.so") - self.path("libgsttheora.so") - self.path("libgsttypefindfunctions.so") - self.path("libgstudp.so") - self.path("libgstvideobalance.so") - self.path("libgstvideobox.so") - self.path("libgstvideocrop.so") - self.path("libgstvideoflip.so") - self.path("libgstvideomixer.so") - self.path("libgstvideorate.so") - self.path("libgstvideoscale.so") - self.path("libgstvideosignal.so") - self.path("libgstvolume.so") - self.path("libgstvorbis.so") - self.path("libgstwavparse.so") + # if (not self.standalone()) and self.prefix(src="../../libraries/universal-darwin/lib_release/gstreamer-plugins", dst="lib/gstreamer-plugins"): + # self.path("libgstaacparse.so") + # self.path("libgstadder.so") + # self.path("libgstaiffparse.so") + # self.path("libgstamrparse.so") + # self.path("libgstapp.so") + # self.path("libgstaudioconvert.so") + # self.path("libgstaudiorate.so") + # self.path("libgstaudioresample.so") + # self.path("libgstautodetect.so") + # self.path("libgstavi.so") + # self.path("libgstcoreelements.so") + # self.path("libgstcoreindexers.so") + # self.path("libgstdebug.so") + # self.path("libgstdecodebin.so") + # self.path("libgstdecodebin2.so") + # self.path("libgstdeinterlace2.so") + # self.path("libgstequalizer.so") + # self.path("libgstfaad.so") + # self.path("libgstffmpeg.so") + # self.path("libgstffmpegcolorspace.so") + # self.path("libgstffmpegscale.so") + # self.path("libgstfilter.so") + # self.path("libgstflac.so") + # self.path("libgstflv.so") + # self.path("libgstgdp.so") + # self.path("libgsth264parse.so") + # self.path("libgsticydemux.so") + # self.path("libgstid3demux.so") + # self.path("libgstinterleave.so") + # self.path("libgstjpeg.so") + # self.path("libgstlevel.so") + # self.path("libgstmetadata.so") + # self.path("libgstmpeg4videoparse.so") + # self.path("libgstmpegdemux.so") + # self.path("libgstmpegvideoparse.so") + # self.path("libgstmultifile.so") + # self.path("libgstmultipart.so") + # self.path("libgstneonhttpsrc.so") + # self.path("libgstogg.so") + # self.path("libgstosxaudio.so") + # self.path("libgstosxvideosink.so") + # self.path("libgstplaybin.so") + # self.path("libgstpng.so") + # self.path("libgstpostproc.so") + # self.path("libgstqtdemux.so") + # #self.path("libgstqtwrapper.so") + # self.path("libgstqueue2.so") + # self.path("libgstreal.so") + # self.path("libgstrtp.so") + # self.path("libgstrtpmanager.so") + # self.path("libgstrtsp.so") + # self.path("libgstsdpelem.so") + # self.path("libgstselector.so") + # self.path("libgststereo.so") + # self.path("libgsttcp.so") + # self.path("libgsttheora.so") + # self.path("libgsttypefindfunctions.so") + # self.path("libgstudp.so") + # self.path("libgstvideobalance.so") + # self.path("libgstvideobox.so") + # self.path("libgstvideocrop.so") + # self.path("libgstvideoflip.so") + # self.path("libgstvideomixer.so") + # self.path("libgstvideorate.so") + # self.path("libgstvideoscale.so") + # self.path("libgstvideosignal.so") + # self.path("libgstvolume.so") + # self.path("libgstvorbis.so") + # self.path("libgstwavparse.so") - self.end_prefix("../../libraries/universal-darwin/lib_release/gstreamer-plugins") + # self.end_prefix("../../libraries/universal-darwin/lib_release/gstreamer-plugins") # SLVoice and vivox lols From ecec32deaff66550dd79b16104353ffee9a9039c Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 23:13:21 -0600 Subject: [PATCH 210/239] Fixed path to Mac SLPlugin launcher. --- linden/indra/llvfs/lldir_mac.cpp | 2 +- linden/indra/newview/viewer_manifest.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/indra/llvfs/lldir_mac.cpp b/linden/indra/llvfs/lldir_mac.cpp index 29cac58a0..6f0b0375f 100644 --- a/linden/indra/llvfs/lldir_mac.cpp +++ b/linden/indra/llvfs/lldir_mac.cpp @@ -393,7 +393,7 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const /*virtual*/ std::string LLDir_Mac::getLLPluginLauncher() { return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() + - "SLPlugin"; + "SLPlugin.app/Contents/MacOS/SLPlugin"; } /*virtual*/ std::string LLDir_Mac::getLLPluginFilename(std::string base_name) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index aa7450240..c9a2f7b81 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -784,7 +784,7 @@ def construct(self): # ) # plugin launcher - self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin") + self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") # plugins if self.prefix(src="", dst="llplugin"): From 521ba06c1f1f8058b6f72897a37d437bf6e7548c Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sat, 13 Nov 2010 23:20:23 -0600 Subject: [PATCH 211/239] Mac SLPlugin.app needs symlinks to some libs. --- linden/indra/newview/viewer_manifest.py | 33 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index c9a2f7b81..948e88ed5 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -771,17 +771,28 @@ def construct(self): # self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") # our apps dependencies on shared libs - # mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") - # mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") - # for libfile in ("libllcommon.dylib", - # "libapr-1.0.3.7.dylib", - # "libaprutil-1.0.3.8.dylib", - # "libexpat.0.5.0.dylib"): - # target_lib = os.path.join('../../..', libfile) - # self.run_command("ln -sf %(target)r %(link)r" % - # {'target': target_lib, - # 'link' : os.path.join(mac_crash_logger_res_path, libfile)} - # ) + if dylibs["llcommon"]: + # mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") + # mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") + slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") + for libfile in ("libllcommon.dylib", + "libapr-1.0.3.7.dylib", + "libaprutil-1.0.3.8.dylib", + "libexpat.0.5.0.dylib", + ): + target_lib = os.path.join('../../..', libfile) + # self.run_command("ln -sf %(target)r %(link)r" % + # {'target': target_lib, + # 'link' : os.path.join(mac_crash_logger_res_path, libfile)} + # ) + # self.run_command("ln -sf %(target)r %(link)r" % + # {'target': target_lib, + # 'link' : os.path.join(mac_updater_res_path, libfile)} + # ) + self.run_command("ln -sf %(target)r %(link)r" % + {'target': target_lib, + 'link' : os.path.join(slplugin_res_path, libfile)} + ) # plugin launcher self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") From 8eff9a80f57e6fc2149a97f818ec0330443715ca Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sun, 14 Nov 2010 01:53:28 -0600 Subject: [PATCH 212/239] Use proper install_name for Mac libllcommon. --- linden/indra/llcommon/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt index 5d590a9b9..ff1d54833 100644 --- a/linden/indra/llcommon/CMakeLists.txt +++ b/linden/indra/llcommon/CMakeLists.txt @@ -203,3 +203,12 @@ target_link_libraries( ${WINDOWS_LIBRARIES} ) +if (DARWIN) + # don't embed a full path in the library's install name + set_target_properties( + llcommon + PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path/../Resources" + ) +endif (DARWIN) From e888b19adc3d7293a4d69962ba0fdebeeeb01793 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli <jacek@imprudenceviewer.org> Date: Sun, 14 Nov 2010 02:04:26 -0600 Subject: [PATCH 213/239] Simplified install of libllcommon in Mac manifest. --- linden/indra/newview/viewer_manifest.py | 66 ++++++++----------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py index 948e88ed5..56c241048 100755 --- a/linden/indra/newview/viewer_manifest.py +++ b/linden/indra/newview/viewer_manifest.py @@ -740,63 +740,39 @@ def construct(self): #self.path("vivox-runtime/universal-darwin/SLVoiceAgent.app", "SLVoiceAgent.app") libdir = "../../libraries/universal-darwin/lib_release" - dylibs = {} - - #for lib in "llkdu", "llcommon": - for lib in "llcommon": - libfile = "lib%s.dylib" % lib - try: - self.path(self.find_existing_file(os.path.join(os.pardir, - lib, - self.args['configuration'], - libfile), - os.path.join(libdir, libfile)), - dst=libfile) - except RuntimeError: - print "Skipping %s" % libfile - dylibs[lib] = False - else: - dylibs[lib] = True + + self.path(os.path.join(os.pardir, + "llcommon", + self.args['configuration'], + "libllcommon.dylib"), + dst="libllcommon.dylib") + for libfile in ("libapr-1.0.3.7.dylib", "libaprutil-1.0.3.8.dylib", "libexpat.0.5.0.dylib"): self.path(os.path.join(libdir, libfile), libfile) - #libfmodwrapper.dylib - #self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib") - # our apps -# self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") + # self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") # self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") - # our apps dependencies on shared libs - if dylibs["llcommon"]: - # mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") - # mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") - slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") - for libfile in ("libllcommon.dylib", - "libapr-1.0.3.7.dylib", - "libaprutil-1.0.3.8.dylib", - "libexpat.0.5.0.dylib", - ): - target_lib = os.path.join('../../..', libfile) - # self.run_command("ln -sf %(target)r %(link)r" % - # {'target': target_lib, - # 'link' : os.path.join(mac_crash_logger_res_path, libfile)} - # ) - # self.run_command("ln -sf %(target)r %(link)r" % - # {'target': target_lib, - # 'link' : os.path.join(mac_updater_res_path, libfile)} - # ) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(slplugin_res_path, libfile)} - ) - # plugin launcher self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") + # symlinks for SLPlugin.app dependencies + slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") + for libfile in ("libllcommon.dylib", + "libapr-1.0.3.7.dylib", + "libaprutil-1.0.3.8.dylib", + "libexpat.0.5.0.dylib", + ): + target_lib = os.path.join('../../..', libfile) + self.run_command("ln -sf %(target)r %(link)r" % + {'target': target_lib, + 'link' : os.path.join(slplugin_res_path, libfile)} + ) + # plugins if self.prefix(src="", dst="llplugin"): self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib") From adb6155aa6d3d5161d2e11ec47a0f73527068c2d Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Sun, 14 Nov 2010 13:18:17 +0100 Subject: [PATCH 214/239] fetch pulseaudio headers also for linux64 --- linden/install.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/linden/install.xml b/linden/install.xml index 1df31e245..e536de2a5 100755 --- a/linden/install.xml +++ b/linden/install.xml @@ -1343,6 +1343,13 @@ Copyright (C) 2004-2005 Vladimir Berezniker @ http://public.xdi.org/=vmpn <key>url</key> <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/linux-pulse-headers-0.9.14.tar.bz2</uri> </map> + <key>linux64</key> + <map> + <key>md5sum</key> + <string>30cb00069fe2a545fbf7be1070386236</string> + <key>url</key> + <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/linux-pulse-headers-0.9.14.tar.bz2</uri> + </map> </map> </map> <key>quicktime</key> From 90df1597295861bbad0fff81cab039df389c1cd2 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 16 Nov 2010 17:44:51 +0100 Subject: [PATCH 215/239] IMP-577: Use the same string for FFSAVE_RAW as in strings.xml Apparently the code of Imprudence was from before this bug was introduced. Nevertheless, decided to add this one-liner so that the code becomes the same (in this regard) as snowglobe 1.x and (soon) viewer 2.x (see https://jira.secondlife.com/browse/STORM-423). --- linden/indra/newview/llfilepicker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp index a59fa0683..ec4e294a5 100644 --- a/linden/indra/newview/llfilepicker.cpp +++ b/linden/indra/newview/llfilepicker.cpp @@ -1181,7 +1181,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename break; case FFSAVE_RAW: caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.raw", LLTrans::getString("dot_raw_file") + " (*.raw)"); + (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); suggest_ext = ".raw"; break; case FFSAVE_J2C: From 9ce7c1e25abc7cac72183787ac2b079ca304cd0a Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 17 Nov 2010 01:00:18 +0100 Subject: [PATCH 216/239] IMP-712: Add shortcut for the Groups tab. Bind control-shift-G to Groups. This is also done in snowglobe. --- linden/doc/contributions.txt | 1 + linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index 41f896f36..6646a4024 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -91,6 +91,7 @@ Aleric Inglewood IMP-670 IMP-688 IMP-692 + IMP-712 Alissa Sabre VWR-81 VWR-83 diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 31e730a8a..01a5b6ee2 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -267,7 +267,8 @@ <on_check function="FloaterVisible" userdata="friends" /> </menu_item_check> - <menu_item_call name="Groups" label="Groups"> + <menu_item_call name="Groups" label="Groups" + shortcut="control|shift|G"> <on_click function="ShowAgentGroups" userdata="agent" /> </menu_item_call> From b66950bc26cfb3210e786c966141b20a5cc13a84 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 10 Nov 2010 15:19:13 +0100 Subject: [PATCH 217/239] IMP-590: Added a thread-safe and robust wrapper for APR pools. See http://redmine.imprudenceviewer.org/issues/590 --- linden/doc/contributions.txt | 1 + linden/indra/llcommon/CMakeLists.txt | 3 + linden/indra/llcommon/aiaprpool.cpp | 198 ++++++++++++ linden/indra/llcommon/aiaprpool.h | 236 ++++++++++++++ linden/indra/llcommon/llapp.cpp | 5 - linden/indra/llcommon/llapr.cpp | 299 +++--------------- linden/indra/llcommon/llapr.h | 74 +---- linden/indra/llcommon/llcommon.cpp | 13 - linden/indra/llcommon/llcommon.h | 2 - linden/indra/llcommon/llerror.cpp | 3 + linden/indra/llcommon/llfixedbuffer.cpp | 3 +- .../indra/llcommon/llscopedvolatileaprpool.h | 58 ++++ linden/indra/llcommon/llthread.cpp | 117 ++++--- linden/indra/llcommon/llthread.h | 88 +++++- linden/indra/llcommon/llworkerthread.cpp | 3 +- linden/indra/llcommon/llworkerthread.h | 2 +- linden/indra/llcrashlogger/llcrashlogger.cpp | 3 +- linden/indra/llimage/llimage.cpp | 2 +- linden/indra/llimage/llimagej2c.cpp | 15 +- linden/indra/llimage/llimageworker.cpp | 7 +- linden/indra/llimage/llimageworker.h | 2 +- linden/indra/llmath/llvolumemgr.cpp | 4 +- linden/indra/llmessage/llares.cpp | 17 +- linden/indra/llmessage/llcurl.cpp | 2 +- linden/indra/llmessage/lliohttpserver.cpp | 10 +- linden/indra/llmessage/lliohttpserver.h | 2 +- linden/indra/llmessage/lliosocket.cpp | 99 +++--- linden/indra/llmessage/lliosocket.h | 33 +- linden/indra/llmessage/llmail.cpp | 17 +- linden/indra/llmessage/llmail.h | 4 +- linden/indra/llmessage/llpumpio.cpp | 74 ++--- linden/indra/llmessage/llpumpio.h | 31 +- linden/indra/llmessage/llurlrequest.cpp | 25 +- linden/indra/llmessage/message.cpp | 17 +- linden/indra/llplugin/llplugininstance.cpp | 5 +- linden/indra/llplugin/llpluginmessagepipe.cpp | 2 - .../indra/llplugin/llpluginprocesschild.cpp | 2 +- .../indra/llplugin/llpluginprocessparent.cpp | 55 ++-- linden/indra/llplugin/llpluginprocessparent.h | 2 + .../indra/llplugin/llpluginsharedmemory.cpp | 9 +- linden/indra/llplugin/llpluginsharedmemory.h | 3 + linden/indra/llplugin/slplugin/slplugin.cpp | 4 - linden/indra/llvfs/llvfs.cpp | 2 +- .../webkit/linux_volume_catcher.cpp | 14 +- linden/indra/newview/llappviewer.cpp | 2 +- linden/indra/newview/llappviewerlinux.cpp | 1 + linden/indra/newview/llappviewermacosx.cpp | 1 + linden/indra/newview/lltexturecache.cpp | 5 +- linden/indra/newview/lltexturecache.h | 3 - linden/indra/newview/lltexturefetch.cpp | 3 - .../newview/llviewerprecompiledheaders.h | 2 +- linden/indra/newview/llvoiceclient.cpp | 2 +- linden/indra/newview/llwatchdog.cpp | 4 +- .../test/lltemplatemessagebuilder_tut.cpp | 2 - linden/indra/test/message_tut.cpp | 2 - linden/indra/test/test.cpp | 16 +- 56 files changed, 878 insertions(+), 732 deletions(-) create mode 100644 linden/indra/llcommon/aiaprpool.cpp create mode 100644 linden/indra/llcommon/aiaprpool.h create mode 100644 linden/indra/llcommon/llscopedvolatileaprpool.h diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index 6646a4024..c8dd7735c 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -80,6 +80,7 @@ Aleric Inglewood IMP-578 IMP-579 IMP-581 + IMP-590 IMP-592 IMP-595 IMP-660 diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt index 5d590a9b9..a05ee6f85 100644 --- a/linden/indra/llcommon/CMakeLists.txt +++ b/linden/indra/llcommon/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories( ) set(llcommon_SOURCE_FILES + aiaprpool.cpp imageids.cpp indra_constants.cpp llapp.cpp @@ -74,6 +75,7 @@ set(llcommon_SOURCE_FILES set(llcommon_HEADER_FILES CMakeLists.txt + aiaprpool.h bitpack.h ctype_workaround.h doublelinkedlist.h @@ -147,6 +149,7 @@ set(llcommon_HEADER_FILES llqueuedthread.h llrand.h llrun.h + llscopedvolatileaprpool.h llsd.h llsdserialize.h llsdserialize_xml.h diff --git a/linden/indra/llcommon/aiaprpool.cpp b/linden/indra/llcommon/aiaprpool.cpp new file mode 100644 index 000000000..d3748e983 --- /dev/null +++ b/linden/indra/llcommon/aiaprpool.cpp @@ -0,0 +1,198 @@ +/** + * @file aiaprpool.cpp + * + * Copyright (c) 2010, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 04/04/2010 + * - Initial version, written by Aleric Inglewood @ SL + * + * 10/11/2010 + * - Changed filename, class names and license to a more + * company-neutral format. + * - Added APR_HAS_THREADS #if's to allow creation and destruction + * of subpools by threads other than the parent pool owner. + */ + +#include "linden_common.h" + +#include "llerror.h" +#include "aiaprpool.h" +#include "llthread.h" + +// Create a subpool from parent. +void AIAPRPool::create(AIAPRPool& parent) +{ + llassert(!mPool); // Must be non-initialized. + mParent = &parent; + if (!mParent) // Using the default parameter? + { + // By default use the root pool of the current thread. + mParent = &AIThreadLocalData::tldata().mRootPool; + } + llassert(mParent->mPool); // Parent must be initialized. +#if APR_HAS_THREADS + // As per the documentation of APR (ie http://apr.apache.org/docs/apr/1.4/apr__pools_8h.html): + // + // Note that most operations on pools are not thread-safe: a single pool should only be + // accessed by a single thread at any given time. The one exception to this rule is creating + // a subpool of a given pool: one or more threads can safely create subpools at the same + // time that another thread accesses the parent pool. + // + // In other words, it's safe for any thread to create a (sub)pool, independent of who + // owns the parent pool. + mOwner = apr_os_thread_current(); +#else + mOwner = mParent->mOwner; + llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); +#endif + apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool); + llassert_always(apr_pool_create_status == APR_SUCCESS); + llassert(mPool); // Initialized. + apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null); +} + +// Destroy the (sub)pool, if any. +void AIAPRPool::destroy(void) +{ + // Only do anything if we are not already (being) destroyed. + if (mPool) + { +#if !APR_HAS_THREADS + // If we are a root pool, then every thread may destruct us: in that case + // we have to assume that no other thread will use this pool concurrently, + // of course. Otherwise, if we are a subpool, only the thread that owns + // the parent may destruct us, since that is the pool that is still alive, + // possibly being used by others and being altered here. + llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current())); +#endif + apr_pool_t* pool = mPool; + mPool = NULL; // Mark that we are BEING destructed. + apr_pool_cleanup_kill(pool, this, &s_plain_cleanup); + apr_pool_destroy(pool); + } +} + +bool AIAPRPool::parent_is_being_destructed(void) +{ + return mParent && (!mParent->mPool || mParent->parent_is_being_destructed()); +} + +AIAPRInitialization::AIAPRInitialization(void) +{ + static bool apr_initialized = false; + + if (!apr_initialized) + { + apr_initialize(); + } + + apr_initialized = true; +} + +bool AIAPRRootPool::sCountInitialized = false; +apr_uint32_t volatile AIAPRRootPool::sCount; + +extern apr_thread_mutex_t* gLogMutexp; +extern apr_thread_mutex_t* gCallStacksLogMutexp; + +AIAPRRootPool::AIAPRRootPool(void) : AIAPRInitialization(), AIAPRPool(0) +{ + // sCountInitialized don't need locking because when we get here there is still only a single thread. + if (!sCountInitialized) + { + // Initialize the logging mutex + apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool); + apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool); + + apr_status_t status = apr_atomic_init(mPool); + llassert_always(status == APR_SUCCESS); + apr_atomic_set32(&sCount, 1); // Set to 1 to account for the global root pool. + sCountInitialized = true; + + // Initialize thread-local APR pool support. + // Because this recursively calls AIAPRRootPool::AIAPRRootPool(void) + // it must be done last, so that sCount is already initialized. + AIThreadLocalData::init(); + } + apr_atomic_inc32(&sCount); +} + +AIAPRRootPool::~AIAPRRootPool() +{ + if (!apr_atomic_dec32(&sCount)) + { + // The last pool was destructed. Cleanup remainder of APR. + LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; + + if (gLogMutexp) + { + // Clean up the logging mutex + + // All other threads NEED to be done before we clean up APR, so this is okay. + apr_thread_mutex_destroy(gLogMutexp); + gLogMutexp = NULL; + } + if (gCallStacksLogMutexp) + { + // Clean up the logging mutex + + // All other threads NEED to be done before we clean up APR, so this is okay. + apr_thread_mutex_destroy(gCallStacksLogMutexp); + gCallStacksLogMutexp = NULL; + } + + // Must destroy ALL, and therefore this last AIAPRRootPool, before terminating APR. + static_cast<AIAPRRootPool*>(this)->destroy(); + + apr_terminate(); + } +} + +//static +AIAPRRootPool& AIAPRRootPool::get(void) +{ + static AIAPRRootPool global_APRpool(0); // This is what used to be gAPRPoolp. + return global_APRpool; +} + +void AIVolatileAPRPool::clearVolatileAPRPool() +{ + llassert_always(mNumActiveRef > 0); + if (--mNumActiveRef == 0) + { + if (isOld()) + { + destroy(); + mNumTotalRef = 0 ; + } + else + { + // This does not actually free the memory, + // it just allows the pool to re-use this memory for the next allocation. + clear(); + } + } + + // Paranoia check if the pool is jammed. + llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; +} diff --git a/linden/indra/llcommon/aiaprpool.h b/linden/indra/llcommon/aiaprpool.h new file mode 100644 index 000000000..f6d7ffa1d --- /dev/null +++ b/linden/indra/llcommon/aiaprpool.h @@ -0,0 +1,236 @@ +/** + * @file aiaprpool.h + * @brief Implementation of AIAPRPool. + * + * Copyright (c) 2010, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 04/04/2010 + * - Initial version, written by Aleric Inglewood @ SL + * + * 10/11/2010 + * - Changed filename, class names and license to a more + * company-neutral format. + * - Added APR_HAS_THREADS #if's to allow creation and destruction + * of subpools by threads other than the parent pool owner. + */ + +#ifndef AIAPRPOOL_H +#define AIAPRPOOL_H + +#ifdef LL_WINDOWS +#include <ws2tcpip.h> // Needed before including apr_portable.h +#endif + +#include "apr_portable.h" +#include "apr_pools.h" +#include "llerror.h" + +extern void ll_init_apr(); + +/** + * @brief A wrapper around the APR memory pool API. + * + * Usage of this class should be restricted to passing it to libapr-1 function calls that need it. + * + */ +class LL_COMMON_API AIAPRPool +{ +protected: + apr_pool_t* mPool; //!< Pointer to the underlaying pool. NULL if not initialized. + AIAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero. + apr_os_thread_t mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero. + +public: + //! Construct an uninitialized (destructed) pool. + AIAPRPool(void) : mPool(NULL) { } + + //! Construct a subpool from an existing pool. + // This is not a copy-constructor, this class doesn't have one! + AIAPRPool(AIAPRPool& parent) : mPool(NULL) { create(parent); } + + //! Destruct the memory pool (free all of it's subpools and allocated memory). + ~AIAPRPool() { destroy(); } + +protected: + // Create a pool that is allocated from the Operating System. Only used by AIAPRRootPool. + AIAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current()) + { + apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL); + llassert_always(apr_pool_create_status == APR_SUCCESS); + llassert(mPool); + apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null); + } + +public: + //! Create a subpool from parent. May only be called for an uninitialized/destroyed pool. + // The default parameter causes the root pool of the current thread to be used. + void create(AIAPRPool& parent = *static_cast<AIAPRPool*>(NULL)); + + //! Destroy the (sub)pool, if any. + void destroy(void); + + // Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool. + typedef apr_pool_t* const AIAPRPool::* const bool_type; + //! Return true if the pool is initialized. + operator bool_type() const { return mPool ? &AIAPRPool::mPool : 0; } + + // Painful, but we have to either provide access to this, or wrap + // every APR function call that needs a apr_pool_t* to be passed. + // NEVER destroy a pool that is returned by this function! + apr_pool_t* operator()(void) const + { + llassert(mPool); + llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); + return mPool; + } + + // Free all memory without destructing the pool. + void clear(void) + { + llassert(mPool); + llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); + apr_pool_clear(mPool); + } + +// These methods would make this class 'complete' (as wrapper around the libapr +// pool functions), but we don't use memory pools in the viewer (only when +// we are forced to pass one to a libapr call), so don't define them in order +// not to encourage people to use them. +#if 0 + void* palloc(size_t size) + { + llassert(mPool); + llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); + return apr_palloc(mPool, size); + } + void* pcalloc(size_t size) + { + llassert(mPool); + llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); + return apr_pcalloc(mPool, size); + } +#endif + +private: + bool parent_is_being_destructed(void); + static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<AIAPRPool*>(userdata)->plain_cleanup(); } + + apr_status_t plain_cleanup(void) + { + if (mPool && // We are not being destructed, + parent_is_being_destructed()) // but our parent is. + // This means the pool is being destructed recursively by libapr + // because one of it's parents is being destructed. + { + mPool = NULL; // Stop destroy() from destructing the pool again. + } + return APR_SUCCESS; + } +}; + +class AIAPRInitialization +{ +public: + AIAPRInitialization(void); +}; + +/** + * @brief Root memory pool (allocates memory from the operating system). + * + * This class should only be used by AIThreadLocalData (and LLMutexRootPool + * when APR_HAS_THREADS isn't defined). + */ +class LL_COMMON_API AIAPRRootPool : public AIAPRInitialization, public AIAPRPool +{ +private: + friend class AIThreadLocalData; +#if !APR_HAS_THREADS + friend class LLMutexRootPool; +#endif + //! Construct a root memory pool. Should only be used by AIThreadLocalData. + AIAPRRootPool(void); + ~AIAPRRootPool(); + +private: + // Keep track of how many root pools exist and when the last one is destructed. + static bool sCountInitialized; + static apr_uint32_t volatile sCount; + +public: + // Return a global root pool that is independent of AIThreadLocalData. + // Normally you should not use this. Only use for early initialization + // (before main) and deinitialization (after main). + static AIAPRRootPool& get(void); + +#if APR_POOL_DEBUG + void grab_ownership(void) + { + // You need a patched libapr to use this. + // See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI + apr_pool_owner_set(mPool); + } +#endif + +private: + // Used for constructing the Special Global Root Pool (returned by AIAPRRootPool::get). + // It is the same as the default constructor but omits to increment sCount. As a result, + // we must be sure that at least one other AIAPRRootPool is created before termination + // of the application (which is the case: we create one AIAPRRootPool per thread). + AIAPRRootPool(int) : AIAPRInitialization(), AIAPRPool(0) { } +}; + +//! Volatile memory pool +// +// 'Volatile' APR memory pool which normally only clears memory, +// and does not destroy the pool (the same pool is reused) for +// greater efficiency. However, as a safe guard the apr pool +// is destructed every FULL_VOLATILE_APR_POOL uses to allow +// the system memory to be allocated more efficiently and not +// get scattered through RAM. +// +class LL_COMMON_API AIVolatileAPRPool : protected AIAPRPool +{ +public: + AIVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { } + + apr_pool_t* getVolatileAPRPool(void) + { + if (!mPool) create(); + ++mNumActiveRef; + ++mNumTotalRef; + return AIAPRPool::operator()(); + } + void clearVolatileAPRPool(void); + + bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; } + bool isUnused() const { return mNumActiveRef == 0; } + +private: + S32 mNumActiveRef; // Number of active uses of the pool. + S32 mNumTotalRef; // Number of total uses of the pool since last creation. + + // Maximum number of references to AIVolatileAPRPool until the pool is recreated. + static S32 const FULL_VOLATILE_APR_POOL = 1024; +}; + +#endif // AIAPRPOOL_H diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp index e269f59d6..eedc50316 100644 --- a/linden/indra/llcommon/llapp.cpp +++ b/linden/indra/llcommon/llapp.cpp @@ -119,13 +119,8 @@ void LLApp::commonCtor() mOptions.append(sd); } - // Make sure we clean up APR when we exit - // Don't need to do this if we're cleaning up APR in the destructor - //atexit(ll_cleanup_apr); - // Set the application to this instance. sApplication = this; - } LLApp::LLApp(LLErrorThread *error_thread) : diff --git a/linden/indra/llcommon/llapr.cpp b/linden/indra/llcommon/llapr.cpp index 7e3a26c0d..a013d9c6c 100644 --- a/linden/indra/llcommon/llapr.cpp +++ b/linden/indra/llcommon/llapr.cpp @@ -34,220 +34,7 @@ #include "linden_common.h" #include "llapr.h" - -apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool -apr_thread_mutex_t *gLogMutexp = NULL; -apr_thread_mutex_t *gCallStacksLogMutexp = NULL; - -const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool - -void ll_init_apr() -{ - if (!gAPRPoolp) - { - // Initialize APR and create the global pool - apr_initialize(); - apr_pool_create(&gAPRPoolp, NULL); - - // Initialize the logging mutex - apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); - apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); - - // Initialize thread-local APR pool support. - LLVolatileAPRPool::initLocalAPRFilePool(); - } -} - - -void ll_cleanup_apr() -{ - LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; - - if (gLogMutexp) - { - // Clean up the logging mutex - - // All other threads NEED to be done before we clean up APR, so this is okay. - apr_thread_mutex_destroy(gLogMutexp); - gLogMutexp = NULL; - } - if (gCallStacksLogMutexp) - { - // Clean up the logging mutex - - // All other threads NEED to be done before we clean up APR, so this is okay. - apr_thread_mutex_destroy(gCallStacksLogMutexp); - gCallStacksLogMutexp = NULL; - } - if (gAPRPoolp) - { - apr_pool_destroy(gAPRPoolp); - gAPRPoolp = NULL; - } - apr_terminate(); -} - -// -// -//LLAPRPool -// -LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) -{ - mParent = parent ; - mReleasePoolFlag = releasePoolFlag ; - mMaxSize = size ; - mPool = NULL ; - - createAPRPool() ; -} - -LLAPRPool::~LLAPRPool() -{ - releaseAPRPool() ; -} - -void LLAPRPool::createAPRPool() -{ - if(mPool) - { - return ; - } - - mStatus = apr_pool_create(&mPool, mParent); - ll_apr_warn_status(mStatus) ; - - if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes. - { - apr_allocator_t *allocator = apr_pool_allocator_get(mPool); - if (allocator) - { - apr_allocator_max_free_set(allocator, mMaxSize) ; - } - } -} - -void LLAPRPool::releaseAPRPool() -{ - if(!mPool) - { - return ; - } - - if(!mParent || mReleasePoolFlag) - { - apr_pool_destroy(mPool) ; - mPool = NULL ; - } -} - -apr_pool_t* LLAPRPool::getAPRPool() -{ - if(!mPool) - { - createAPRPool() ; - } - - return mPool ; -} -LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) - : LLAPRPool(parent, size, releasePoolFlag) -{ - mNumActiveRef = 0 ; - mNumTotalRef = 0 ; -} - -apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() -{ - mNumTotalRef++ ; - mNumActiveRef++ ; - return getAPRPool() ; -} - -void LLVolatileAPRPool::clearVolatileAPRPool() -{ - if(mNumActiveRef > 0) - { - mNumActiveRef--; - if(mNumActiveRef < 1) - { - if(isFull()) - { - mNumTotalRef = 0 ; - - //destroy the apr_pool. - releaseAPRPool() ; - } - else - { - //This does not actually free the memory, - //it just allows the pool to re-use this memory for the next allocation. - apr_pool_clear(mPool) ; - } - } - } - else - { - llassert_always(mNumActiveRef > 0) ; - } - - //paranoia check if the pool is jammed. - //will remove the check before going to release. - llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; -} - -BOOL LLVolatileAPRPool::isFull() -{ - return mNumTotalRef > FULL_VOLATILE_APR_POOL ; -} - -#ifdef SHOW_ASSERT -// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. -static void* gIsMainThread; -bool is_main_thread() { return gIsMainThread == LLVolatileAPRPool::getLocalAPRFilePool(); } -#endif - -// The thread private handle to access the LocalAPRFilePool. -apr_threadkey_t* LLVolatileAPRPool::sLocalAPRFilePoolKey; - -// This should be called exactly once, before the first call to createLocalAPRFilePool. -// static -void LLVolatileAPRPool::initLocalAPRFilePool() -{ - apr_status_t status = apr_threadkey_private_create(&sLocalAPRFilePoolKey, &destroyLocalAPRFilePool, gAPRPoolp); - ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the - // total number of keys per process {PTHREAD_KEYS_MAX} - // has been exceeded. - // Create the thread-local pool for the main thread (this function is called by the main thread). - createLocalAPRFilePool(); -#ifdef SHOW_ASSERT - gIsMainThread = getLocalAPRFilePool(); -#endif -} - -// This should be called once for every thread, before it uses getLocalAPRFilePool. -// static -void LLVolatileAPRPool::createLocalAPRFilePool() -{ - void* thread_local_data = new LLVolatileAPRPool; - apr_status_t status = apr_threadkey_private_set(thread_local_data, sLocalAPRFilePoolKey); - llassert_always(status == APR_SUCCESS); -} - -// This is called once for every thread when the thread is destructed. -// static -void LLVolatileAPRPool::destroyLocalAPRFilePool(void* thread_local_data) -{ - delete reinterpret_cast<LLVolatileAPRPool*>(thread_local_data); -} - -// static -LLVolatileAPRPool* LLVolatileAPRPool::getLocalAPRFilePool() -{ - void* thread_local_data; - apr_status_t status = apr_threadkey_private_get(&thread_local_data, sLocalAPRFilePoolKey); - llassert_always(status == APR_SUCCESS); - return reinterpret_cast<LLVolatileAPRPool*>(thread_local_data); -} +#include "llscopedvolatileaprpool.h" //--------------------------------------------------------------------- // @@ -310,13 +97,15 @@ void ll_apr_assert_status(apr_status_t status) // LLAPRFile::LLAPRFile() : mFile(NULL), - mCurrentFilePoolp(NULL) + mVolatileFilePoolp(NULL), + mRegularFilePoolp(NULL) { } LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type) : mFile(NULL), - mCurrentFilePoolp(NULL) + mVolatileFilePoolp(NULL), + mRegularFilePoolp(NULL) { open(filename, flags, access_type); } @@ -335,10 +124,16 @@ apr_status_t LLAPRFile::close() mFile = NULL ; } - if(mCurrentFilePoolp) + if (mVolatileFilePoolp) { - mCurrentFilePoolp->clearVolatileAPRPool() ; - mCurrentFilePoolp = NULL ; + mVolatileFilePoolp->clearVolatileAPRPool() ; + mVolatileFilePoolp = NULL ; + } + + if (mRegularFilePoolp) + { + delete mRegularFilePoolp; + mRegularFilePoolp = NULL; } return ret ; @@ -347,25 +142,28 @@ apr_status_t LLAPRFile::close() apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep) { llassert_always(!mFile); - llassert_always(!mCurrentFilePoolp); + llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp); - // Access the pool and increment it's reference count. - // The reference count of LLVolatileAPRPool objects will be decremented - // again in LLAPRFile::close by calling mCurrentFilePoolp->clearVolatileAPRPool(). - apr_pool_t* pool; - if (access_type == local) - { - // Use a "volatile" thread-local pool. - mCurrentFilePoolp = LLVolatileAPRPool::getLocalAPRFilePool(); - pool = mCurrentFilePoolp->getVolatileAPRPool(); - } - else + apr_status_t status; { - llassert(is_main_thread()); - pool = gAPRPoolp; + apr_pool_t* apr_file_open_pool; + if (access_type == local) + { + // Use a "volatile" thread-local pool. + mVolatileFilePoolp = &AIThreadLocalData::tldata().mVolatileAPRPool; + // Access the pool and increment it's reference count. + // The reference count of AIVolatileAPRPool objects will be decremented + // again in LLAPRFile::close by calling mVolatileFilePoolp->clearVolatileAPRPool(). + apr_file_open_pool = mVolatileFilePoolp->getVolatileAPRPool(); + } + else + { + mRegularFilePoolp = new AIAPRPool(AIThreadLocalData::tldata().mRootPool); + apr_file_open_pool = (*mRegularFilePoolp)(); + } + status = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, apr_file_open_pool); } - apr_status_t s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, pool); - if (s != APR_SUCCESS || !mFile) + if (status != APR_SUCCESS || !mFile) { mFile = NULL ; close() ; @@ -373,7 +171,7 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc { *sizep = 0; } - return s; + return status; } if (sizep) @@ -390,7 +188,7 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc *sizep = file_size; } - return s; + return status; } // File I/O @@ -440,17 +238,6 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) //static components of LLAPRFile // -// Used in the static functions below. -class LLScopedVolatileAPRFilePool { -private: - LLVolatileAPRPool* mPool; - apr_pool_t* apr_pool; -public: - LLScopedVolatileAPRFilePool() : mPool(LLVolatileAPRPool::getLocalAPRFilePool()), apr_pool(mPool->getVolatileAPRPool()) { } - ~LLScopedVolatileAPRFilePool() { mPool->clearVolatileAPRPool(); } - operator apr_pool_t*() const { return apr_pool; } -}; - //static S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) { @@ -487,7 +274,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) { apr_file_t* file_handle; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool); if (s != APR_SUCCESS || !file_handle) { @@ -539,7 +326,7 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n } apr_file_t* file_handle; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); if (s != APR_SUCCESS || !file_handle) { @@ -584,7 +371,7 @@ bool LLAPRFile::remove(const std::string& filename) { apr_status_t s; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; s = apr_file_remove(filename.c_str(), pool); if (s != APR_SUCCESS) @@ -601,7 +388,7 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname) { apr_status_t s; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; s = apr_file_rename(filename.c_str(), newname.c_str(), pool); if (s != APR_SUCCESS) @@ -619,7 +406,7 @@ bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags) apr_file_t* file_handle; apr_status_t s; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); if (s != APR_SUCCESS || !file_handle) @@ -640,7 +427,7 @@ S32 LLAPRFile::size(const std::string& filename) apr_finfo_t info; apr_status_t s; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool); if (s != APR_SUCCESS || !file_handle) @@ -669,7 +456,7 @@ bool LLAPRFile::makeDir(const std::string& dirname) { apr_status_t s; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); if (s != APR_SUCCESS) @@ -686,7 +473,7 @@ bool LLAPRFile::removeDir(const std::string& dirname) { apr_status_t s; - LLScopedVolatileAPRFilePool pool; + LLScopedVolatileAPRPool pool; s = apr_file_remove(dirname.c_str(), pool); if (s != APR_SUCCESS) diff --git a/linden/indra/llcommon/llapr.h b/linden/indra/llcommon/llapr.h index 2aed51511..ded15f531 100644 --- a/linden/indra/llcommon/llapr.h +++ b/linden/indra/llcommon/llapr.h @@ -48,73 +48,8 @@ #include "apr_atomic.h" #include "llstring.h" -extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; - -/** - * @brief initialize the common apr constructs -- apr itself, the - * global pool, and a mutex. - */ -void LL_COMMON_API ll_init_apr(); - -/** - * @brief Cleanup those common apr constructs. - */ -void LL_COMMON_API ll_cleanup_apr(); - -// -//LL apr_pool -//manage apr_pool_t, destroy allocated apr_pool in the destruction function. -// -class LL_COMMON_API LLAPRPool -{ -public: - LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ; - ~LLAPRPool() ; - - apr_pool_t* getAPRPool() ; - apr_status_t getStatus() {return mStatus ; } - -protected: - void releaseAPRPool() ; - void createAPRPool() ; - -protected: - apr_pool_t* mPool ; //pointing to an apr_pool - apr_pool_t* mParent ; //parent pool - apr_size_t mMaxSize ; //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work. - apr_status_t mStatus ; //status when creating the pool - BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true. -}; - -// -//volatile LL apr_pool -//which clears memory automatically. -//so it can not hold static data or data after memory is cleared -// -class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool -{ -public: - LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); - ~LLVolatileAPRPool(){} - - apr_pool_t* getVolatileAPRPool() ; - - void clearVolatileAPRPool() ; - - BOOL isFull() ; - BOOL isEmpty() {return !mNumActiveRef ;} - - static void initLocalAPRFilePool(); - static void createLocalAPRFilePool(); - static void destroyLocalAPRFilePool(void* thread_local_data); - static LLVolatileAPRPool* getLocalAPRFilePool(); - -private: - S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. - S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. - - static apr_threadkey_t* sLocalAPRFilePoolKey; -} ; +class AIAPRPool; +class AIVolatileAPRPool; /** * @class LLScopedLock @@ -205,7 +140,8 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable // make this non copyable since a copy closes the file private: apr_file_t* mFile ; - LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. + AIVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use. + AIAPRPool* mRegularFilePoolp; // ...or a regular pool. public: enum access_t { @@ -260,6 +196,4 @@ bool LL_COMMON_API ll_apr_warn_status(apr_status_t status); void LL_COMMON_API ll_apr_assert_status(apr_status_t status); -extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool - #endif // LL_LLAPR_H diff --git a/linden/indra/llcommon/llcommon.cpp b/linden/indra/llcommon/llcommon.cpp index 2cbb71855..298dd4695 100644 --- a/linden/indra/llcommon/llcommon.cpp +++ b/linden/indra/llcommon/llcommon.cpp @@ -34,18 +34,10 @@ #include "llcommon.h" #include "llthread.h" -//static -BOOL LLCommon::sAprInitialized = FALSE; - //static void LLCommon::initClass() { LLMemory::initClass(); - if (!sAprInitialized) - { - ll_init_apr(); - sAprInitialized = TRUE; - } LLTimer::initClass(); LLThreadSafeRefCount::initThreadSafeRefCount(); // LLWorkerThread::initClass(); @@ -59,10 +51,5 @@ void LLCommon::cleanupClass() // LLWorkerThread::cleanupClass(); LLThreadSafeRefCount::cleanupThreadSafeRefCount(); LLTimer::cleanupClass(); - if (sAprInitialized) - { - ll_cleanup_apr(); - sAprInitialized = FALSE; - } LLMemory::cleanupClass(); } diff --git a/linden/indra/llcommon/llcommon.h b/linden/indra/llcommon/llcommon.h index 851d4ac2d..300ebe2b2 100644 --- a/linden/indra/llcommon/llcommon.h +++ b/linden/indra/llcommon/llcommon.h @@ -43,8 +43,6 @@ class LL_COMMON_API LLCommon public: static void initClass(); static void cleanupClass(); -private: - static BOOL sAprInitialized; }; #endif diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp index edc570f34..b9be3708d 100644 --- a/linden/indra/llcommon/llerror.cpp +++ b/linden/indra/llcommon/llerror.cpp @@ -871,6 +871,9 @@ You get: */ +apr_thread_mutex_t* gLogMutexp; +apr_thread_mutex_t* gCallStacksLogMutexp; + namespace { bool checkLevelMap(const LevelMap& map, const std::string& key, LLError::ELevel& level) diff --git a/linden/indra/llcommon/llfixedbuffer.cpp b/linden/indra/llcommon/llfixedbuffer.cpp index e9d602937..37a12add8 100644 --- a/linden/indra/llcommon/llfixedbuffer.cpp +++ b/linden/indra/llcommon/llfixedbuffer.cpp @@ -33,9 +33,8 @@ #include "llfixedbuffer.h" LLFixedBuffer::LLFixedBuffer(const U32 max_lines) - : mMutex(NULL) + : mMaxLines(max_lines) { - mMaxLines = max_lines; mTimer.reset(); } diff --git a/linden/indra/llcommon/llscopedvolatileaprpool.h b/linden/indra/llcommon/llscopedvolatileaprpool.h new file mode 100644 index 000000000..724dc7f05 --- /dev/null +++ b/linden/indra/llcommon/llscopedvolatileaprpool.h @@ -0,0 +1,58 @@ +/** + * @file llscopedvolatileaprpool.h + * @brief Implementation of LLScopedVolatileAPRPool + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSCOPEDVOLATILEAPRPOOL_H +#define LL_LLSCOPEDVOLATILEAPRPOOL_H + +#include "llthread.h" + +//! Scoped volatile memory pool. +// +// As the AIVolatileAPRPool should never keep allocations very +// long, it's most common use is for allocations with a lifetime +// equal to it's scope. +// +// This is a convenience class that makes just a little easier to type. +// +class LLScopedVolatileAPRPool +{ +private: + AIVolatileAPRPool& mPool; + apr_pool_t* mScopedAPRpool; +public: + LLScopedVolatileAPRPool() : mPool(AIThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { } + ~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); } + // Only use this to pass the pointer to a libapr-1 function that requires it. + operator apr_pool_t*() const { return mScopedAPRpool; } +}; + +#endif diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp index 692d6c44f..f7732cb6a 100644 --- a/linden/indra/llcommon/llthread.cpp +++ b/linden/indra/llcommon/llthread.cpp @@ -72,8 +72,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // Set thread state to running threadp->mStatus = RUNNING; - // Create a thread local APRFile pool. - LLVolatileAPRPool::createLocalAPRFilePool(); + // Create a thread local data. + AIThreadLocalData::create(threadp); // Run the user supplied function threadp->run(); @@ -87,24 +87,14 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap } -LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : +LLThread::LLThread(std::string const& name) : mPaused(false), mName(name), mAPRThreadp(NULL), - mStatus(STOPPED) + mStatus(STOPPED), + mThreadLocalData(NULL) { - // Thread creation probably CAN be paranoid about APR being initialized, if necessary - if (poolp) - { - mIsLocalPool = false; - mAPRPoolp = poolp; - } - else - { - mIsLocalPool = true; - apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread - } - mRunCondition = new LLCondition(mAPRPoolp); + mRunCondition = new LLCondition; } @@ -147,24 +137,18 @@ void LLThread::shutdown() if (!isStopped()) { // This thread just wouldn't stop, even though we gave it time - llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl; + llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl; return; } mAPRThreadp = NULL; } delete mRunCondition; - - if (mIsLocalPool) - { - apr_pool_destroy(mAPRPoolp); - } } - void LLThread::start() { - apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); + apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool()); // We won't bother joining apr_thread_detach(mAPRThreadp); @@ -265,38 +249,72 @@ void LLThread::wakeLocked() } } -//============================================================================ +#ifdef SHOW_ASSERT +// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. +static apr_os_thread_t main_thread_id; +bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } +#endif -LLMutex::LLMutex(apr_pool_t *poolp) : - mAPRMutexp(NULL) +// The thread private handle to access the AIThreadLocalData instance. +apr_threadkey_t* AIThreadLocalData::sThreadLocalDataKey; + +//static +void AIThreadLocalData::init(void) { - //if (poolp) - //{ - // mIsLocalPool = false; - // mAPRPoolp = poolp; - //} - //else + // Only do this once. + if (sThreadLocalDataKey) { - mIsLocalPool = true; - apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread + return; } - apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); + + apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &AIThreadLocalData::destroy, AIAPRRootPool::get()()); + ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the + // total number of keys per process {PTHREAD_KEYS_MAX} + // has been exceeded. + + // Create the thread-local data for the main thread (this function is called by the main thread). + AIThreadLocalData::create(NULL); + +#ifdef SHOW_ASSERT + // This function is called by the main thread. + main_thread_id = apr_os_thread_current(); +#endif } -LLMutex::~LLMutex() +// This is called once for every thread when the thread is destructed. +//static +void AIThreadLocalData::destroy(void* thread_local_data) { -#if _DEBUG - llassert(!isLocked()); // better not be locked! -#endif - apr_thread_mutex_destroy(mAPRMutexp); - mAPRMutexp = NULL; - if (mIsLocalPool) + delete reinterpret_cast<AIThreadLocalData*>(thread_local_data); +} + +//static +void AIThreadLocalData::create(LLThread* threadp) +{ + AIThreadLocalData* new_tld = new AIThreadLocalData; + if (threadp) { - apr_pool_destroy(mAPRPoolp); + threadp->mThreadLocalData = new_tld; } + apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey); + llassert_always(status == APR_SUCCESS); } -bool LLMutex::isLocked() +//static +AIThreadLocalData& AIThreadLocalData::tldata(void) +{ + if (!sThreadLocalDataKey) + AIThreadLocalData::init(); + + void* data; + apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey); + llassert_always(status == APR_SUCCESS); + return *static_cast<AIThreadLocalData*>(data); +} + +//============================================================================ + +bool LLMutexBase::isLocked() { if (!tryLock()) { @@ -308,12 +326,9 @@ bool LLMutex::isLocked() //============================================================================ -LLCondition::LLCondition(apr_pool_t *poolp) : - LLMutex(poolp) +LLCondition::LLCondition(AIAPRPool& parent) : LLMutex(parent) { - // base class (LLMutex) has already ensured that mAPRPoolp is set up. - - apr_thread_cond_create(&mAPRCondp, mAPRPoolp); + apr_thread_cond_create(&mAPRCondp, mPool()); } LLCondition::~LLCondition() @@ -349,7 +364,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() { if (!sMutex) { - sMutex = new LLMutex(0); + sMutex = new LLMutex; } } diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index 98d64efb1..8708929b3 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h @@ -38,11 +38,28 @@ #include "llmemory.h" #include "apr_thread_cond.h" +#include "aiaprpool.h" class LLThread; class LLMutex; class LLCondition; +class LL_COMMON_API AIThreadLocalData +{ +private: + static apr_threadkey_t* sThreadLocalDataKey; + +public: + // Thread-local memory pool. + AIAPRRootPool mRootPool; + AIVolatileAPRPool mVolatileAPRPool; + + static void init(void); + static void destroy(void* thread_local_data); + static void create(LLThread* pthread); + static AIThreadLocalData& tldata(void); +}; + class LL_COMMON_API LLThread { public: @@ -53,7 +70,7 @@ class LL_COMMON_API LLThread QUITTING= 2 // Someone wants this thread to quit } EThreadStatus; - LLThread(const std::string& name, apr_pool_t *poolp = NULL); + LLThread(std::string const& name); virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. virtual void shutdown(); // stops the thread @@ -82,7 +99,8 @@ class LL_COMMON_API LLThread // this kicks off the apr thread void start(void); - apr_pool_t *getAPRPool() { return mAPRPoolp; } + // Return thread-local data for the current thread. + static AIThreadLocalData& tldata(void) { return AIThreadLocalData::tldata(); } private: bool mPaused; @@ -95,10 +113,11 @@ class LL_COMMON_API LLThread LLCondition* mRunCondition; apr_thread_t *mAPRThreadp; - apr_pool_t *mAPRPoolp; - bool mIsLocalPool; EThreadStatus mStatus; + friend void AIThreadLocalData::create(LLThread* threadp); + AIThreadLocalData* mThreadLocalData; + void setQuitting(); // virtual function overridden by subclass -- this will be called when the thread runs @@ -125,12 +144,9 @@ class LL_COMMON_API LLThread //============================================================================ -class LL_COMMON_API LLMutex +class LL_COMMON_API LLMutexBase { public: - LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex - ~LLMutex(); - void lock() { apr_thread_mutex_lock(mAPRMutexp); } void unlock() { apr_thread_mutex_unlock(mAPRMutexp); } // Returns true if lock was obtained successfully. @@ -139,16 +155,60 @@ class LL_COMMON_API LLMutex bool isLocked(); // non-blocking, but does do a lock/unlock so not free protected: - apr_thread_mutex_t *mAPRMutexp; - apr_pool_t *mAPRPoolp; - bool mIsLocalPool; + // mAPRMutexp is initialized and uninitialized in the derived class. + apr_thread_mutex_t* mAPRMutexp; +}; + +class LL_COMMON_API LLMutex : public LLMutexBase +{ +public: + LLMutex(AIAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent) + { + apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mPool()); + } + ~LLMutex() + { + llassert(!isLocked()); // better not be locked! + apr_thread_mutex_destroy(mAPRMutexp); + mAPRMutexp = NULL; + } + +protected: + AIAPRPool mPool; +}; + +#if APR_HAS_THREADS +// No need to use a root pool in this case. +typedef LLMutex LLMutexRootPool; +#else // APR_HAS_THREADS +class LL_COMMON_API LLMutexRootPool : public LLMutexBase +{ +public: + LLMutexRootPool(void) + { + apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mRootPool()); + } + ~LLMutexRootPool() + { +#if APR_POOL_DEBUG + // It is allowed to destruct root pools from a different thread. + mRootPool.grab_ownership(); +#endif + llassert(!isLocked()); // better not be locked! + apr_thread_mutex_destroy(mAPRMutexp); + mAPRMutexp = NULL; + } + +protected: + AIAPRRootPool mRootPool; }; +#endif // APR_HAS_THREADS // Actually a condition/mutex pair (since each condition needs to be associated with a mutex). class LL_COMMON_API LLCondition : public LLMutex { public: - LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. + LLCondition(AIAPRPool& parent = LLThread::tldata().mRootPool); ~LLCondition(); void wait(); // blocks @@ -162,7 +222,7 @@ class LL_COMMON_API LLCondition : public LLMutex class LL_COMMON_API LLMutexLock { public: - LLMutexLock(LLMutex* mutex) + LLMutexLock(LLMutexBase* mutex) { mMutex = mutex; mMutex->lock(); @@ -172,7 +232,7 @@ class LL_COMMON_API LLMutexLock mMutex->unlock(); } private: - LLMutex* mMutex; + LLMutexBase* mMutex; }; //============================================================================ diff --git a/linden/indra/llcommon/llworkerthread.cpp b/linden/indra/llcommon/llworkerthread.cpp index 8195e1cc8..e238a89b0 100644 --- a/linden/indra/llcommon/llworkerthread.cpp +++ b/linden/indra/llcommon/llworkerthread.cpp @@ -43,7 +43,7 @@ LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) : LLQueuedThread(name, threaded) { - mDeleteMutex = new LLMutex(NULL); + mDeleteMutex = new LLMutex; } LLWorkerThread::~LLWorkerThread() @@ -183,7 +183,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na : mWorkerThread(workerthread), mWorkerClassName(name), mRequestHandle(LLWorkerThread::nullHandle()), - mMutex(NULL), mWorkFlags(0) { if (!mWorkerThread) diff --git a/linden/indra/llcommon/llworkerthread.h b/linden/indra/llcommon/llworkerthread.h index 33d4c40f8..8e0dd8a2e 100644 --- a/linden/indra/llcommon/llworkerthread.h +++ b/linden/indra/llcommon/llworkerthread.h @@ -194,7 +194,7 @@ class LL_COMMON_API LLWorkerClass U32 mRequestPriority; // last priority set private: - LLMutex mMutex; + LLMutexRootPool mMutex; // Use LLMutexRootPool since this object is created and destructed by multiple threads. LLAtomicU32 mWorkFlags; }; diff --git a/linden/indra/llcrashlogger/llcrashlogger.cpp b/linden/indra/llcrashlogger/llcrashlogger.cpp index d25be5580..b6afbc6ca 100755 --- a/linden/indra/llcrashlogger/llcrashlogger.cpp +++ b/linden/indra/llcrashlogger/llcrashlogger.cpp @@ -387,8 +387,7 @@ bool LLCrashLogger::init() return false; } - gServicePump = new LLPumpIO(gAPRPoolp); - gServicePump->prime(gAPRPoolp); + gServicePump = new LLPumpIO; LLHTTPClient::setPump(*gServicePump); //If we've opened the crash logger, assume we can delete the marker file if it exists diff --git a/linden/indra/llimage/llimage.cpp b/linden/indra/llimage/llimage.cpp index 776c481f0..e9337509f 100644 --- a/linden/indra/llimage/llimage.cpp +++ b/linden/indra/llimage/llimage.cpp @@ -57,7 +57,7 @@ LLMutex* LLImage::sMutex = NULL; //static void LLImage::initClass(const bool& useDSO) { - sMutex = new LLMutex(NULL); + sMutex = new LLMutex; if (useDSO) { LLImageJ2C::openDSO(); diff --git a/linden/indra/llimage/llimagej2c.cpp b/linden/indra/llimage/llimagej2c.cpp index b99ebff98..9e88bcd66 100644 --- a/linden/indra/llimage/llimagej2c.cpp +++ b/linden/indra/llimage/llimagej2c.cpp @@ -46,7 +46,7 @@ typedef const char* (*EngineInfoLLImageJ2CFunction)(); CreateLLImageJ2CFunction j2cimpl_create_func; DestroyLLImageJ2CFunction j2cimpl_destroy_func; EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func; -apr_pool_t *j2cimpl_dso_memory_pool; +AIAPRPool j2cimpl_dso_memory_pool; apr_dso_handle_t *j2cimpl_dso_handle; //Declare the prototype for theses functions here, their functionality @@ -81,13 +81,12 @@ void LLImageJ2C::openDSO() gDirUtilp->getExecutableDir()); j2cimpl_dso_handle = NULL; - j2cimpl_dso_memory_pool = NULL; + j2cimpl_dso_memory_pool.create(); //attempt to load the shared library - apr_pool_create(&j2cimpl_dso_memory_pool, NULL); rv = apr_dso_load(&j2cimpl_dso_handle, dso_path.c_str(), - j2cimpl_dso_memory_pool); + j2cimpl_dso_memory_pool()); //now, check for success if ( rv == APR_SUCCESS ) @@ -151,11 +150,7 @@ void LLImageJ2C::openDSO() j2cimpl_dso_handle = NULL; } - if ( j2cimpl_dso_memory_pool ) - { - apr_pool_destroy(j2cimpl_dso_memory_pool); - j2cimpl_dso_memory_pool = NULL; - } + j2cimpl_dso_memory_pool.destroy(); } } @@ -163,7 +158,7 @@ void LLImageJ2C::openDSO() void LLImageJ2C::closeDSO() { if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle); - if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool); + j2cimpl_dso_memory_pool.destroy(); } //static diff --git a/linden/indra/llimage/llimageworker.cpp b/linden/indra/llimage/llimageworker.cpp index 558a968bd..dc989e53f 100644 --- a/linden/indra/llimage/llimageworker.cpp +++ b/linden/indra/llimage/llimageworker.cpp @@ -41,14 +41,13 @@ LLImageDecodeThread::LLImageDecodeThread(bool threaded) : LLQueuedThread("imagedecode", threaded) { - mCreationMutex = new LLMutex(getAPRPool()); } // MAIN THREAD // virtual S32 LLImageDecodeThread::update(U32 max_time_ms) { - LLMutexLock lock(mCreationMutex); + LLMutexLock lock(&mCreationMutex); for (creation_list_t::iterator iter = mCreationList.begin(); iter != mCreationList.end(); ++iter) { @@ -71,7 +70,7 @@ S32 LLImageDecodeThread::update(U32 max_time_ms) LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder) { - LLMutexLock lock(mCreationMutex); + LLMutexLock lock(&mCreationMutex); handle_t handle = generateHandle(); mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); return handle; @@ -81,7 +80,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* // Returns the size of the mutex guarded list as an indication of sanity S32 LLImageDecodeThread::tut_size() { - LLMutexLock lock(mCreationMutex); + LLMutexLock lock(&mCreationMutex); S32 res = mCreationList.size(); return res; } diff --git a/linden/indra/llimage/llimageworker.h b/linden/indra/llimage/llimageworker.h index 026020648..fa2a8fa75 100644 --- a/linden/indra/llimage/llimageworker.h +++ b/linden/indra/llimage/llimageworker.h @@ -101,7 +101,7 @@ class LLImageDecodeThread : public LLQueuedThread }; typedef std::list<creation_info> creation_list_t; creation_list_t mCreationList; - LLMutex* mCreationMutex; + LLMutex mCreationMutex; }; #endif diff --git a/linden/indra/llmath/llvolumemgr.cpp b/linden/indra/llmath/llvolumemgr.cpp index 53641fcea..8bfebcb42 100644 --- a/linden/indra/llmath/llvolumemgr.cpp +++ b/linden/indra/llmath/llvolumemgr.cpp @@ -55,7 +55,7 @@ LLVolumeMgr::LLVolumeMgr() { // the LLMutex magic interferes with easy unit testing, // so you now must manually call useMutex() to use it - //mDataMutex = new LLMutex(gAPRPoolp); + //mDataMutex = new LLMutex; } LLVolumeMgr::~LLVolumeMgr() @@ -222,7 +222,7 @@ void LLVolumeMgr::useMutex() { if (!mDataMutex) { - mDataMutex = new LLMutex(gAPRPoolp); + mDataMutex = new LLMutex; } } diff --git a/linden/indra/llmessage/llares.cpp b/linden/indra/llmessage/llares.cpp index fe37fe814..5a6794e03 100644 --- a/linden/indra/llmessage/llares.cpp +++ b/linden/indra/llmessage/llares.cpp @@ -43,6 +43,7 @@ #include "llapr.h" #include "llares.h" +#include "llscopedvolatileaprpool.h" #if defined(LL_WINDOWS) # define ns_c_in 1 @@ -463,11 +464,6 @@ void LLAres::search(const std::string &query, LLResType type, bool LLAres::process(U64 timeout) { - if (!gAPRPoolp) - { - ll_init_apr(); - } - int socks[ARES_GETSOCK_MAXNUM]; apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; apr_int32_t nsds = 0; @@ -481,10 +477,7 @@ bool LLAres::process(U64 timeout) return nsds > 0; } - apr_status_t status; - LLAPRPool pool; - status = pool.getStatus() ; - ll_apr_assert_status(status); + LLScopedVolatileAPRPool scoped_pool; for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++) { @@ -501,7 +494,7 @@ bool LLAres::process(U64 timeout) apr_socket_t *aprSock = NULL; - status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool()); + apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool); if (status != APR_SUCCESS) { ll_apr_warn_status(status); @@ -510,7 +503,7 @@ bool LLAres::process(U64 timeout) aprFds[nactive].desc.s = aprSock; aprFds[nactive].desc_type = APR_POLL_SOCKET; - aprFds[nactive].p = pool.getAPRPool(); + aprFds[nactive].p = scoped_pool; aprFds[nactive].rtnevents = 0; aprFds[nactive].client_data = &socks[i]; @@ -519,7 +512,7 @@ bool LLAres::process(U64 timeout) if (nactive > 0) { - status = apr_poll(aprFds, nactive, &nsds, timeout); + apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout); if (status != APR_SUCCESS && status != APR_TIMEUP) { diff --git a/linden/indra/llmessage/llcurl.cpp b/linden/indra/llmessage/llcurl.cpp index 202332c9d..9ecfee417 100644 --- a/linden/indra/llmessage/llcurl.cpp +++ b/linden/indra/llmessage/llcurl.cpp @@ -1020,7 +1020,7 @@ void LLCurl::initClass() S32 mutex_count = CRYPTO_num_locks(); for (S32 i=0; i<mutex_count; i++) { - sSSLMutex.push_back(new LLMutex(NULL)); + sSSLMutex.push_back(new LLMutex); } CRYPTO_set_id_callback(&LLCurl::ssl_thread_id); CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback); diff --git a/linden/indra/llmessage/lliohttpserver.cpp b/linden/indra/llmessage/lliohttpserver.cpp index 83dfa94f0..8ad052b91 100644 --- a/linden/indra/llmessage/lliohttpserver.cpp +++ b/linden/indra/llmessage/lliohttpserver.cpp @@ -948,13 +948,9 @@ class LLHTTPResponseFactory : public LLChainIOFactory // static -LLHTTPNode& LLIOHTTPServer::create( - apr_pool_t* pool, LLPumpIO& pump, U16 port) +LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port) { - LLSocket::ptr_t socket = LLSocket::create( - pool, - LLSocket::STREAM_TCP, - port); + LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port); if(!socket) { llerrs << "Unable to initialize socket" << llendl; @@ -963,7 +959,7 @@ LLHTTPNode& LLIOHTTPServer::create( LLHTTPResponseFactory* factory = new LLHTTPResponseFactory; boost::shared_ptr<LLChainIOFactory> factory_ptr(factory); - LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr); + LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr); LLPumpIO::chain_t chain; chain.push_back(LLIOPipe::ptr_t(server)); diff --git a/linden/indra/llmessage/lliohttpserver.h b/linden/indra/llmessage/lliohttpserver.h index d1c9bdde8..d2a8e2a8f 100644 --- a/linden/indra/llmessage/lliohttpserver.h +++ b/linden/indra/llmessage/lliohttpserver.h @@ -57,7 +57,7 @@ class LLIOHTTPServer public: typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); - static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port); + static LLHTTPNode& create(LLPumpIO& pump, U16 port); /**< Creates an HTTP wire server on the pump for the given TCP port. * * Returns the root node of the new server. Add LLHTTPNode instances diff --git a/linden/indra/llmessage/lliosocket.cpp b/linden/indra/llmessage/lliosocket.cpp index 7ec577c7b..686c03742 100644 --- a/linden/indra/llmessage/lliosocket.cpp +++ b/linden/indra/llmessage/lliosocket.cpp @@ -41,6 +41,7 @@ #include "llhost.h" #include "llmemtype.h" #include "llpumpio.h" +#include "llthread.h" // // constants @@ -104,51 +105,31 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock) /// // static -LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) +LLSocket::ptr_t LLSocket::create(EType type, U16 port) { LLMemType m1(LLMemType::MTYPE_IO_TCP); - LLSocket::ptr_t rv; - apr_socket_t* socket = NULL; - apr_pool_t* new_pool = NULL; apr_status_t status = APR_EGENERAL; - - // create a pool for the socket - status = apr_pool_create(&new_pool, pool); - if(ll_apr_warn_status(status)) - { - if(new_pool) apr_pool_destroy(new_pool); - return rv; - } + LLSocket::ptr_t rv(new LLSocket); if(STREAM_TCP == type) { - status = apr_socket_create( - &socket, - APR_INET, - SOCK_STREAM, - APR_PROTO_TCP, - new_pool); + status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool()); } else if(DATAGRAM_UDP == type) { - status = apr_socket_create( - &socket, - APR_INET, - SOCK_DGRAM, - APR_PROTO_UDP, - new_pool); + status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool()); } else { - if(new_pool) apr_pool_destroy(new_pool); + rv.reset(); return rv; } if(ll_apr_warn_status(status)) { - if(new_pool) apr_pool_destroy(new_pool); + rv->mSocket = NULL; + rv.reset(); return rv; } - rv = ptr_t(new LLSocket(socket, new_pool)); if(port > 0) { apr_sockaddr_t* sa = NULL; @@ -158,7 +139,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) APR_UNSPEC, port, 0, - new_pool); + rv->mPool()); if(ll_apr_warn_status(status)) { rv.reset(); @@ -166,8 +147,8 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) } // This allows us to reuse the address on quick down/up. This // is unlikely to create problems. - ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); - status = apr_socket_bind(socket, sa); + ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1)); + status = apr_socket_bind(rv->mSocket, sa); if(ll_apr_warn_status(status)) { rv.reset(); @@ -181,7 +162,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) // to keep a queue of incoming connections for ACCEPT. lldebugs << "Setting listen state for socket." << llendl; status = apr_socket_listen( - socket, + rv->mSocket, LL_DEFAULT_LISTEN_BACKLOG); if(ll_apr_warn_status(status)) { @@ -202,21 +183,28 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) } // static -LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool) +LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket) { LLMemType m1(LLMemType::MTYPE_IO_TCP); - LLSocket::ptr_t rv; - if(!socket) + if (!listen_socket->getSocket()) + { + status = APR_ENOSOCKET; + return LLSocket::ptr_t(); + } + LLSocket::ptr_t rv(new LLSocket); + lldebugs << "accepting socket" << llendl; + status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool()); + if (status != APR_SUCCESS) { + rv->mSocket = NULL; + rv.reset(); return rv; } - rv = ptr_t(new LLSocket(socket, pool)); rv->mPort = PORT_EPHEMERAL; rv->setOptions(); return rv; } - bool LLSocket::blockingConnect(const LLHost& host) { if(!mSocket) return false; @@ -229,7 +217,7 @@ bool LLSocket::blockingConnect(const LLHost& host) APR_UNSPEC, host.getPort(), 0, - mPool))) + mPool()))) { return false; } @@ -240,13 +228,11 @@ bool LLSocket::blockingConnect(const LLHost& host) return true; } -LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) : - mSocket(socket), - mPool(pool), +LLSocket::LLSocket() : + mSocket(NULL), + mPool(LLThread::tldata().mRootPool), mPort(PORT_INVALID) { - ll_debug_socket("Constructing wholely formed socket", mSocket); - LLMemType m1(LLMemType::MTYPE_IO_TCP); } LLSocket::~LLSocket() @@ -258,10 +244,6 @@ LLSocket::~LLSocket() ll_debug_socket("Destroying socket", mSocket); apr_socket_close(mSocket); } - if(mPool) - { - apr_pool_destroy(mPool); - } } void LLSocket::setOptions() @@ -522,10 +504,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( /// LLIOServerSocket::LLIOServerSocket( - apr_pool_t* pool, LLIOServerSocket::socket_t listener, factory_t factory) : - mPool(pool), mListenSocket(listener), mReactor(factory), mInitialized(false), @@ -585,21 +565,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( lldebugs << "accepting socket" << llendl; PUMP_DEBUG; - apr_pool_t* new_pool = NULL; - apr_status_t status = apr_pool_create(&new_pool, mPool); - apr_socket_t* socket = NULL; - status = apr_socket_accept( - &socket, - mListenSocket->getSocket(), - new_pool); - LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool)); + apr_status_t status; + LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket)); //EStatus rv = STATUS_ERROR; - if(llsocket) + if(llsocket && status == APR_SUCCESS) { PUMP_DEBUG; apr_sockaddr_t* remote_addr; - apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); + apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket()); char* remote_host_string; apr_sockaddr_ip_get(&remote_host_string, remote_addr); @@ -614,7 +588,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( { chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); pump->addChain(chain, mResponseTimeout); - status = STATUS_OK; } else { @@ -623,7 +596,8 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( } else { - llwarns << "Unable to create linden socket." << llendl; + char buf[256]; + llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl; } PUMP_DEBUG; @@ -636,11 +610,10 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( #if 0 LLIODataSocket::LLIODataSocket( U16 suggested_port, - U16 start_discovery_port, - apr_pool_t* pool) : + U16 start_discovery_port) : mSocket(NULL) { - if(!pool || (PORT_INVALID == suggested_port)) return; + if(PORT_INVALID == suggested_port) return; if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return; apr_sockaddr_t* sa = NULL; if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return; diff --git a/linden/indra/llmessage/lliosocket.h b/linden/indra/llmessage/lliosocket.h index ec09ad8ba..5ad75e909 100644 --- a/linden/indra/llmessage/lliosocket.h +++ b/linden/indra/llmessage/lliosocket.h @@ -44,7 +44,6 @@ */ #include "lliopipe.h" -#include "apr_pools.h" #include "apr_network_io.h" #include "llchainio.h" @@ -94,34 +93,22 @@ class LLSocket * socket. If you intend the socket to be known to external * clients without prior port notification, do not use * PORT_EPHEMERAL. - * @param pool The apr pool to use. A child pool will be created - * and associated with the socket. * @param type The type of socket to create * @param port The port for the socket * @return A valid socket shared pointer if the call worked. */ static ptr_t create( - apr_pool_t* pool, EType type, U16 port = PORT_EPHEMERAL); /** - * @brief Create a LLSocket when you already have an apr socket. + * @brief Create a LLSocket by accepting a connection from a listen socket. * - * This method assumes an ephemeral port. This is typically used - * by calls which spawn a socket such as a call to - * <code>accept()</code> as in the server socket. This call should - * not fail if you have a valid apr socket. - * Because of the nature of how accept() works, you are expected - * to create a new pool for the socket, use that pool for the - * accept, and pass it in here where it will be bound with the - * socket and destroyed at the same time. - * @param socket The apr socket to use - * @param pool The pool used to create the socket. *NOTE: The pool - * passed in will be DESTROYED. + * @param status Output. Status of the accept if a valid listen socket was passed. + * @param listen_socket The listen socket to use. * @return A valid socket shared pointer if the call worked. */ - static ptr_t create(apr_socket_t* socket, apr_pool_t* pool); + static ptr_t create(apr_status_t& status, ptr_t& listen_socket); /** * @brief Perform a blocking connect to a host. Do not use in production. @@ -156,7 +143,7 @@ class LLSocket * @brief Protected constructor since should only make sockets * with one of the two <code>create()</code> calls. */ - LLSocket(apr_socket_t* socket, apr_pool_t* pool); + LLSocket(void); /** * @brief Set default socket options. @@ -173,8 +160,8 @@ class LLSocket // The apr socket. apr_socket_t* mSocket; - // our memory pool - apr_pool_t* mPool; + // Our memory pool. + AIAPRPool mPool; // The port if we know it. U16 mPort; @@ -299,7 +286,7 @@ class LLIOServerSocket : public LLIOPipe public: typedef LLSocket::ptr_t socket_t; typedef boost::shared_ptr<LLChainIOFactory> factory_t; - LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor); + LLIOServerSocket(socket_t listener, factory_t reactor); virtual ~LLIOServerSocket(); /** @@ -331,7 +318,6 @@ class LLIOServerSocket : public LLIOPipe //@} protected: - apr_pool_t* mPool; socket_t mListenSocket; factory_t mReactor; bool mInitialized; @@ -365,8 +351,7 @@ class LLIODataSocket : public LLIOSocket */ LLIODataSocket( U16 suggested_port, - U16 start_discovery_port, - apr_pool_t* pool); + U16 start_discovery_port); virtual ~LLIODataSocket(); protected: diff --git a/linden/indra/llmessage/llmail.cpp b/linden/indra/llmessage/llmail.cpp index d52ff6c7e..8850e2967 100644 --- a/linden/indra/llmessage/llmail.cpp +++ b/linden/indra/llmessage/llmail.cpp @@ -56,6 +56,7 @@ #include "llstring.h" #include "lluuid.h" #include "net.h" +#include "aiaprpool.h" // // constants @@ -63,7 +64,7 @@ const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096; static bool gMailEnabled = true; -static apr_pool_t* gMailPool; +static AIAPRPool gMailPool; static apr_sockaddr_t* gSockAddr; static apr_socket_t* gMailSocket; @@ -88,7 +89,7 @@ bool connect_smtp() gSockAddr->sa.sin.sin_family, SOCK_STREAM, APR_PROTO_TCP, - gMailPool); + gMailPool()); if(ll_apr_warn_status(status)) return false; status = apr_socket_connect(gMailSocket, gSockAddr); if(ll_apr_warn_status(status)) @@ -145,19 +146,19 @@ BOOL LLMail::send( } // static -void LLMail::init(const std::string& hostname, apr_pool_t* pool) +void LLMail::init(const std::string& hostname) { gMailSocket = NULL; - if(hostname.empty() || !pool) + if (hostname.empty()) { - gMailPool = NULL; gSockAddr = NULL; + gMailPool.destroy(); } else { - gMailPool = pool; + gMailPool.create(); - // collect all the information into a socaddr sturcture. the + // Collect all the information into a sockaddr structure. the // documentation is a bit unclear, but I either have to // specify APR_UNSPEC or not specify any flags. I am not sure // which option is better. @@ -167,7 +168,7 @@ void LLMail::init(const std::string& hostname, apr_pool_t* pool) APR_UNSPEC, 25, APR_IPV4_ADDR_OK, - gMailPool); + gMailPool()); ll_apr_warn_status(status); } } diff --git a/linden/indra/llmessage/llmail.h b/linden/indra/llmessage/llmail.h index 7effb847a..7026d93b3 100644 --- a/linden/indra/llmessage/llmail.h +++ b/linden/indra/llmessage/llmail.h @@ -33,15 +33,13 @@ #ifndef LL_LLMAIL_H #define LL_LLMAIL_H -typedef struct apr_pool_t apr_pool_t; - #include "llsd.h" class LLMail { public: // if hostname is NULL, then the host is resolved as 'mail' - static void init(const std::string& hostname, apr_pool_t* pool); + static void init(const std::string& hostname); // Allow all email transmission to be disabled/enabled. static void enable(bool mail_enabled); diff --git a/linden/indra/llmessage/llpumpio.cpp b/linden/indra/llmessage/llpumpio.cpp index 8ef2b16c0..6f10c6b68 100644 --- a/linden/indra/llmessage/llpumpio.cpp +++ b/linden/indra/llmessage/llpumpio.cpp @@ -43,6 +43,7 @@ #include "llmemtype.h" #include "llstl.h" #include "llstat.h" +#include "llthread.h" #include "llfasttimer.h" // These should not be enabled in production, but they can be @@ -169,14 +170,12 @@ struct ll_delete_apr_pollset_fd_client_data /** * LLPumpIO */ -LLPumpIO::LLPumpIO(apr_pool_t* pool) : +LLPumpIO::LLPumpIO(void) : mState(LLPumpIO::NORMAL), mRebuildPollset(false), mPollset(NULL), mPollsetClientID(0), mNextLock(0), - mPool(NULL), - mCurrentPool(NULL), mCurrentPoolReallocCount(0), mChainsMutex(NULL), mCallbackMutex(NULL), @@ -185,21 +184,24 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) : mCurrentChain = mRunningChains.end(); LLMemType m1(LLMemType::MTYPE_IO_PUMP); - initialize(pool); + initialize(); } LLPumpIO::~LLPumpIO() { LLMemType m1(LLMemType::MTYPE_IO_PUMP); - cleanup(); -} - -bool LLPumpIO::prime(apr_pool_t* pool) -{ - LLMemType m1(LLMemType::MTYPE_IO_PUMP); - cleanup(); - initialize(pool); - return ((pool == NULL) ? false : true); +#if LL_THREADS_APR + if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex); + if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex); +#endif + mChainsMutex = NULL; + mCallbackMutex = NULL; + if(mPollset) + { +// lldebugs << "cleaning up pollset" << llendl; + apr_pollset_destroy(mPollset); + mPollset = NULL; + } } bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) @@ -359,8 +361,7 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll) { // each fd needs a pool to work with, so if one was // not specified, use this pool. - // *FIX: Should it always be this pool? - value.second.p = mPool; + value.second.p = (*mCurrentChain).mDescriptorsPool->operator()(); } value.second.client_data = new S32(++mPollsetClientID); (*mCurrentChain).mDescriptors.push_back(value); @@ -827,39 +828,15 @@ void LLPumpIO::control(LLPumpIO::EControl op) } } -void LLPumpIO::initialize(apr_pool_t* pool) +void LLPumpIO::initialize(void) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); - if(!pool) return; + mPool.create(); #if LL_THREADS_APR // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly. - apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool); - apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool); -#endif - mPool = pool; -} - -void LLPumpIO::cleanup() -{ - LLMemType m1(LLMemType::MTYPE_IO_PUMP); -#if LL_THREADS_APR - if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex); - if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex); + apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool()); + apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool()); #endif - mChainsMutex = NULL; - mCallbackMutex = NULL; - if(mPollset) - { -// lldebugs << "cleaning up pollset" << llendl; - apr_pollset_destroy(mPollset); - mPollset = NULL; - } - if(mCurrentPool) - { - apr_pool_destroy(mCurrentPool); - mCurrentPool = NULL; - } - mPool = NULL; } void LLPumpIO::rebuildPollset() @@ -887,21 +864,19 @@ void LLPumpIO::rebuildPollset() if(mCurrentPool && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) { - apr_pool_destroy(mCurrentPool); - mCurrentPool = NULL; + mCurrentPool.destroy(); mCurrentPoolReallocCount = 0; } if(!mCurrentPool) { - apr_status_t status = apr_pool_create(&mCurrentPool, mPool); - (void)ll_apr_warn_status(status); + mCurrentPool.create(mPool); } // add all of the file descriptors run_it = mRunningChains.begin(); LLChainInfo::conditionals_t::iterator fd_it; LLChainInfo::conditionals_t::iterator fd_end; - apr_pollset_create(&mPollset, size, mCurrentPool, 0); + apr_pollset_create(&mPollset, size, mCurrentPool(), 0); for(; run_it != run_end; ++run_it) { fd_it = (*run_it).mDescriptors.begin(); @@ -1159,7 +1134,8 @@ bool LLPumpIO::handleChainError( LLPumpIO::LLChainInfo::LLChainInfo() : mInit(false), mLock(0), - mEOS(false) + mEOS(false), + mDescriptorsPool(new AIAPRPool(LLThread::tldata().mRootPool)) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); diff --git a/linden/indra/llmessage/llpumpio.h b/linden/indra/llmessage/llpumpio.h index fc0bfabaa..2666be04a 100644 --- a/linden/indra/llmessage/llpumpio.h +++ b/linden/indra/llmessage/llpumpio.h @@ -36,11 +36,12 @@ #define LL_LLPUMPIO_H #include <set> +#include <boost/shared_ptr.hpp> #if LL_LINUX // needed for PATH_MAX in APR. #include <sys/param.h> #endif -#include "apr_pools.h" +#include "aiaprpool.h" #include "llbuffer.h" #include "llframetimer.h" #include "lliopipe.h" @@ -64,9 +65,8 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS; * <code>pump()</code> on a thread used for IO and call * <code>respond()</code> on a thread that is expected to do higher * level processing. You can call almost any other method from any - * thread - see notes for each method for details. In order for the - * threading abstraction to work, you need to call <code>prime()</code> - * with a valid apr pool. + * thread - see notes for each method for details. + * * A pump instance manages much of the state for the pipe, including * the list of pipes in the chain, the channel for each element in the * chain, the buffer, and if any pipe has marked the stream or process @@ -85,24 +85,13 @@ class LLPumpIO /** * @brief Constructor. */ - LLPumpIO(apr_pool_t* pool); + LLPumpIO(void); /** * @brief Destructor. */ ~LLPumpIO(); - /** - * @brief Prepare this pump for usage. - * - * If you fail to call this method prior to use, the pump will - * try to work, but will not come with any thread locking - * mechanisms. - * @param pool The apr pool to use. - * @return Returns true if the pump is primed. - */ - bool prime(apr_pool_t* pool); - /** * @brief Typedef for having a chain of pipes. */ @@ -374,6 +363,7 @@ class LLPumpIO typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; typedef std::vector<pipe_conditional_t> conditionals_t; conditionals_t mDescriptors; + boost::shared_ptr<AIAPRPool> mDescriptorsPool; }; // All the running chains & info @@ -392,9 +382,9 @@ class LLPumpIO callbacks_t mPendingCallbacks; callbacks_t mCallbacks; - // memory allocator for pollsets & mutexes. - apr_pool_t* mPool; - apr_pool_t* mCurrentPool; + // Memory pool for pollsets & mutexes. + AIAPRPool mPool; + AIAPRPool mCurrentPool; S32 mCurrentPoolReallocCount; #if LL_THREADS_APR @@ -406,8 +396,7 @@ class LLPumpIO #endif protected: - void initialize(apr_pool_t* pool); - void cleanup(); + void initialize(); /** * @brief Given the internal state of the chains, rebuild the pollset diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp index 46e976fe3..87f011643 100644 --- a/linden/indra/llmessage/llurlrequest.cpp +++ b/linden/indra/llmessage/llurlrequest.cpp @@ -45,6 +45,7 @@ #include "llstring.h" #include "apr_env.h" #include "llapr.h" +#include "llscopedvolatileaprpool.h" static const U32 HTTP_STATUS_PIPE_ERROR = 499; /** @@ -161,27 +162,31 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback) // is called with use_proxy = FALSE void LLURLRequest::useProxy(bool use_proxy) { - static char *env_proxy; + static std::string env_proxy; - if (use_proxy && (env_proxy == NULL)) + if (use_proxy && env_proxy.empty()) { - apr_status_t status; - LLAPRPool pool; - status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool()); + char* env_proxy_str; + LLScopedVolatileAPRPool scoped_pool; + apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool); if (status != APR_SUCCESS) { - status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool()); + status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool); } if (status != APR_SUCCESS) { - use_proxy = FALSE; + use_proxy = false; } + else + { + // env_proxy_str is stored in the scoped_pool, so we have to make a copy. + env_proxy = env_proxy_str; + } } + lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl; - lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl; - - if (env_proxy && use_proxy) + if (use_proxy) { mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy); } diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp index 7e8aff16d..53036bcf6 100644 --- a/linden/indra/llmessage/message.cpp +++ b/linden/indra/llmessage/message.cpp @@ -103,8 +103,10 @@ std::string get_shared_secret(); class LLMessagePollInfo { public: + LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { } apr_socket_t *mAPRSocketp; apr_pollfd_t mPollFD; + AIAPRPool mPool; }; namespace @@ -291,20 +293,13 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, } // LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl; - // - // Create the data structure that we can poll on - // - if (!gAPRPoolp) - { - LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl; - ll_init_apr(); - } + mPollInfop = new LLMessagePollInfo; + apr_socket_t *aprSocketp = NULL; - apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp); + apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool()); - mPollInfop = new LLMessagePollInfo; mPollInfop->mAPRSocketp = aprSocketp; - mPollInfop->mPollFD.p = gAPRPoolp; + mPollInfop->mPollFD.p = mPollInfop->mPool(); mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET; mPollInfop->mPollFD.reqevents = APR_POLLIN; mPollInfop->mPollFD.rtnevents = 0; diff --git a/linden/indra/llplugin/llplugininstance.cpp b/linden/indra/llplugin/llplugininstance.cpp index b822b9e94..3a1395cd2 100755 --- a/linden/indra/llplugin/llplugininstance.cpp +++ b/linden/indra/llplugin/llplugininstance.cpp @@ -36,8 +36,7 @@ #include "linden_common.h" #include "llplugininstance.h" - -#include "llapr.h" +#include "aiaprpool.h" /** Virtual destructor. */ LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() @@ -86,7 +85,7 @@ int LLPluginInstance::load(std::string &plugin_file) int result = apr_dso_load(&mDSOHandle, plugin_file.c_str(), - gAPRPoolp); + AIAPRRootPool::get()()); if(result != APR_SUCCESS) { char buf[1024]; diff --git a/linden/indra/llplugin/llpluginmessagepipe.cpp b/linden/indra/llplugin/llpluginmessagepipe.cpp index 8168b32c4..ebac3c52b 100755 --- a/linden/indra/llplugin/llpluginmessagepipe.cpp +++ b/linden/indra/llplugin/llpluginmessagepipe.cpp @@ -99,8 +99,6 @@ void LLPluginMessagePipeOwner::killMessagePipe(void) } LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): - mInputMutex(gAPRPoolp), - mOutputMutex(gAPRPoolp), mOwner(owner), mSocket(socket) { diff --git a/linden/indra/llplugin/llpluginprocesschild.cpp b/linden/indra/llplugin/llpluginprocesschild.cpp index 8dbf2b3e9..d2238236f 100755 --- a/linden/indra/llplugin/llpluginprocesschild.cpp +++ b/linden/indra/llplugin/llpluginprocesschild.cpp @@ -47,7 +47,7 @@ LLPluginProcessChild::LLPluginProcessChild() { mState = STATE_UNINITIALIZED; mInstance = NULL; - mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); + mSocket = LLSocket::create(LLSocket::STREAM_TCP); mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz mCPUElapsed = 0.0f; mBlockingRequest = false; diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp index 8fd18ef05..2cb6b2832 100755 --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp @@ -49,6 +49,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() bool LLPluginProcessParent::sUseReadThread = false; apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; +AIAPRPool LLPluginProcessParent::sPollSetPool; bool LLPluginProcessParent::sPollsetNeedsRebuild = false; LLMutex *LLPluginProcessParent::sInstancesMutex; std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; @@ -59,7 +60,7 @@ class LLPluginProcessParentPollThread: public LLThread { public: LLPluginProcessParentPollThread() : - LLThread("LLPluginProcessParentPollThread", gAPRPoolp) + LLThread("LLPluginProcessParentPollThread") { } protected: @@ -84,12 +85,11 @@ class LLPluginProcessParentPollThread: public LLThread }; -LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): - mIncomingQueueMutex(gAPRPoolp) +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) { if(!sInstancesMutex) { - sInstancesMutex = new LLMutex(gAPRPoolp); + sInstancesMutex = new LLMutex; } mOwner = owner; @@ -102,6 +102,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): mBlocked = false; mPolledInput = false; mPollFD.client_data = NULL; + mPollFDPool.create(); mPluginLaunchTimeout = 60.0f; mPluginLockupTimeout = 15.0f; @@ -177,44 +178,28 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std bool LLPluginProcessParent::accept() { bool result = false; - apr_status_t status = APR_EGENERAL; - apr_socket_t *new_socket = NULL; - - status = apr_socket_accept( - &new_socket, - mListenSocket->getSocket(), - gAPRPoolp); + mSocket = LLSocket::create(status, mListenSocket); if(status == APR_SUCCESS) { // llinfos << "SUCCESS" << llendl; // Success. Create a message pipe on the new socket - - // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! - apr_pool_t* new_pool = NULL; - status = apr_pool_create(&new_pool, gAPRPoolp); - - mSocket = LLSocket::create(new_socket, new_pool); new LLPluginMessagePipe(this, mSocket); result = true; } - else if(APR_STATUS_IS_EAGAIN(status)) - { -// llinfos << "EAGAIN" << llendl; - - // No incoming connections. This is not an error. - status = APR_SUCCESS; - } else { -// llinfos << "Error:" << llendl; - ll_apr_warn_status(status); - - // Some other error. - errorState(); + mSocket.reset(); + // EAGAIN means "No incoming connections". This is not an error. + if (!APR_STATUS_IS_EAGAIN(status)) + { + // Some other error. + ll_apr_warn_status(status); + errorState(); + } } return result; @@ -283,7 +268,7 @@ void LLPluginProcessParent::idle(void) apr_status_t status = APR_SUCCESS; apr_sockaddr_t* addr = NULL; - mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); + mListenSocket = LLSocket::create(LLSocket::STREAM_TCP); mBoundPort = 0; // This code is based on parts of LLSocket::create() in lliosocket.cpp. @@ -294,7 +279,7 @@ void LLPluginProcessParent::idle(void) APR_INET, 0, // port 0 = ephemeral ("find me a port") 0, - gAPRPoolp); + AIAPRRootPool::get()()); if(ll_apr_warn_status(status)) { @@ -617,7 +602,8 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) if(message_pipe != NULL) { // Set up the apr_pollfd_t - mPollFD.p = gAPRPoolp; + + mPollFD.p = mPollFDPool(); mPollFD.desc_type = APR_POLL_SOCKET; mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; mPollFD.rtnevents = 0; @@ -664,6 +650,7 @@ void LLPluginProcessParent::updatePollset() // delete the existing pollset. apr_pollset_destroy(sPollSet); sPollSet = NULL; + sPollSetPool.destroy(); } std::list<LLPluginProcessParent*>::iterator iter; @@ -686,12 +673,14 @@ void LLPluginProcessParent::updatePollset() { #ifdef APR_POLLSET_NOCOPY // The pollset doesn't exist yet. Create it now. - apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); + sPollSetPool.create(); + apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY); if(status != APR_SUCCESS) { #endif // APR_POLLSET_NOCOPY LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; sPollSet = NULL; + sPollSetPool.destroy(); #ifdef APR_POLLSET_NOCOPY } else diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h index 95f5f70c5..bba3643d6 100755 --- a/linden/indra/llplugin/llpluginprocessparent.h +++ b/linden/indra/llplugin/llpluginprocessparent.h @@ -186,7 +186,9 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner static bool sUseReadThread; apr_pollfd_t mPollFD; + AIAPRPool mPollFDPool; static apr_pollset_t *sPollSet; + static AIAPRPool sPollSetPool; static bool sPollsetNeedsRebuild; static LLMutex *sInstancesMutex; static std::list<LLPluginProcessParent*> sInstances; diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp index e8a411a53..883d7b634 100755 --- a/linden/indra/llplugin/llpluginsharedmemory.cpp +++ b/linden/indra/llplugin/llpluginsharedmemory.cpp @@ -201,7 +201,8 @@ bool LLPluginSharedMemory::create(size_t size) mName += createName(); mSize = size; - apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp ); + mPool.create(); + apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool()); if(ll_apr_warn_status(status)) { @@ -224,7 +225,7 @@ bool LLPluginSharedMemory::destroy(void) } mImpl->mAprSharedMemory = NULL; } - + mPool.destroy(); return true; } @@ -233,7 +234,8 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size) mName = name; mSize = size; - apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp ); + mPool.create(); + apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() ); if(ll_apr_warn_status(status)) { @@ -255,6 +257,7 @@ bool LLPluginSharedMemory::detach(void) } mImpl->mAprSharedMemory = NULL; } + mPool.destroy(); return true; } diff --git a/linden/indra/llplugin/llpluginsharedmemory.h b/linden/indra/llplugin/llpluginsharedmemory.h index 081d311b3..669a3e409 100755 --- a/linden/indra/llplugin/llpluginsharedmemory.h +++ b/linden/indra/llplugin/llpluginsharedmemory.h @@ -35,6 +35,8 @@ #ifndef LL_LLPLUGINSHAREDMEMORY_H #define LL_LLPLUGINSHAREDMEMORY_H +#include "aiaprpool.h" + class LLPluginSharedMemoryPlatformImpl; /** @@ -115,6 +117,7 @@ class LLPluginSharedMemory bool close(void); bool unlink(void); + AIAPRPool mPool; std::string mName; size_t mSize; void *mMappedAddress; diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp index 64c087bec..cca8ead8f 100755 --- a/linden/indra/llplugin/slplugin/slplugin.cpp +++ b/linden/indra/llplugin/slplugin/slplugin.cpp @@ -183,8 +183,6 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL int main(int argc, char **argv) #endif { - ll_init_apr(); - // Set up llerror logging { LLError::initForApplication("."); @@ -400,8 +398,6 @@ int main(int argc, char **argv) delete plugin; - ll_cleanup_apr(); - return 0; } diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp index dea8c9ca1..654dfa1ea 100644 --- a/linden/indra/llvfs/llvfs.cpp +++ b/linden/indra/llvfs/llvfs.cpp @@ -237,7 +237,7 @@ const S32 LLVFSFileBlock::SERIAL_SIZE = 34; LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash) : mRemoveAfterCrash(remove_after_crash) { - mDataMutex = new LLMutex(0); + mDataMutex = new LLMutex; S32 i; for (i = 0; i < VFSLOCK_COUNT; i++) diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp index c4c4181a4..cc3836ea5 100644 --- a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp +++ b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp @@ -58,7 +58,7 @@ extern "C" { #include <pulse/subscribe.h> #include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. -#include "apr_pools.h" +#include "aiaprpool.h" #include "apr_dso.h" } @@ -74,7 +74,7 @@ extern "C" { #undef LL_PA_SYM static bool sSymsGrabbed = false; -static apr_pool_t *sSymPADSOMemoryPool = NULL; +static AIAPRPool sSymPADSOMemoryPool; static apr_dso_handle_t *sSymPADSOHandleG = NULL; bool grab_pa_syms(std::string pulse_dso_name) @@ -93,11 +93,11 @@ bool grab_pa_syms(std::string pulse_dso_name) #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) //attempt to load the shared library - apr_pool_create(&sSymPADSOMemoryPool, NULL); + sSymPADSOMemoryPool.create(); if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, pulse_dso_name.c_str(), - sSymPADSOMemoryPool) )) + sSymPADSOMemoryPool()) )) { INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); @@ -140,11 +140,7 @@ void ungrab_pa_syms() sSymPADSOHandleG = NULL; } - if ( sSymPADSOMemoryPool ) - { - apr_pool_destroy(sSymPADSOMemoryPool); - sSymPADSOMemoryPool = NULL; - } + sSymPADSOMemoryPool.destroy(); // NULL-out all of the symbols we'd grabbed #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 8aea22111..aaae4d2af 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -920,7 +920,7 @@ bool LLAppViewer::mainLoop() //------------------------------------------- // Create IO Pump to use for HTTP Requests. - gServicePump = new LLPumpIO(gAPRPoolp); + gServicePump = new LLPumpIO; LLHTTPClient::setPump(*gServicePump); LLCurl::setCAFile(gDirUtilp->getCAFile()); diff --git a/linden/indra/newview/llappviewerlinux.cpp b/linden/indra/newview/llappviewerlinux.cpp index 307f925fc..88ddf7ef7 100644 --- a/linden/indra/newview/llappviewerlinux.cpp +++ b/linden/indra/newview/llappviewerlinux.cpp @@ -129,6 +129,7 @@ int main( int argc, char **argv ) } delete viewer_app_ptr; viewer_app_ptr = NULL; + return 0; } diff --git a/linden/indra/newview/llappviewermacosx.cpp b/linden/indra/newview/llappviewermacosx.cpp index 91de066e4..d81b6e3c5 100644 --- a/linden/indra/newview/llappviewermacosx.cpp +++ b/linden/indra/newview/llappviewermacosx.cpp @@ -119,6 +119,7 @@ int main( int argc, char **argv ) } delete viewer_app_ptr; viewer_app_ptr = NULL; + return 0; } diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index a1a9a3985..2b032a586 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp @@ -736,9 +736,6 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted) LLTextureCache::LLTextureCache(bool threaded) : LLWorkerThread("TextureCache", threaded), - mWorkersMutex(NULL), - mHeaderMutex(NULL), - mListMutex(NULL), mHeaderAPRFile(NULL), mReadOnly(FALSE), mTexturesSizeTotal(0), @@ -1541,7 +1538,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort) } } - unlockWorkers(); + unlockWorkers(); if (delete_worker) worker->scheduleDelete(); diff --git a/linden/indra/newview/lltexturecache.h b/linden/indra/newview/lltexturecache.h index c859b9aee..56b4c4f51 100644 --- a/linden/indra/newview/lltexturecache.h +++ b/linden/indra/newview/lltexturecache.h @@ -139,9 +139,6 @@ class LLTextureCache : public LLWorkerThread std::string getTextureFileName(const LLUUID& id); void addCompleted(Responder* responder, bool success); -protected: - //void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; } - private: void setDirNames(ELLPath location); void readHeaderCache(); diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index f93a5748f..072af2595 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp @@ -428,7 +428,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mRetryAttempt(0), mActiveCount(0), mGetStatus(0), - mWorkMutex(NULL), mFirstPacket(0), mLastPacket(-1), mTotalPackets(0), @@ -1540,8 +1539,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mDebugPause(FALSE), mPacketCount(0), mBadPacketCount(0), - mQueueMutex(getAPRPool()), - mNetworkQueueMutex(getAPRPool()), mTextureCache(cache), mImageDecodeThread(imagedecodethread), mTextureBandwidth(0), diff --git a/linden/indra/newview/llviewerprecompiledheaders.h b/linden/indra/newview/llviewerprecompiledheaders.h index 9bc6574f0..a0b99bf2f 100644 --- a/linden/indra/newview/llviewerprecompiledheaders.h +++ b/linden/indra/newview/llviewerprecompiledheaders.h @@ -165,7 +165,7 @@ #include "llinstantmessage.h" #include "llinvite.h" //#include "llloginflags.h" -#include "llmail.h" +//#include "llmail.h" #include "llmessagethrottle.h" #include "llnamevalue.h" #include "llpacketack.h" diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp index d67b9e3a2..7b1ed954d 100644 --- a/linden/indra/newview/llvoiceclient.cpp +++ b/linden/indra/newview/llvoiceclient.cpp @@ -1795,7 +1795,7 @@ void LLVoiceClient::stateMachine() if(!mSocket) { - mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); + mSocket = LLSocket::create(LLSocket::STREAM_TCP); } mConnected = mSocket->blockingConnect(mDaemonHost); diff --git a/linden/indra/newview/llwatchdog.cpp b/linden/indra/newview/llwatchdog.cpp index 330bc8a39..9af050c4c 100644 --- a/linden/indra/newview/llwatchdog.cpp +++ b/linden/indra/newview/llwatchdog.cpp @@ -184,8 +184,8 @@ void LLWatchdog::init(killer_event_callback func) mKillerCallback = func; if(!mSuspectsAccessMutex && !mTimer) { - mSuspectsAccessMutex = new LLMutex(NULL); - mTimer = new LLWatchdogTimerThread(); + mSuspectsAccessMutex = new LLMutex; + mTimer = new LLWatchdogTimerThread; mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000); mLastClockCount = LLTimer::getTotalTime(); diff --git a/linden/indra/test/lltemplatemessagebuilder_tut.cpp b/linden/indra/test/lltemplatemessagebuilder_tut.cpp index 5b33d0272..9fecc2f90 100644 --- a/linden/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/linden/indra/test/lltemplatemessagebuilder_tut.cpp @@ -35,7 +35,6 @@ #include "linden_common.h" #include "lltut.h" -#include "llapr.h" #include "llmessagetemplate.h" #include "llquaternion.h" #include "lltemplatemessagebuilder.h" @@ -59,7 +58,6 @@ namespace tut static bool init = false; if(! init) { - ll_init_apr(); const F32 circuit_heartbeat_interval=5; const F32 circuit_timeout=100; diff --git a/linden/indra/test/message_tut.cpp b/linden/indra/test/message_tut.cpp index 3fede2608..694db5213 100644 --- a/linden/indra/test/message_tut.cpp +++ b/linden/indra/test/message_tut.cpp @@ -35,7 +35,6 @@ #include "linden_common.h" #include "lltut.h" -#include "llapr.h" #include "llmessageconfig.h" #include "llsdserialize.h" #include "llversionserver.h" @@ -68,7 +67,6 @@ namespace tut static bool init = false; if(!init) { - ll_init_apr(); //init_prehash_data(); init = true; } diff --git a/linden/indra/test/test.cpp b/linden/indra/test/test.cpp index ba81c6e49..b699f74b0 100644 --- a/linden/indra/test/test.cpp +++ b/linden/indra/test/test.cpp @@ -43,8 +43,8 @@ #include "linden_common.h" #include "llerrorcontrol.h" #include "lltut.h" +#include "aiaprpool.h" -#include "apr_pools.h" #include "apr_getopt.h" // the CTYPE_WORKAROUND is needed for linux dev stations that don't @@ -248,17 +248,12 @@ int main(int argc, char **argv) ctype_workaround(); #endif - apr_initialize(); - apr_pool_t* pool = NULL; - if(APR_SUCCESS != apr_pool_create(&pool, NULL)) - { - std::cerr << "Unable to initialize pool" << std::endl; - return 1; - } + LLAPRPool pool; + pool.create(); apr_getopt_t* os = NULL; - if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv)) + if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv)) { - std::cerr << "Unable to pool" << std::endl; + std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << std::endl; return 1; } @@ -360,6 +355,5 @@ int main(int argc, char **argv) s.close(); } - apr_terminate(); return 0; } From 7bc679e616a4b8e0fafe2c1f6cac821208b649ff Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Thu, 11 Nov 2010 00:06:08 +0100 Subject: [PATCH 218/239] IMP-701: An API to wrap objects for thread-safe access. See http://redmine.imprudenceviewer.org/issues/701 --- linden/doc/contributions.txt | 1 + linden/indra/llcommon/CMakeLists.txt | 1 + linden/indra/llcommon/aiaprpool.h | 8 +- linden/indra/llcommon/aithreadsafe.h | 463 +++++++++++++++++++++++++++ linden/indra/llcommon/llthread.h | 96 +++++- 5 files changed, 565 insertions(+), 4 deletions(-) create mode 100644 linden/indra/llcommon/aithreadsafe.h diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index c8dd7735c..0ca56be7b 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -92,6 +92,7 @@ Aleric Inglewood IMP-670 IMP-688 IMP-692 + IMP-701 IMP-712 Alissa Sabre VWR-81 diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt index a05ee6f85..ee80ec3ea 100644 --- a/linden/indra/llcommon/CMakeLists.txt +++ b/linden/indra/llcommon/CMakeLists.txt @@ -76,6 +76,7 @@ set(llcommon_HEADER_FILES CMakeLists.txt aiaprpool.h + aithreadsafe.h bitpack.h ctype_workaround.h doublelinkedlist.h diff --git a/linden/indra/llcommon/aiaprpool.h b/linden/indra/llcommon/aiaprpool.h index f6d7ffa1d..72e9ddbd4 100644 --- a/linden/indra/llcommon/aiaprpool.h +++ b/linden/indra/llcommon/aiaprpool.h @@ -157,17 +157,19 @@ class AIAPRInitialization /** * @brief Root memory pool (allocates memory from the operating system). * - * This class should only be used by AIThreadLocalData (and LLMutexRootPool - * when APR_HAS_THREADS isn't defined). + * This class should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase + * (and LLMutexRootPool when APR_HAS_THREADS isn't defined). */ class LL_COMMON_API AIAPRRootPool : public AIAPRInitialization, public AIAPRPool { private: friend class AIThreadLocalData; + friend class AIThreadSafeSimpleDCRootPool_pbase; #if !APR_HAS_THREADS friend class LLMutexRootPool; #endif - //! Construct a root memory pool. Should only be used by AIThreadLocalData. + //! Construct a root memory pool. + // Should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase. AIAPRRootPool(void); ~AIAPRRootPool(); diff --git a/linden/indra/llcommon/aithreadsafe.h b/linden/indra/llcommon/aithreadsafe.h new file mode 100644 index 000000000..e1b93ba48 --- /dev/null +++ b/linden/indra/llcommon/aithreadsafe.h @@ -0,0 +1,463 @@ +/** + * @file aithreadsafe.h + * @brief Implementation of AIThreadSafe, AIReadAccessConst, AIReadAccess and AIWriteAccess. + * + * CHANGELOG + * and additional copyright holders. + * + * 31/03/2010 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AITHREADSAFE_H +#define AITHREADSAFE_H + +#include <new> + +#include "llthread.h" +#include "llerror.h" + +template<typename T> struct AIReadAccessConst; +template<typename T> struct AIReadAccess; +template<typename T> struct AIWriteAccess; +template<typename T> struct AIAccess; + +template<typename T> +class AIThreadSafeBits +{ +private: + // AIThreadSafe is a wrapper around an instance of T. + // Because T might not have a default constructor, it is constructed + // 'in place', with placement new, in the memory reserved here. + // + // Make sure that the memory that T will be placed in is properly + // aligned by using an array of long's. + long mMemory[(sizeof(T) + sizeof(long) - 1) / sizeof(long)]; + +public: + // The wrapped objects are constructed in-place with placement new *outside* + // of this object (by AITHREADSAFE macro(s) or derived classes). + // However, we are responsible for the destruction of the wrapped object. + ~AIThreadSafeBits() { ptr()->~T(); } + + // Only for use by AITHREADSAFE, see below. + void* memory() const { return const_cast<long*>(&mMemory[0]); } + +protected: + // Accessors. + T const* ptr() const { return reinterpret_cast<T const*>(mMemory); } + T* ptr() { return reinterpret_cast<T*>(mMemory); } +}; + +/** + * @brief A wrapper class for objects that need to be accessed by more than one thread, allowing concurrent readers. + * + * Use AITHREADSAFE to define instances of any type, and use AIReadAccessConst, + * AIReadAccess and AIWriteAccess to get access to the instance. + * + * For example, + * + * <code> + * class Foo { public: Foo(int, int); }; + * + * AITHREADSAFE(Foo, foo, (2, 3)); + * + * AIReadAccess<Foo> foo_r(foo); + * // Use foo_r-> for read access. + * + * AIWriteAccess<Foo> foo_w(foo); + * // Use foo_w-> for write access. + * </code> + * + * If <code>foo</code> is constant, you have to use <code>AIReadAccessConst<Foo></code>. + * + * It is possible to pass access objects to a function that + * downgrades the access, for example: + * + * <code> + * void readfunc(AIReadAccess const& access); + * + * AIWriteAccess<Foo> foo_w(foo); + * readfunc(foo_w); // readfunc will perform read access to foo_w. + * </code> + * + * If <code>AIReadAccess</code> is non-const, you can upgrade the access by creating + * an <code>AIWriteAccess</code> object from it. For example: + * + * <code> + * AIWriteAccess<Foo> foo_w(foo_r); + * </code> + * + * This API is Robust(tm). If you try anything that could result in problems, + * it simply won't compile. The only mistake you can still easily make is + * to obtain write access to an object when it is not needed, or to unlock + * an object in between accesses while the state of the object should be + * preserved. For example: + * + * <code> + * // This resets foo to point to the first file and then returns that. + * std::string filename = AIWriteAccess<Foo>(foo)->get_first_filename(); + * + * // WRONG! The state between calling get_first_filename and get_next_filename should be preserved! + * + * AIWriteAccess<Foo> foo_w(foo); // Wrong. The code below only needs read-access. + * while (!filename.empty()) + * { + * something(filename); + * filename = foo_w->next_filename(); + * } + * </code> + * + * Correct would be + * + * <code> + * AIReadAccess<Foo> foo_r(foo); + * std::string filename = AIWriteAccess<Foo>(foo_r)->get_first_filename(); + * while (!filename.empty()) + * { + * something(filename); + * filename = foo_r->next_filename(); + * } + * </code> + * + */ +template<typename T> +class AIThreadSafe : public AIThreadSafeBits<T> +{ +protected: + // Only these may access the object (through ptr()). + friend struct AIReadAccessConst<T>; + friend struct AIReadAccess<T>; + friend struct AIWriteAccess<T>; + + // Locking control. + AIRWLock mRWLock; + + // For use by AIThreadSafeDC + AIThreadSafe(void) { } + AIThreadSafe(AIAPRPool& parent) : mRWLock(parent) { } + +public: + // Only for use by AITHREADSAFE, see below. + AIThreadSafe(T* object) { llassert(object == AIThreadSafeBits<T>::ptr()); } +}; + +/** + * @brief Instantiate an static, global or local object of a given type wrapped in AIThreadSafe, using an arbitrary constructor. + * + * For example, instead of doing + * + * <code> + * Foo foo(x, y); + * static Bar bar; + * </code> + * + * One can instantiate a thread-safe instance with + * + * <code> + * AITHREADSAFE(Foo, foo, (x, y)); + * static AITHREADSAFE(Bar, bar, ); + * </code> + * + * Note: This macro does not allow to allocate such object on the heap. + * If that is needed, have a look at AIThreadSafeDC. + */ +#define AITHREADSAFE(type, var, paramlist) AIThreadSafe<type> var(new (var.memory()) type paramlist) + +/** + * @brief A wrapper class for objects that need to be accessed by more than one thread. + * + * This class is the same as an AIThreadSafe wrapper, except that it can only + * be used for default constructed objects. + * + * For example, instead of + * + * <code> + * Foo foo; + * </code> + * + * One would use + * + * <code> + * AIThreadSafeDC<Foo> foo; + * </code> + * + * The advantage over AITHREADSAFE is that this object can be allocated with + * new on the heap. For example: + * + * <code> + * AIThreadSafeDC<Foo>* ptr = new AIThreadSafeDC<Foo>; + * </code> + * + * which is not possible with AITHREADSAFE. + */ +template<typename T> +class AIThreadSafeDC : public AIThreadSafe<T> +{ +public: + // Construct a wrapper around a default constructed object. + AIThreadSafeDC(void) { new (AIThreadSafe<T>::ptr()) T; } +}; + +/** + * @brief Read lock object and provide read access. + */ +template<typename T> +struct AIReadAccessConst +{ + //! Internal enum for the lock-type of the AI*Access object. + enum state_type + { + readlocked, //!< A AIReadAccessConst or AIReadAccess. + read2writelocked, //!< A AIWriteAccess constructed from a AIReadAccess. + writelocked, //!< A AIWriteAccess constructed from a AIThreadSafe. + write2writelocked //!< A AIWriteAccess constructed from (the AIReadAccess base class of) a AIWriteAccess. + }; + + //! Construct a AIReadAccessConst from a constant AIThreadSafe. + AIReadAccessConst(AIThreadSafe<T> const& wrapper) + : mWrapper(const_cast<AIThreadSafe<T>&>(wrapper)), + mState(readlocked) + { + mWrapper.mRWLock.rdlock(); + } + + //! Destruct the AI*Access object. + // These should never be dynamically allocated, so there is no need to make this virtual. + ~AIReadAccessConst() + { + if (mState == readlocked) + mWrapper.mRWLock.rdunlock(); + else if (mState == writelocked) + mWrapper.mRWLock.wrunlock(); + else if (mState == read2writelocked) + mWrapper.mRWLock.wr2rdlock(); + } + + //! Access the underlaying object for read access. + T const* operator->() const { return mWrapper.ptr(); } + + //! Access the underlaying object for read access. + T const& operator*() const { return *mWrapper.ptr(); } + +protected: + //! Constructor used by AIReadAccess. + AIReadAccessConst(AIThreadSafe<T>& wrapper, state_type state) + : mWrapper(wrapper), mState(state) { } + + AIThreadSafe<T>& mWrapper; //!< Reference to the object that we provide access to. + state_type const mState; //!< The lock state that mWrapper is in. + +private: + // Disallow copy constructing directly. + AIReadAccessConst(AIReadAccessConst const&); +}; + +/** + * @brief Read lock object and provide read access, with possible promotion to write access. + */ +template<typename T> +struct AIReadAccess : public AIReadAccessConst<T> +{ + typedef typename AIReadAccessConst<T>::state_type state_type; + using AIReadAccessConst<T>::readlocked; + + //! Construct a AIReadAccess from a non-constant AIThreadSafe. + AIReadAccess(AIThreadSafe<T>& wrapper) : AIReadAccessConst<T>(wrapper, readlocked) { this->mWrapper.mRWLock.rdlock(); } + +protected: + //! Constructor used by AIWriteAccess. + AIReadAccess(AIThreadSafe<T>& wrapper, state_type state) : AIReadAccessConst<T>(wrapper, state) { } + + friend class AIWriteAccess<T>; +}; + +/** + * @brief Write lock object and provide read/write access. + */ +template<typename T> +struct AIWriteAccess : public AIReadAccess<T> +{ + using AIReadAccessConst<T>::readlocked; + using AIReadAccessConst<T>::read2writelocked; + using AIReadAccessConst<T>::writelocked; + using AIReadAccessConst<T>::write2writelocked; + + //! Construct a AIWriteAccess from a non-constant AIThreadSafe. + AIWriteAccess(AIThreadSafe<T>& wrapper) : AIReadAccess<T>(wrapper, writelocked) { this->mWrapper.mRWLock.wrlock();} + + //! Promote read access to write access. + explicit AIWriteAccess(AIReadAccess<T>& access) + : AIReadAccess<T>(access.mWrapper, (access.mState == readlocked) ? read2writelocked : write2writelocked) + { + if (this->mState == read2writelocked) + { + this->mWrapper.mRWLock.rd2wrlock(); + } + } + + //! Access the underlaying object for (read and) write access. + T* operator->() const { return this->mWrapper.ptr(); } + + //! Access the underlaying object for (read and) write access. + T& operator*() const { return *this->mWrapper.ptr(); } +}; + +/** + * @brief A wrapper class for objects that need to be accessed by more than one thread. + * + * Use AITHREADSAFESIMPLE to define instances of any type, and use AIAccess + * to get access to the instance. + * + * For example, + * + * <code> + * class Foo { public: Foo(int, int); }; + * + * AITHREADSAFESIMPLE(Foo, foo, (2, 3)); + * + * AIAccess<Foo> foo_w(foo); + * // Use foo_w-> for read and write access. + * + * See also AIThreadSafe + */ +template<typename T> +class AIThreadSafeSimple : public AIThreadSafeBits<T> +{ +protected: + // Only this one may access the object (through ptr()). + friend struct AIAccess<T>; + + // Locking control. + LLMutex mMutex; + + // For use by AIThreadSafeSimpleDC + AIThreadSafeSimple(void) { } + AIThreadSafeSimple(AIAPRPool& parent) : mMutex(parent) { } + +public: + // Only for use by AITHREADSAFESIMPLE, see below. + AIThreadSafeSimple(T* object) { llassert(object == AIThreadSafeBits<T>::ptr()); } +}; + +/** + * @brief Instantiate an static, global or local object of a given type wrapped in AIThreadSafeSimple, using an arbitrary constructor. + * + * For example, instead of doing + * + * <code> + * Foo foo(x, y); + * static Bar bar; + * </code> + * + * One can instantiate a thread-safe instance with + * + * <code> + * AITHREADSAFESIMPLE(Foo, foo, (x, y)); + * static AITHREADSAFESIMPLE(Bar, bar, ); + * </code> + * + * Note: This macro does not allow to allocate such object on the heap. + * If that is needed, have a look at AIThreadSafeSimpleDC. + */ +#define AITHREADSAFESIMPLE(type, var, paramlist) AIThreadSafeSimple<type> var(new (var.memory()) type paramlist) + +/** + * @brief A wrapper class for objects that need to be accessed by more than one thread. + * + * This class is the same as an AIThreadSafeSimple wrapper, except that it can only + * be used for default constructed objects. + * + * For example, instead of + * + * <code> + * Foo foo; + * </code> + * + * One would use + * + * <code> + * AIThreadSafeSimpleDC<Foo> foo; + * </code> + * + * The advantage over AITHREADSAFESIMPLE is that this object can be allocated with + * new on the heap. For example: + * + * <code> + * AIThreadSafeSimpleDC<Foo>* ptr = new AIThreadSafeSimpleDC<Foo>; + * </code> + * + * which is not possible with AITHREADSAFESIMPLE. + */ +template<typename T> +class AIThreadSafeSimpleDC : public AIThreadSafeSimple<T> +{ +public: + // Construct a wrapper around a default constructed object. + AIThreadSafeSimpleDC(void) { new (AIThreadSafeSimple<T>::ptr()) T; } + +protected: + // For use by AIThreadSafeSimpleDCRootPool + AIThreadSafeSimpleDC(AIAPRPool& parent) : AIThreadSafeSimple<T>(parent) { new (AIThreadSafeSimple<T>::ptr()) T; } +}; + +// Helper class for AIThreadSafeSimpleDCRootPool to assure initialization of +// the root pool before constructing AIThreadSafeSimpleDC. +class AIThreadSafeSimpleDCRootPool_pbase +{ +protected: + AIAPRRootPool mRootPool; + +private: + template<typename T> friend class AIThreadSafeSimpleDCRootPool; + AIThreadSafeSimpleDCRootPool_pbase(void) { } +}; + +/** + * @brief A wrapper class for objects that need to be accessed by more than one thread. + * + * The same as AIThreadSafeSimpleDC except that this class creates its own AIAPRRootPool + * for the internally used mutexes and condition, instead of using the current threads + * root pool. The advantage of this is that it can be used for objects that need to + * be accessed from the destructors of global objects (after main). The disadvantage + * is that it's less efficient to use your own root pool, therefore it's use should be + * restricted to those cases where it is absolutely necessary. + */ +template<typename T> +class AIThreadSafeSimpleDCRootPool : private AIThreadSafeSimpleDCRootPool_pbase, public AIThreadSafeSimpleDC<T> +{ +public: + // Construct a wrapper around a default constructed object, using memory allocated + // from the operating system for the internal APR objects (mutexes and conditional), + // as opposed to allocated from the current threads root pool. + AIThreadSafeSimpleDCRootPool(void) : + AIThreadSafeSimpleDCRootPool_pbase(), + AIThreadSafeSimpleDC<T>(mRootPool) { } +}; + +/** + * @brief Write lock object and provide read/write access. + */ +template<typename T> +struct AIAccess +{ + //! Construct a AIAccess from a non-constant AIThreadSafeSimple. + AIAccess(AIThreadSafeSimple<T>& wrapper) : mWrapper(wrapper) { this->mWrapper.mMutex.lock(); } + + //! Access the underlaying object for (read and) write access. + T* operator->() const { return this->mWrapper.ptr(); } + + //! Access the underlaying object for (read and) write access. + T& operator*() const { return *this->mWrapper.ptr(); } + + ~AIAccess() { this->mWrapper.mMutex.unlock(); } + +protected: + AIThreadSafeSimple<T>& mWrapper; //!< Reference to the object that we provide access to. + +private: + // Disallow copy constructing directly. + AIAccess(AIAccess const&); +}; + +#endif diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index 8708929b3..1e982cc1e 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h @@ -235,6 +235,101 @@ class LL_COMMON_API LLMutexLock LLMutexBase* mMutex; }; +class AIRWLock +{ +public: + AIRWLock(AIAPRPool& parent = LLThread::tldata().mRootPool) : + mWriterWaitingMutex(parent), mNoHoldersCondition(parent), mHoldersCount(0), mWriterIsWaiting(false) { } + +private: + LLMutex mWriterWaitingMutex; //!< This mutex is locked while some writer is waiting for access. + LLCondition mNoHoldersCondition; //!< Access control for mHoldersCount. Condition true when there are no more holders. + int mHoldersCount; //!< Number of readers or -1 if a writer locked this object. + // This is volatile because we read it outside the critical area of mWriterWaitingMutex, at [1]. + // That means that other threads can change it while we are already in the (inlined) function rdlock. + // Without volatile, the following assembly would fail: + // register x = mWriterIsWaiting; + // /* some thread changes mWriterIsWaiting */ + // if (x ... + // However, because the function is fuzzy to begin with (we don't mind that this race + // condition exists) it would work fine without volatile. So, basically it's just here + // out of principle ;). -- Aleric + bool volatile mWriterIsWaiting; //!< True when there is a writer waiting for write access. + +public: + void rdlock(bool high_priority = false) + { + // Give a writer a higher priority (kinda fuzzy). + if (mWriterIsWaiting && !high_priority) // [1] If there is a writer interested, + { + mWriterWaitingMutex.lock(); // [2] then give it precedence and wait here. + // If we get here then the writer got it's access; mHoldersCount == -1. + mWriterWaitingMutex.unlock(); + } + mNoHoldersCondition.lock(); // [3] Get exclusive access to mHoldersCount. + while (mHoldersCount == -1) // [4] + { + mNoHoldersCondition.wait(); // [5] Wait till mHoldersCount is (or just was) 0. + } + ++mHoldersCount; // One more reader. + mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. + } + void rdunlock(void) + { + mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. + if (--mHoldersCount == 0) // Was this the last reader? + { + mNoHoldersCondition.signal(); // Tell waiting threads, see [5], [6] and [7]. + } + mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. + } + void wrlock(void) + { + mWriterWaitingMutex.lock(); // Block new readers, see [2], + mWriterIsWaiting = true; // from this moment on, see [1]. + mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. + while (mHoldersCount != 0) // Other readers or writers have this lock? + { + mNoHoldersCondition.wait(); // [6] Wait till mHoldersCount is (or just was) 0. + } + mWriterIsWaiting = false; // Stop checking the lock for new readers, see [1]. + mWriterWaitingMutex.unlock(); // Release blocked readers, they will still hang at [3]. + mHoldersCount = -1; // We are a writer now (will cause a hang at [5], see [4]). + mNoHoldersCondition.unlock(); // Release lock on mHolders (readers go from [3] to [5]). + } + void wrunlock(void) + { + mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. + mHoldersCount = 0; // We have no writer anymore. + mNoHoldersCondition.signal(); // Tell waiting threads, see [5], [6] and [7]. + mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. + } + void rd2wrlock(void) + { + mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. Blocks new readers at [3]. + if (--mHoldersCount > 0) // Any other reads left? + { + mWriterWaitingMutex.lock(); // Block new readers, see [2], + mWriterIsWaiting = true; // from this moment on, see [1]. + while (mHoldersCount != 0) // Other readers (still) have this lock? + { + mNoHoldersCondition.wait(); // [7] Wait till mHoldersCount is (or just was) 0. + } + mWriterIsWaiting = false; // Stop checking the lock for new readers, see [1]. + mWriterWaitingMutex.unlock(); // Release blocked readers, they will still hang at [3]. + } + mHoldersCount = -1; // We are a writer now (will cause a hang at [5], see [4]). + mNoHoldersCondition.unlock(); // Release lock on mHolders (readers go from [3] to [5]). + } + void wr2rdlock(void) + { + mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. + mHoldersCount = 1; // Turn writer into a reader. + mNoHoldersCondition.signal(); // Tell waiting readers, see [5]. + mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. + } +}; + //============================================================================ void LLThread::lockData() @@ -247,7 +342,6 @@ void LLThread::unlockData() mRunCondition->unlock(); } - //============================================================================ // see llmemory.h for LLPointer<> definition From dd4630a13ce0cac5080cd1e0f442afd5b534d71f Mon Sep 17 00:00:00 2001 From: Armin Weatherwax <Armin.Weatherwax@gmail.com> Date: Fri, 19 Nov 2010 11:38:23 +0100 Subject: [PATCH 219/239] fix: Bug #721: Search lags --- linden/indra/newview/llfloaterdirectory.cpp | 4 +++- linden/indra/newview/llpanelavatar.cpp | 11 +++++++++++ linden/indra/newview/llpanelavatar.h | 4 ++-- linden/indra/newview/llpaneldirfind.cpp | 8 ++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/linden/indra/newview/llfloaterdirectory.cpp b/linden/indra/newview/llfloaterdirectory.cpp index 8018c31f0..7c8ddf1d1 100644 --- a/linden/indra/newview/llfloaterdirectory.cpp +++ b/linden/indra/newview/llfloaterdirectory.cpp @@ -466,7 +466,9 @@ void LLFloaterDirectory::setVisible(BOOL visible) void LLFloaterDirectory::onClose(bool app_quitting) { - setVisible(FALSE); + LLFloater::onClose(app_quitting); + + //setVisible(FALSE); //meaning you hide 3 web browsers - one SLPlugin each } // static diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp index e47ae2a14..6110e4410 100644 --- a/linden/indra/newview/llpanelavatar.cpp +++ b/linden/indra/newview/llpanelavatar.cpp @@ -416,6 +416,7 @@ BOOL LLPanelAvatarWeb::postBuild(void) childSetControlName("auto_load","AutoLoadWebProfiles"); mWebBrowser = getChild<LLMediaCtrl>("profile_html"); + mWebBrowser->addObserver(this); // links open in internally @@ -490,7 +491,17 @@ void LLPanelAvatarWeb::refresh() mNavigateTo = ""; } } +void LLPanelAvatarWeb::onVisibilityChange(BOOL new_visibility) +{ + LLPluginClassMedia::EPriority new_priority; + if (new_visibility) + new_priority = LLPluginClassMedia::PRIORITY_NORMAL; + else + new_priority = LLPluginClassMedia::PRIORITY_HIDDEN; + + mWebBrowser->getMediaPlugin()->setPriority(new_priority); +} void LLPanelAvatarWeb::enableControls(BOOL self) { diff --git a/linden/indra/newview/llpanelavatar.h b/linden/indra/newview/llpanelavatar.h index b687cd8d3..9a2f450e7 100644 --- a/linden/indra/newview/llpanelavatar.h +++ b/linden/indra/newview/llpanelavatar.h @@ -76,7 +76,6 @@ class LLPanelAvatarTab : public LLPanel /*virtual*/ void draw(); LLPanelAvatar* getPanelAvatar() const { return mPanelAvatar; } - void setDataRequested(bool requested) { mDataRequested = requested; } bool isDataRequested() const { return mDataRequested; } @@ -143,14 +142,15 @@ class LLPanelAvatarWeb : LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar); /*virtual*/ ~LLPanelAvatarWeb(); /*virtual*/ BOOL postBuild(void); - /*virtual*/ void refresh(); + /*virtual*/ void onVisibilityChange(BOOL new_visibility); void enableControls(BOOL own_avatar); void setWebURL(std::string url); void load(std::string url); + static void onURLKeystroke(LLLineEditor* editor, void* data); static void onCommitLoad(LLUICtrl* ctrl, void* data); static void onCommitURL(LLUICtrl* ctrl, void* data); diff --git a/linden/indra/newview/llpaneldirfind.cpp b/linden/indra/newview/llpaneldirfind.cpp index 342ffec61..719a7a06d 100644 --- a/linden/indra/newview/llpaneldirfind.cpp +++ b/linden/indra/newview/llpaneldirfind.cpp @@ -62,6 +62,7 @@ #include "lluictrlfactory.h" #include "llfloaterdirectory.h" #include "llpaneldirbrowser.h" +#include "llpluginclassmedia.h" #include <boost/tokenizer.hpp> #if LL_WINDOWS @@ -196,10 +197,17 @@ void LLPanelDirFind::draw() // virtual void LLPanelDirFind::onVisibilityChange(BOOL new_visibility) { + LLPluginClassMedia::EPriority new_priority; if (new_visibility) { mFloaterDirectory->hideAllDetailPanels(); + new_priority = LLPluginClassMedia::PRIORITY_NORMAL; } + else + new_priority = LLPluginClassMedia::PRIORITY_HIDDEN; + + mWebBrowser->getMediaPlugin()->setPriority(new_priority); + LLPanel::onVisibilityChange(new_visibility); } From 1d15c37689b15b2005ff97738e259d63b7e6c446 Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 20 Nov 2010 14:13:19 +0200 Subject: [PATCH 220/239] Fix #705 (SNOW-717): Prevent mouse cursor flicker Patch by Lance Corrimal taken from SNOW-717. --- linden/doc/contributions.txt | 2 ++ linden/indra/newview/lltoolpie.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index cd6544a98..bb1c98b27 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -338,6 +338,8 @@ Khyota Wulluf Kunnis Basiat VWR-82 VWR-102 +Lance Corrimal + SNOW-717 Lisa Lowe CT-218 CT-219 diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp index 296d1bb13..34735a391 100644 --- a/linden/indra/newview/lltoolpie.cpp +++ b/linden/indra/newview/lltoolpie.cpp @@ -645,8 +645,6 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) } */ - - gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); LLViewerObject *object = NULL; LLViewerObject *parent = NULL; @@ -697,9 +695,14 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) { gViewerWindow->getWindow()->setCursor(UI_CURSOR_HAND); } + else + { + gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); + } } else { + gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW); // We need to clear media hover flag if (LLViewerMediaFocus::getInstance()->getMouseOverFlag()) { From 0e81c179bc3d4f0b5eef09eb368a1662c7feb4fd Mon Sep 17 00:00:00 2001 From: thickbrick <thickbrick.sleaford@gmail.com> Date: Sat, 20 Nov 2010 14:55:44 +0200 Subject: [PATCH 221/239] Fix #724: Snap guides in scale manipulator not shown. --- linden/indra/newview/llmanipscale.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linden/indra/newview/llmanipscale.cpp b/linden/indra/newview/llmanipscale.cpp index 268e4310e..b38abe441 100644 --- a/linden/indra/newview/llmanipscale.cpp +++ b/linden/indra/newview/llmanipscale.cpp @@ -1523,7 +1523,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) F32 max_subdivisions = sGridMaxSubdivisionLevel; F32 grid_alpha = gSavedSettings.getF32("GridOpacity"); - F32 max_point_on_scale_line = partToMaxScale(mManipPart, bbox); + F32 max_point_on_scale_line = llmin(partToMaxScale(mManipPart, bbox), LLWorld::getInstance()->getRegionWidthInMeters()); LLVector3 drag_point = gAgent.getPosAgentFromGlobal(mDragPointGlobal); updateGridSettings(); From 04e9ce0fc1f242af1581751463a450dd680d4ea3 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 23 Nov 2010 16:28:19 -0700 Subject: [PATCH 222/239] Revert "Ported fix for Apply button not working correctly when changing show group in profile option in the group window from Ascent Viewer" since it actually causes the bug it's supposed to fix This reverts commit 46bcc05dfd4a37c27a5db6146c5da1b632106c39. --- linden/indra/newview/llpanelgroupgeneral.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/linden/indra/newview/llpanelgroupgeneral.cpp b/linden/indra/newview/llpanelgroupgeneral.cpp index 6878f84b3..72a485c34 100644 --- a/linden/indra/newview/llpanelgroupgeneral.cpp +++ b/linden/indra/newview/llpanelgroupgeneral.cpp @@ -561,10 +561,6 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) gIMMgr->saveIgnoreGroup(); } - mCtrlReceiveNotices->resetDirty(); //resetDirty() here instead of in update because this is where the settings - mCtrlListGroup->resetDirty(); //are actually being applied. onCommitUserOnly doesn't call updateChanged directly. - mCtrlReceiveChat->resetDirty(); - mChanged = FALSE; return true; @@ -778,21 +774,14 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) { mCtrlReceiveNotices->setEnabled(mAllowEdit); } + mCtrlReceiveNotices->resetDirty(); } if (mCtrlReceiveChat) { mCtrlReceiveChat->setVisible(is_member); mCtrlReceiveChat->setEnabled(TRUE); - } - - if (mCtrlListGroup) - { - mCtrlListGroup->setVisible(is_member); - if (is_member) - { - mCtrlListGroup->setEnabled(mAllowEdit); - } + mCtrlReceiveChat->resetDirty(); } From a17ac424f23a3151d66d2a313f85da948b421173 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 23 Nov 2010 17:27:58 -0700 Subject: [PATCH 223/239] Fixed group list not updating when the group profile is changed (#644) --- linden/indra/newview/llpanelgroupgeneral.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/linden/indra/newview/llpanelgroupgeneral.cpp b/linden/indra/newview/llpanelgroupgeneral.cpp index 72a485c34..7ff25a7b9 100644 --- a/linden/indra/newview/llpanelgroupgeneral.cpp +++ b/linden/indra/newview/llpanelgroupgeneral.cpp @@ -561,6 +561,14 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) gIMMgr->saveIgnoreGroup(); } + // Make sure we update the group list in our contacts list and our IMs -- MC + if (gIMMgr) + { + // update the talk view + gIMMgr->refresh(); + } + gAgent.fireEvent(new LLEvent(&gAgent, "new group"), ""); + mChanged = FALSE; return true; From 0d654102fcb5b1aae70e7c3f565ab208455f8f36 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted <McCabe.Maxsted@gmail.com> Date: Tue, 23 Nov 2010 19:41:47 -0700 Subject: [PATCH 224/239] Fixed Windows compile error introduced in fe9a3d2b. Also made sure winsock2.h is always included before windows.h throughout the source to prevent collisions --- linden/indra/llcommon/aiaprpool.h | 4 +++- linden/indra/llcommon/llerror.cpp | 2 ++ linden/indra/llcommon/llfile.cpp | 2 ++ linden/indra/llcommon/llfindlocale.cpp | 2 ++ linden/indra/llcommon/llmemory.cpp | 2 ++ linden/indra/llcommon/llprocesslauncher.h | 2 ++ linden/indra/llplugin/llpluginsharedmemory.cpp | 2 ++ linden/indra/llplugin/slplugin/slplugin.cpp | 2 ++ linden/indra/llvfs/llpidlock.h | 2 ++ linden/indra/llwindow/GL/glh_extensions.h | 2 ++ linden/indra/media_plugins/webkit/windows_volume_catcher.cpp | 2 ++ linden/indra/test_apps/llplugintest/demo_plugin.cpp | 2 ++ linden/indra/win_crash_logger/StdAfx.h | 2 ++ linden/indra/win_crash_logger/llcrashloggerwindows.h | 2 ++ linden/indra/win_updater/updater.cpp | 2 ++ 15 files changed, 31 insertions(+), 1 deletion(-) diff --git a/linden/indra/llcommon/aiaprpool.h b/linden/indra/llcommon/aiaprpool.h index 72e9ddbd4..ac523a9b9 100644 --- a/linden/indra/llcommon/aiaprpool.h +++ b/linden/indra/llcommon/aiaprpool.h @@ -38,7 +38,9 @@ #define AIAPRPOOL_H #ifdef LL_WINDOWS -#include <ws2tcpip.h> // Needed before including apr_portable.h +//#include <ws2tcpip.h> +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> // Needed before including apr_portable.h #endif #include "apr_portable.h" diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp index b9be3708d..a9587c61b 100644 --- a/linden/indra/llcommon/llerror.cpp +++ b/linden/indra/llcommon/llerror.cpp @@ -46,6 +46,8 @@ # include <unistd.h> #endif // !LL_WINDOWS #if LL_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> # include <windows.h> #endif // LL_WINDOWS #include <vector> diff --git a/linden/indra/llcommon/llfile.cpp b/linden/indra/llcommon/llfile.cpp index 2a76f7fb8..6b6863019 100644 --- a/linden/indra/llcommon/llfile.cpp +++ b/linden/indra/llcommon/llfile.cpp @@ -34,6 +34,8 @@ */ #if LL_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #endif diff --git a/linden/indra/llcommon/llfindlocale.cpp b/linden/indra/llcommon/llfindlocale.cpp index 505f5c540..71675af01 100644 --- a/linden/indra/llcommon/llfindlocale.cpp +++ b/linden/indra/llcommon/llfindlocale.cpp @@ -39,6 +39,8 @@ #include <ctype.h> #ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #include <winnt.h> #endif diff --git a/linden/indra/llcommon/llmemory.cpp b/linden/indra/llcommon/llmemory.cpp index 74004b019..2b01442be 100644 --- a/linden/indra/llcommon/llmemory.cpp +++ b/linden/indra/llcommon/llmemory.cpp @@ -33,6 +33,8 @@ #include "linden_common.h" #if defined(LL_WINDOWS) +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> # include <windows.h> # include <psapi.h> #elif defined(LL_DARWIN) diff --git a/linden/indra/llcommon/llprocesslauncher.h b/linden/indra/llcommon/llprocesslauncher.h index b72be2713..9833a1304 100644 --- a/linden/indra/llcommon/llprocesslauncher.h +++ b/linden/indra/llcommon/llprocesslauncher.h @@ -34,6 +34,8 @@ #define LL_LLPROCESSLAUNCHER_H #if LL_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #endif diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp index 883d7b634..6becb8dff 100755 --- a/linden/indra/llplugin/llpluginsharedmemory.cpp +++ b/linden/indra/llplugin/llpluginsharedmemory.cpp @@ -84,6 +84,8 @@ #include <sys/mman.h> #include <errno.h> #elif USE_WIN32_SHARED_MEMORY +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #endif // USE_APR_SHARED_MEMORY diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp index cca8ead8f..878577bf7 100755 --- a/linden/indra/llplugin/slplugin/slplugin.cpp +++ b/linden/indra/llplugin/slplugin/slplugin.cpp @@ -78,6 +78,8 @@ static void crash_handler(int sig) #endif #if LL_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> //////////////////////////////////////////////////////////////////////////////// // Our exception handler - will probably just exit and the host application diff --git a/linden/indra/llvfs/llpidlock.h b/linden/indra/llvfs/llpidlock.h index efcfd9150..6103599b1 100755 --- a/linden/indra/llvfs/llpidlock.h +++ b/linden/indra/llvfs/llpidlock.h @@ -39,6 +39,8 @@ class LLFrameTimer; #if LL_WINDOWS //For windows platform. +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #else //Everyone Else diff --git a/linden/indra/llwindow/GL/glh_extensions.h b/linden/indra/llwindow/GL/glh_extensions.h index b936b5d30..5b149c992 100644 --- a/linden/indra/llwindow/GL/glh_extensions.h +++ b/linden/indra/llwindow/GL/glh_extensions.h @@ -17,6 +17,8 @@ #include <stdio.h> #ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> # include <windows.h> #endif diff --git a/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp index f1afea7ee..64f70c419 100644 --- a/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp +++ b/linden/indra/media_plugins/webkit/windows_volume_catcher.cpp @@ -34,6 +34,8 @@ */ #include "volume_catcher.h" +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #include "llmemory.h" class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl> diff --git a/linden/indra/test_apps/llplugintest/demo_plugin.cpp b/linden/indra/test_apps/llplugintest/demo_plugin.cpp index 772fa16ad..fd67a5898 100644 --- a/linden/indra/test_apps/llplugintest/demo_plugin.cpp +++ b/linden/indra/test_apps/llplugintest/demo_plugin.cpp @@ -33,6 +33,8 @@ #include "linden_common.h" #ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #endif diff --git a/linden/indra/win_crash_logger/StdAfx.h b/linden/indra/win_crash_logger/StdAfx.h index 021a995f5..79198c256 100644 --- a/linden/indra/win_crash_logger/StdAfx.h +++ b/linden/indra/win_crash_logger/StdAfx.h @@ -46,6 +46,8 @@ // Windows Header Files: +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> // C RunTime Header Files diff --git a/linden/indra/win_crash_logger/llcrashloggerwindows.h b/linden/indra/win_crash_logger/llcrashloggerwindows.h index e6a9c77d5..f2a877e25 100644 --- a/linden/indra/win_crash_logger/llcrashloggerwindows.h +++ b/linden/indra/win_crash_logger/llcrashloggerwindows.h @@ -34,6 +34,8 @@ #define LLCRASHLOGGERWINDOWS_H #include "llcrashlogger.h" +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include "windows.h" #include "llstring.h" diff --git a/linden/indra/win_updater/updater.cpp b/linden/indra/win_updater/updater.cpp index 503127082..c6fa3c8dc 100644 --- a/linden/indra/win_updater/updater.cpp +++ b/linden/indra/win_updater/updater.cpp @@ -39,6 +39,8 @@ // *TODO: Switch to fopen_s, strtok_s, etc. #define _CRT_SECURE_NO_DEPRECATE +# define WIN32_LEAN_AND_MEAN +# include <winsock2.h> #include <windows.h> #include <wininet.h> #include <stdio.h> From 8a3c0705c2a0630a5122eb662d8226c79d8a060e Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 26 Nov 2010 16:11:25 +0100 Subject: [PATCH 225/239] IMP-734: SNOW-707: Start up crash of LLErrorThread due to corrupt map in CheckLevelMap Wrapped gSettings and the global objects returned by Settings::get() and Globals::get() in AIThreadSafe, forcing thread-safe access. --- linden/doc/contributions.txt | 1 + linden/indra/llcommon/llapp.cpp | 1 - linden/indra/llcommon/llapp.h | 7 +- linden/indra/llcommon/llerror.cpp | 315 +++++++++++----------- linden/indra/llcommon/llerrorcontrol.h | 6 +- linden/indra/llxml/llcontrol.cpp | 10 +- linden/indra/llxml/llcontrol.h | 6 +- linden/indra/llxml/llcontrolgroupreader.h | 2 +- linden/indra/newview/llappviewer.cpp | 41 +-- linden/indra/newview/llappviewer.h | 12 +- linden/indra/newview/llstartup.cpp | 2 +- linden/indra/newview/llviewercontrol.cpp | 5 +- linden/indra/newview/llviewercontrol.h | 4 +- 13 files changed, 213 insertions(+), 199 deletions(-) diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index d18b5ba2e..9712c6ec7 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -94,6 +94,7 @@ Aleric Inglewood IMP-692 IMP-701 IMP-712 + IMP-734 Alissa Sabre VWR-81 VWR-83 diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp index eedc50316..08b145c5a 100644 --- a/linden/indra/llcommon/llapp.cpp +++ b/linden/indra/llcommon/llapp.cpp @@ -91,7 +91,6 @@ LLAppChildCallback LLApp::sDefaultChildCallback = NULL; LLApp::LLApp() : mThreadErrorp(NULL) { commonCtor(); - startErrorThread(); } void LLApp::commonCtor() diff --git a/linden/indra/llcommon/llapp.h b/linden/indra/llcommon/llapp.h index 96112c971..0f5825e96 100644 --- a/linden/indra/llcommon/llapp.h +++ b/linden/indra/llcommon/llapp.h @@ -253,9 +253,12 @@ class LL_COMMON_API LLApp */ void stepFrame(); -private: + /** + * @ brief This method is called once as soon as logging is initialized. + */ void startErrorThread(); - + +private: void setupErrorHandling(); // Do platform-specific error-handling setup (signals, structured exceptions) static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred. static void runSyncErrorHandler(); // run IMMEDIATELY when we get an error, ran in the context of the faulting thread. diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp index a9587c61b..146ec620b 100644 --- a/linden/indra/llcommon/llerror.cpp +++ b/linden/indra/llcommon/llerror.cpp @@ -61,6 +61,7 @@ #include "llsdserialize.h" #include "llstl.h" #include "lltimer.h" +#include "aithreadsafe.h" extern apr_thread_mutex_t* gCallStacksLogMutexp; @@ -359,12 +360,15 @@ namespace void addCallSite(LLError::CallSite&); void invalidateCallSites(); - static Globals& get(); + static AIThreadSafeSimple<Globals>& get(); // return the one instance of the globals private: CallSiteVector callSites; + friend class AIThreadSafeSimpleDC<Globals>; // Calls constructor. + friend class AIThreadSafeSimple<Globals>; // Calls destructor. + Globals() : messageStreamInUse(false) { } @@ -388,7 +392,7 @@ namespace callSites.clear(); } - Globals& Globals::get() + AIThreadSafeSimple<Globals>& Globals::get() { /* This pattern, of returning a reference to a static function variable, is to ensure that this global is constructed before @@ -396,8 +400,8 @@ namespace is. See C++ FAQ Lite, sections 10.12 through 10.14 */ - static Globals* globals = new Globals; - return *globals; + static AIThreadSafeSimpleDCRootPool<Globals>* ts_globals_ptr = new AIThreadSafeSimpleDCRootPool<Globals>; + return *ts_globals_ptr; } } @@ -426,13 +430,16 @@ namespace LLError int shouldLogCallCounter; - static Settings& get(); + static AIThreadSafeSimple<Settings>& get(); static void reset(); - static Settings* saveAndReset(); - static void restore(Settings*); + static AIThreadSafeSimple<Settings>* saveAndReset(); + static void restore(AIThreadSafeSimple<Settings>*); private: + friend class AIThreadSafeBits<Settings>; // Calls destructor. + friend class AIThreadSafeSimpleDC<Settings>; // Calls constructor. + Settings() : printLocation(false), defaultLevel(LLError::LEVEL_DEBUG), @@ -448,53 +455,42 @@ namespace LLError for_each(recorders.begin(), recorders.end(), DeletePointer()); } - - static Settings*& getPtr(); + + static AIThreadSafeSimple<Settings>* sSettings; }; + + // Pointer to current AIThreadSafeSimple<Settings> object if any (NULL otherwise). + AIThreadSafeSimple<Settings>* Settings::sSettings; - Settings& Settings::get() + AIThreadSafeSimple<Settings>& Settings::get() { - Settings* p = getPtr(); - if (!p) + if (!sSettings) { reset(); - p = getPtr(); } - return *p; + return *sSettings; } void Settings::reset() { - Globals::get().invalidateCallSites(); - - Settings*& p = getPtr(); - delete p; - p = new Settings(); + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + delete sSettings; + sSettings = new AIThreadSafeSimpleDC<Settings>; } - Settings* Settings::saveAndReset() + AIThreadSafeSimple<Settings>* Settings::saveAndReset() { - Globals::get().invalidateCallSites(); - - Settings*& p = getPtr(); - Settings* originalSettings = p; - p = new Settings(); + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + AIThreadSafeSimple<Settings>* originalSettings = sSettings; + sSettings = new AIThreadSafeSimpleDC<Settings>; return originalSettings; } - void Settings::restore(Settings* originalSettings) - { - Globals::get().invalidateCallSites(); - - Settings*& p = getPtr(); - delete p; - p = originalSettings; - } - - Settings*& Settings::getPtr() + void Settings::restore(AIThreadSafeSimple<Settings>* originalSettings) { - static Settings* currentSettings = NULL; - return currentSettings; + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + delete sSettings; + sSettings = originalSettings; } } @@ -598,62 +594,59 @@ namespace LLError commonInit(dir); } + void setPrintLocation(AIAccess<Settings> const& settings_w, bool print) + { + settings_w->printLocation = print; + } + void setPrintLocation(bool print) { - Settings& s = Settings::get(); - s.printLocation = print; + setPrintLocation(AIAccess<Settings>(Settings::get()), print); } void setFatalFunction(FatalFunction f) { - Settings& s = Settings::get(); - s.crashFunction = f; + AIAccess<Settings>(Settings::get())->crashFunction = f; } void setTimeFunction(TimeFunction f) { - Settings& s = Settings::get(); - s.timeFunction = f; + AIAccess<Settings>(Settings::get())->timeFunction = f; + } + + void setDefaultLevel(AIAccess<Settings> const& settings_w, ELevel level) + { + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + settings_w->defaultLevel = level; } void setDefaultLevel(ELevel level) { - Globals& g = Globals::get(); - Settings& s = Settings::get(); - g.invalidateCallSites(); - s.defaultLevel = level; + setDefaultLevel(AIAccess<Settings>(Settings::get()), level); } void setFunctionLevel(const std::string& function_name, ELevel level) { - Globals& g = Globals::get(); - Settings& s = Settings::get(); - g.invalidateCallSites(); - s.functionLevelMap[function_name] = level; + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + AIAccess<Settings>(Settings::get())->functionLevelMap[function_name] = level; } void setClassLevel(const std::string& class_name, ELevel level) { - Globals& g = Globals::get(); - Settings& s = Settings::get(); - g.invalidateCallSites(); - s.classLevelMap[class_name] = level; + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + AIAccess<Settings>(Settings::get())->classLevelMap[class_name] = level; } void setFileLevel(const std::string& file_name, ELevel level) { - Globals& g = Globals::get(); - Settings& s = Settings::get(); - g.invalidateCallSites(); - s.fileLevelMap[file_name] = level; + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + AIAccess<Settings>(Settings::get())->fileLevelMap[file_name] = level; } void setTagLevel(const std::string& tag_name, ELevel level) { - Globals& g = Globals::get(); - Settings& s = Settings::get(); - g.invalidateCallSites(); - s.tagLevelMap[tag_name] = level; + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + AIAccess<Settings>(Settings::get())->tagLevelMap[tag_name] = level; } } @@ -697,18 +690,16 @@ namespace LLError { void configure(const LLSD& config) { - Globals& g = Globals::get(); - Settings& s = Settings::get(); - - g.invalidateCallSites(); - s.functionLevelMap.clear(); - s.classLevelMap.clear(); - s.fileLevelMap.clear(); - s.tagLevelMap.clear(); - s.uniqueLogMessages.clear(); + AIAccess<Settings> settings_w(Settings::get()); + AIAccess<Globals>(Globals::get())->invalidateCallSites(); + settings_w->functionLevelMap.clear(); + settings_w->classLevelMap.clear(); + settings_w->fileLevelMap.clear(); + settings_w->tagLevelMap.clear(); + settings_w->uniqueLogMessages.clear(); - setPrintLocation(config["print-location"]); - setDefaultLevel(decodeLevel(config["default-level"])); + setPrintLocation(settings_w, config["print-location"]); + setDefaultLevel(settings_w, decodeLevel(config["default-level"])); LLSD sets = config["settings"]; LLSD::array_const_iterator a, end; @@ -718,10 +709,10 @@ namespace LLError ELevel level = decodeLevel(entry["level"]); - setLevels(s.functionLevelMap, entry["functions"], level); - setLevels(s.classLevelMap, entry["classes"], level); - setLevels(s.fileLevelMap, entry["files"], level); - setLevels(s.tagLevelMap, entry["tags"], level); + setLevels(settings_w->functionLevelMap, entry["functions"], level); + setLevels(settings_w->classLevelMap, entry["classes"], level); + setLevels(settings_w->fileLevelMap, entry["files"], level); + setLevels(settings_w->tagLevelMap, entry["tags"], level); } } } @@ -738,26 +729,34 @@ namespace LLError - void addRecorder(Recorder* recorder) + void addRecorder(AIAccess<Settings> const& settings_w, Recorder* recorder) { if (recorder == NULL) { return; } - Settings& s = Settings::get(); - s.recorders.push_back(recorder); + settings_w->recorders.push_back(recorder); } - void removeRecorder(Recorder* recorder) + void addRecorder(Recorder* recorder) + { + addRecorder(AIAccess<Settings>(Settings::get()), recorder); + } + + void removeRecorder(AIAccess<Settings> const& settings_w, Recorder* recorder) { if (recorder == NULL) { return; } - Settings& s = Settings::get(); - s.recorders.erase( - std::remove(s.recorders.begin(), s.recorders.end(), recorder), - s.recorders.end()); + settings_w->recorders.erase( + std::remove(settings_w->recorders.begin(), settings_w->recorders.end(), recorder), + settings_w->recorders.end()); + } + + void removeRecorder(Recorder* recorder) + { + removeRecorder(AIAccess<Settings>(Settings::get()), recorder); } } @@ -765,12 +764,12 @@ namespace LLError { void logToFile(const std::string& file_name) { - LLError::Settings& s = LLError::Settings::get(); + AIAccess<Settings> settings_w(Settings::get()); - removeRecorder(s.fileRecorder); - delete s.fileRecorder; - s.fileRecorder = NULL; - s.fileRecorderFileName.clear(); + removeRecorder(settings_w, settings_w->fileRecorder); + delete settings_w->fileRecorder; + settings_w->fileRecorder = NULL; + settings_w->fileRecorderFileName.clear(); if (file_name.empty()) { @@ -784,54 +783,51 @@ namespace LLError return; } - s.fileRecorderFileName = file_name; - s.fileRecorder = f; - addRecorder(f); + settings_w->fileRecorderFileName = file_name; + settings_w->fileRecorder = f; + addRecorder(settings_w, f); } void logToFixedBuffer(LLFixedBuffer* fixedBuffer) { - LLError::Settings& s = LLError::Settings::get(); + AIAccess<Settings> settings_w(Settings::get()); - removeRecorder(s.fixedBufferRecorder); - delete s.fixedBufferRecorder; - s.fixedBufferRecorder = NULL; + removeRecorder(settings_w, settings_w->fixedBufferRecorder); + delete settings_w->fixedBufferRecorder; + settings_w->fixedBufferRecorder = NULL; if (!fixedBuffer) { return; } - s.fixedBufferRecorder = new RecordToFixedBuffer(*fixedBuffer); - addRecorder(s.fixedBufferRecorder); + settings_w->fixedBufferRecorder = new RecordToFixedBuffer(*fixedBuffer); + addRecorder(settings_w, settings_w->fixedBufferRecorder); } std::string logFileName() { - LLError::Settings& s = LLError::Settings::get(); - return s.fileRecorderFileName; + return AIAccess<Settings>(Settings::get())->fileRecorderFileName; } } namespace { - void writeToRecorders(LLError::ELevel level, const std::string& message) + void writeToRecorders(AIAccess<LLError::Settings> const& settings_w, LLError::ELevel level, const std::string& message) { - LLError::Settings& s = LLError::Settings::get(); - std::string messageWithTime; - - for (Recorders::const_iterator i = s.recorders.begin(); - i != s.recorders.end(); + + for (Recorders::const_iterator i = settings_w->recorders.begin(); + i != settings_w->recorders.end(); ++i) { LLError::Recorder* r = *i; - if (r->wantsTime() && s.timeFunction != NULL) + if (r->wantsTime() && settings_w->timeFunction != NULL) { if (messageWithTime.empty()) { - messageWithTime = s.timeFunction() + " " + message; + messageWithTime = settings_w->timeFunction() + " " + message; } r->recordMessage(level, messageWithTime); @@ -949,10 +945,9 @@ namespace LLError return false; } - Globals& g = Globals::get(); - Settings& s = Settings::get(); + AIAccess<Settings> settings_w(Settings::get()); - s.shouldLogCallCounter += 1; + settings_w->shouldLogCallCounter += 1; std::string class_name = className(site.mClassInfo); std::string function_name = functionName(site.mFunction); @@ -961,20 +956,20 @@ namespace LLError function_name = class_name + "::" + function_name; } - ELevel compareLevel = s.defaultLevel; + ELevel compareLevel = settings_w->defaultLevel; // The most specific match found will be used as the log level, // since the computation short circuits. // So, in increasing order of importance: // Default < Broad Tag < File < Class < Function < Narrow Tag - ((site.mNarrowTag != NULL) ? checkLevelMap(s.tagLevelMap, site.mNarrowTag, compareLevel) : false) - || checkLevelMap(s.functionLevelMap, function_name, compareLevel) - || checkLevelMap(s.classLevelMap, class_name, compareLevel) - || checkLevelMap(s.fileLevelMap, abbreviateFile(site.mFile), compareLevel) - || ((site.mBroadTag != NULL) ? checkLevelMap(s.tagLevelMap, site.mBroadTag, compareLevel) : false); + ((site.mNarrowTag != NULL) ? checkLevelMap(settings_w->tagLevelMap, site.mNarrowTag, compareLevel) : false) + || checkLevelMap(settings_w->functionLevelMap, function_name, compareLevel) + || checkLevelMap(settings_w->classLevelMap, class_name, compareLevel) + || checkLevelMap(settings_w->fileLevelMap, abbreviateFile(site.mFile), compareLevel) + || ((site.mBroadTag != NULL) ? checkLevelMap(settings_w->tagLevelMap, site.mBroadTag, compareLevel) : false); site.mCached = true; - g.addCallSite(site); + AIAccess<Globals>(Globals::get())->addCallSite(site); return site.mShouldLog = site.mLevel >= compareLevel; } @@ -984,16 +979,16 @@ namespace LLError LogLock lock; if (lock.ok()) { - Globals& g = Globals::get(); + AIAccess<Globals> globals(Globals::get()); - if (!g.messageStreamInUse) + if (!globals->messageStreamInUse) { - g.messageStreamInUse = true; - return &g.messageStream; + globals->messageStreamInUse = true; + return &globals->messageStream; // Returns pointer to member of unlocked object, apparently "protected" by having set globals->messageStreamInUse. } } - return new std::ostringstream; + return new std::ostringstream; // Holy memory leak. } void Log::flush(std::ostringstream* out, char* message) @@ -1014,12 +1009,12 @@ namespace LLError message[127] = '\0' ; } - Globals& g = Globals::get(); - if (out == &g.messageStream) + AIAccess<Globals> globals(Globals::get()); + if (out == &globals->messageStream) { - g.messageStream.clear(); - g.messageStream.str(""); - g.messageStreamInUse = false; + globals->messageStream.clear(); + globals->messageStream.str(""); + globals->messageStreamInUse = false; } else { @@ -1036,28 +1031,31 @@ namespace LLError return; } - Globals& g = Globals::get(); - Settings& s = Settings::get(); - std::string message = out->str(); - if (out == &g.messageStream) - { - g.messageStream.clear(); - g.messageStream.str(""); - g.messageStreamInUse = false; - } - else + { - delete out; + AIAccess<Globals> globals(Globals::get()); + if (out == &globals->messageStream) + { + globals->messageStream.clear(); + globals->messageStream.str(""); + globals->messageStreamInUse = false; + } + else + { + delete out; + } } + AIAccess<Settings> settings_w(Settings::get()); + if (site.mLevel == LEVEL_ERROR) { std::ostringstream fatalMessage; fatalMessage << abbreviateFile(site.mFile) << "(" << site.mLine << ") : error"; - writeToRecorders(site.mLevel, fatalMessage.str()); + writeToRecorders(settings_w, site.mLevel, fatalMessage.str()); } @@ -1072,7 +1070,7 @@ namespace LLError default: prefix << "XXX: "; break; }; - if (s.printLocation) + if (settings_w->printLocation) { prefix << abbreviateFile(site.mFile) << "(" << site.mLine << ") : "; @@ -1090,8 +1088,8 @@ namespace LLError if (site.mPrintOnce) { - std::map<std::string, unsigned int>::iterator messageIter = s.uniqueLogMessages.find(message); - if (messageIter != s.uniqueLogMessages.end()) + std::map<std::string, unsigned int>::iterator messageIter = settings_w->uniqueLogMessages.find(message); + if (messageIter != settings_w->uniqueLogMessages.end()) { messageIter->second++; unsigned int num_messages = messageIter->second; @@ -1107,14 +1105,14 @@ namespace LLError else { prefix << "ONCE: "; - s.uniqueLogMessages[message] = 1; + settings_w->uniqueLogMessages[message] = 1; } } if (site.mPrintOnce) { - std::map<std::string, unsigned int>::iterator messageIter = s.uniqueLogMessages.find(message); - if (messageIter != s.uniqueLogMessages.end()) + std::map<std::string, unsigned int>::iterator messageIter = settings_w->uniqueLogMessages.find(message); + if (messageIter != settings_w->uniqueLogMessages.end()) { messageIter->second++; unsigned int num_messages = messageIter->second; @@ -1130,18 +1128,18 @@ namespace LLError else { prefix << "ONCE: "; - s.uniqueLogMessages[message] = 1; + settings_w->uniqueLogMessages[message] = 1; } } prefix << message; message = prefix.str(); - writeToRecorders(site.mLevel, message); + writeToRecorders(settings_w, site.mLevel, message); - if (site.mLevel == LEVEL_ERROR && s.crashFunction) + if (site.mLevel == LEVEL_ERROR && settings_w->crashFunction) { - s.crashFunction(message); + settings_w->crashFunction(message); } } } @@ -1151,14 +1149,16 @@ namespace LLError namespace LLError { - Settings* saveAndResetSettings() + class ThreadSafeSettings { }; + + ThreadSafeSettings* saveAndResetSettings() { - return Settings::saveAndReset(); + return reinterpret_cast<ThreadSafeSettings*>(Settings::saveAndReset()); } - void restoreSettings(Settings* s) + void restoreSettings(ThreadSafeSettings* s) { - return Settings::restore(s); + Settings::restore(reinterpret_cast<AIThreadSafeSimple<Settings>*>(s)); } std::string removePrefix(std::string& s, const std::string& p) @@ -1204,8 +1204,7 @@ namespace LLError int shouldLogCallCount() { - Settings& s = Settings::get(); - return s.shouldLogCallCounter; + return AIAccess<Settings>(Settings::get())->shouldLogCallCounter; } #if LL_WINDOWS diff --git a/linden/indra/llcommon/llerrorcontrol.h b/linden/indra/llcommon/llerrorcontrol.h index 54138b2b0..c086f27a7 100644 --- a/linden/indra/llcommon/llerrorcontrol.h +++ b/linden/indra/llcommon/llerrorcontrol.h @@ -135,9 +135,9 @@ namespace LLError Utilities for use by the unit tests of LLError itself. */ - class Settings; - LL_COMMON_API Settings* saveAndResetSettings(); - LL_COMMON_API void restoreSettings(Settings *); + class ThreadSafeSettings; + LL_COMMON_API ThreadSafeSettings* saveAndResetSettings(); + LL_COMMON_API void restoreSettings(ThreadSafeSettings *); LL_COMMON_API std::string abbreviateFile(const std::string& filePath); LL_COMMON_API int shouldLogCallCount(); diff --git a/linden/indra/llxml/llcontrol.cpp b/linden/indra/llxml/llcontrol.cpp index 452167e10..004b75333 100644 --- a/linden/indra/llxml/llcontrol.cpp +++ b/linden/indra/llxml/llcontrol.cpp @@ -254,9 +254,9 @@ LLSD LLControlVariable::getSaveValue() const return mValues[0]; } -LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name) +LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name) const { - ctrl_name_table_t::iterator iter = mNameTable.find(name); + ctrl_name_table_t::const_iterator iter = mNameTable.find(name); return iter == mNameTable.end() ? LLPointer<LLControlVariable>() : iter->second; } @@ -452,7 +452,7 @@ std::string LLControlGroup::findString(const std::string& name) return LLStringUtil::null; } -std::string LLControlGroup::getString(const std::string& name) +std::string LLControlGroup::getString(const std::string& name) const { LLControlVariable* control = getControl(name); @@ -599,9 +599,9 @@ LLSD LLControlGroup::getLLSD(const std::string& name) return LLSD(); } -BOOL LLControlGroup::controlExists(const std::string& name) +BOOL LLControlGroup::controlExists(const std::string& name) const { - ctrl_name_table_t::iterator iter = mNameTable.find(name); + ctrl_name_table_t::const_iterator iter = mNameTable.find(name); return iter != mNameTable.end(); } diff --git a/linden/indra/llxml/llcontrol.h b/linden/indra/llxml/llcontrol.h index 316de5c20..f68c34389 100644 --- a/linden/indra/llxml/llcontrol.h +++ b/linden/indra/llxml/llcontrol.h @@ -160,7 +160,7 @@ class LLControlGroup : public LLControlGroupReader ~LLControlGroup(); void cleanup(); - LLPointer<LLControlVariable> getControl(const std::string& name); + LLPointer<LLControlVariable> getControl(const std::string& name) const; struct ApplyFunctor { @@ -185,7 +185,7 @@ class LLControlGroup : public LLControlGroupReader std::string findString(const std::string& name); - std::string getString(const std::string& name); + std::string getString(const std::string& name) const; LLWString getWString(const std::string& name); std::string getText(const std::string& name); LLVector3 getVector3(const std::string& name); @@ -220,7 +220,7 @@ class LLControlGroup : public LLControlGroupReader void setValue(const std::string& name, const LLSD& val); - BOOL controlExists(const std::string& name); + BOOL controlExists(const std::string& name) const; // Returns number of controls loaded, 0 if failed // If require_declaration is false, will auto-declare controls it finds diff --git a/linden/indra/llxml/llcontrolgroupreader.h b/linden/indra/llxml/llcontrolgroupreader.h index c4c04b98b..ef8ee18c9 100644 --- a/linden/indra/llxml/llcontrolgroupreader.h +++ b/linden/indra/llxml/llcontrolgroupreader.h @@ -46,7 +46,7 @@ class LLControlGroupReader LLControlGroupReader() {} virtual ~LLControlGroupReader() {} - virtual std::string getString(const std::string& name) = 0; + virtual std::string getString(const std::string& name) const = 0; //virtual LLWString getWString(const std::string& name) = 0; virtual std::string getText(const std::string& name) = 0; //virtual LLVector3 getVector3(const std::string& name) = 0; diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index aaae4d2af..19a0163d0 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -602,7 +602,10 @@ bool LLAppViewer::init() gDirUtilp->setSkinFolder("default"); initLogging(); - + + // Logging is initialized. Now it's safe to start the error thread. + startErrorThread(); + // // OK to write stuff to logs now, we've now crash reported if necessary // @@ -1661,8 +1664,9 @@ bool LLAppViewer::initLogging() return true; } -bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, - bool set_defaults) +bool LLAppViewer::loadSettingsFromDirectory(AIReadAccess<settings_map_type> const& settings_r, + std::string const& location_key, + bool set_defaults) { // Find and vet the location key. if(!mSettingsLocationList.has(location_key)) @@ -1689,11 +1693,13 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, LLSD files = location.get("Files"); for(LLSD::map_iterator itr = files.beginMap(); itr != files.endMap(); ++itr) { - std::string settings_group = (*itr).first; + std::string const settings_group = (*itr).first; + settings_map_type::const_iterator const settings_group_iter = settings_r->find(settings_group); + llinfos << "Attempting to load settings for the group " << settings_group << " - from location " << location_key << llendl; - if(gSettings.find(settings_group) == gSettings.end()) + if(settings_group_iter == settings_r->end()) { llwarns << "No matching settings group for name " << settings_group << llendl; continue; @@ -1707,11 +1713,10 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, std::string custom_name_setting = file.get("NameFromSetting"); // *NOTE: Regardless of the group currently being lodaed, // this setting is always read from the Global settings. - if(gSettings[sGlobalSettingsName]->controlExists(custom_name_setting)) + LLControlGroup const* control_group = settings_r->find(sGlobalSettingsName)->second; + if(control_group->controlExists(custom_name_setting)) { - std::string file_name = - gSettings[sGlobalSettingsName]->getString(custom_name_setting); - full_settings_path = file_name; + full_settings_path = control_group->getString(custom_name_setting); } } @@ -1727,7 +1732,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, requirement = file.get("Requirement").asInteger(); } - if(!gSettings[settings_group]->loadFromFile(full_settings_path, set_defaults)) + if(!settings_group_iter->second->loadFromFile(full_settings_path, set_defaults)) { if(requirement == 1) { @@ -1772,10 +1777,14 @@ bool LLAppViewer::initConfiguration() // init Imprudence version - MC ViewerVersion::initViewerVersion(); + // Grab and hold write locks for the entire duration of this function. + AIWriteAccess<settings_map_type> settings_w(gSettings); + settings_map_type& settings(*settings_w); + //Set up internal pointers - gSettings[sGlobalSettingsName] = &gSavedSettings; - gSettings[sPerAccountSettingsName] = &gSavedPerAccountSettings; - gSettings[sCrashSettingsName] = &gCrashSettings; + settings[sGlobalSettingsName] = &gSavedSettings; + settings[sPerAccountSettingsName] = &gSavedPerAccountSettings; + settings[sCrashSettingsName] = &gCrashSettings; //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); @@ -1800,7 +1809,7 @@ bool LLAppViewer::initConfiguration() // - load defaults bool set_defaults = true; - if(!loadSettingsFromDirectory("Default", set_defaults)) + if(!loadSettingsFromDirectory(settings_w, "Default", set_defaults)) { std::ostringstream msg; msg << "Second Life could not load its default settings file. \n" @@ -1910,7 +1919,7 @@ bool LLAppViewer::initConfiguration() } // - load overrides from user_settings - loadSettingsFromDirectory("User"); + loadSettingsFromDirectory(settings_w, "User"); // - apply command line settings clp.notify(); @@ -1980,7 +1989,7 @@ bool LLAppViewer::initConfiguration() { const std::string& name = *itr; const std::string& value = *(++itr); - LLControlVariable* c = gSettings[sGlobalSettingsName]->getControl(name); + LLControlVariable* c = settings[sGlobalSettingsName]->getControl(name); if(c) { c->setValue(value, false); diff --git a/linden/indra/newview/llappviewer.h b/linden/indra/newview/llappviewer.h index 7b3230a28..15fd9d6e2 100644 --- a/linden/indra/newview/llappviewer.h +++ b/linden/indra/newview/llappviewer.h @@ -33,7 +33,8 @@ #ifndef LL_LLAPPVIEWER_H #define LL_LLAPPVIEWER_H -#include "llsys.h" // LLOSInfo +#include "llsys.h" // LLOSInfo +#include "llviewercontrol.h" // settings_map_type class LLTextureCache; class LLImageDecodeThread; @@ -135,11 +136,12 @@ class LLAppViewer : public LLApp // Load settings from the location specified by loction_key. // Key availale and rules for loading, are specified in // 'app_settings/settings_files.xml' - bool loadSettingsFromDirectory(const std::string& location_key, - bool set_defaults = false); + bool loadSettingsFromDirectory(AIReadAccess<settings_map_type> const& settings_r, + std::string const& location_key, + bool set_defaults = false); - std::string getSettingsFilename(const std::string& location_key, - const std::string& file); + std::string getSettingsFilename(std::string const& location_key, + std::string const& file); // For thread debugging. // llstartup needs to control init. diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index b744961e4..0e4bebea6 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -941,7 +941,7 @@ bool idle_startup() ); // Overwrite default user settings with user settings - LLAppViewer::instance()->loadSettingsFromDirectory("Account"); + LLAppViewer::instance()->loadSettingsFromDirectory(AIReadAccess<settings_map_type>(gSettings), "Account"); // Need to set the LastLogoff time here if we don't have one. LastLogoff is used for "Recent Items" calculation // and startup time is close enough if we don't have a real value. diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 36750724e..703e62a69 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -71,14 +71,13 @@ #include "llrender.h" #include "llslider.h" #include "llfloaterchat.h" - +#include "aithreadsafe.h" #ifdef TOGGLE_HACKED_GODLIKE_VIEWER BOOL gHackGodmode = FALSE; #endif - -std::map<std::string, LLControlGroup*> gSettings; +AITHREADSAFE(settings_map_type, gSettings,); LLControlGroup gSavedSettings; // saved at end of session LLControlGroup gSavedPerAccountSettings; // saved at end of session LLControlGroup gColors; // read-only diff --git a/linden/indra/newview/llviewercontrol.h b/linden/indra/newview/llviewercontrol.h index d0dc80cb9..780940fc2 100644 --- a/linden/indra/newview/llviewercontrol.h +++ b/linden/indra/newview/llviewercontrol.h @@ -35,6 +35,7 @@ #include <map> #include "llcontrol.h" +#include "aithreadsafe.h" // Enabled this definition to compile a 'hacked' viewer that // allows a hacked godmode to be toggled on and off. @@ -47,7 +48,8 @@ extern BOOL gHackGodmode; //setting variables are declared in this function void settings_setup_listeners(); -extern std::map<std::string, LLControlGroup*> gSettings; +typedef std::map<std::string, LLControlGroup*> settings_map_type; +extern AIThreadSafe<settings_map_type> gSettings; // for the graphics settings void create_graphics_group(LLControlGroup& group); From 508aff93cf1b3f8803ba57a7dcc9a8da59acc974 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 26 Nov 2010 16:51:04 +0100 Subject: [PATCH 226/239] IMP-701: Added missing license header. --- linden/indra/llcommon/aithreadsafe.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/linden/indra/llcommon/aithreadsafe.h b/linden/indra/llcommon/aithreadsafe.h index e1b93ba48..70cd2a3db 100644 --- a/linden/indra/llcommon/aithreadsafe.h +++ b/linden/indra/llcommon/aithreadsafe.h @@ -2,6 +2,25 @@ * @file aithreadsafe.h * @brief Implementation of AIThreadSafe, AIReadAccessConst, AIReadAccess and AIWriteAccess. * + * Copyright (c) 2010, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * * CHANGELOG * and additional copyright holders. * From 3decbd0c849cb4105eda26926ef076f81cf609fb Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 7 Dec 2010 14:11:15 +0100 Subject: [PATCH 227/239] More support for ld.gold in case a plugin uses threads. --- linden/indra/cmake/LLPlugin.cmake | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/linden/indra/cmake/LLPlugin.cmake b/linden/indra/cmake/LLPlugin.cmake index 9722f16c3..7ee404b9b 100644 --- a/linden/indra/cmake/LLPlugin.cmake +++ b/linden/indra/cmake/LLPlugin.cmake @@ -5,4 +5,10 @@ set(LLPLUGIN_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llplugin ) -set(LLPLUGIN_LIBRARIES llplugin) +if (LINUX) + # In order to support using ld.gold on linux, we need to explicitely + # specify all libraries that llplugin uses. + set(LLPLUGIN_LIBRARIES llplugin pthread) +else (LINUX) + set(LLPLUGIN_LIBRARIES llplugin) +endif (LINUX) From 065ca3d1832bacb7b35c483e9d07659bbd5ee4b8 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 7 Dec 2010 14:14:05 +0100 Subject: [PATCH 228/239] Make is_main_thread globally accessible. --- linden/indra/llcommon/llthread.cpp | 2 +- linden/indra/llcommon/llthread.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp index f7732cb6a..5efaf0fe2 100644 --- a/linden/indra/llcommon/llthread.cpp +++ b/linden/indra/llcommon/llthread.cpp @@ -252,7 +252,7 @@ void LLThread::wakeLocked() #ifdef SHOW_ASSERT // This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. static apr_os_thread_t main_thread_id; -bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } +LL_COMMON_API bool is_main_thread(void) { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } #endif // The thread private handle to access the AIThreadLocalData instance. diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index 1e982cc1e..275411f62 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h @@ -40,6 +40,10 @@ #include "apr_thread_cond.h" #include "aiaprpool.h" +#ifdef SHOW_ASSERT +extern bool is_main_thread(void); +#endif + class LLThread; class LLMutex; class LLCondition; From 05143baba0d4c4131ec0249fb50b989957da83d5 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Mon, 10 Jan 2011 13:35:44 +0100 Subject: [PATCH 229/239] Direct all webbrowser activity to the external browser. Force UseExternalBrowser to on. For two cases (automatic script help and explicitely opening a browser from the menu), call LLWeb::loadURL rather than LLWeb::loadURLInternal, which now will default to calling LLWeb::loadURLExternal. Finally, removed weird /icanhas* builtin gestures that open all kinds of imprudence specific 'easter egg' webpages. This remove made more sense than changing opening the imprudence webpages in an external browser or even reproducing the pages on a moonworld website %-). --- linden/indra/newview/llgesturemgr.cpp | 3 +++ linden/indra/newview/llpanelweb.cpp | 6 ++++-- linden/indra/newview/llpreviewscript.cpp | 3 ++- linden/indra/newview/llviewermenu.cpp | 3 ++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/llgesturemgr.cpp b/linden/indra/newview/llgesturemgr.cpp index bb678d7a0..d1c3ee376 100644 --- a/linden/indra/newview/llgesturemgr.cpp +++ b/linden/indra/newview/llgesturemgr.cpp @@ -565,6 +565,8 @@ BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::s found_gestures = TRUE; } } + +#if 0 // MoonWorld: Kill all the /icanhas insanity (opens loads of webbrowser pages). else if (LLStringUtil::compareInsensitive("/icanhaseasteregg", cur_token) == 0 || LLStringUtil::compareInsensitive("/icanhaseastereggs", cur_token) == 0) { @@ -803,6 +805,7 @@ BOOL LLGestureManager::triggerAndReviseString(const std::string &utf8str, std::s } return TRUE; } +#endif // NO ICANHAS } diff --git a/linden/indra/newview/llpanelweb.cpp b/linden/indra/newview/llpanelweb.cpp index 6f9bd7a5a..4a79493ce 100644 --- a/linden/indra/newview/llpanelweb.cpp +++ b/linden/indra/newview/llpanelweb.cpp @@ -65,7 +65,8 @@ BOOL LLPanelWeb::postBuild() childSetAction("clear_cache", onClickClearCache, this); childSetCommitCallback("web_proxy_enabled", onCommitWebProxyEnabled, this); - std::string value = gSavedSettings.getBOOL("UseExternalBrowser") ? "external" : "internal"; + // MoonWorld: Always use external browser. + std::string value = "external"; childSetValue("use_external_browser", value); childSetValue("cookies_enabled", gSavedSettings.getBOOL("BrowserCookiesEnabled")); @@ -114,7 +115,8 @@ void LLPanelWeb::apply() gSavedSettings.setString("SearchURLQueryOpenSim", childGetValue("world_search_editor")); } - bool value = childGetValue("use_external_browser").asString() == "external" ? true : false; + // MoonWorld: Always use external browser. + bool value = true; gSavedSettings.setBOOL("UseExternalBrowser", value); viewer_media_t media_source = get_web_media(); diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp index d2d9ed5db..813be03dc 100644 --- a/linden/indra/newview/llpreviewscript.cpp +++ b/linden/indra/newview/llpreviewscript.cpp @@ -546,7 +546,8 @@ bool LLScriptEdCore::onHelpAutoscript(const LLSD& notification, const LLSD& resp switch(option) { case 0: - LLWeb::loadURLInternal(notification["payload"]["autoscript_url"]); + // MoonWorld: Open even script help in the external browser instead of the internal browser. + LLWeb::loadURL(notification["payload"]["autoscript_url"]); break; default: break; diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 7f003826c..f70cc4199 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -6099,7 +6099,8 @@ class LLShowFloater : public view_listener_t } else { - LLWeb::loadURLInternal(gSavedSettings.getString("BrowserHome")); + // MoonWorld: Even in this case, open BrowserHome in the external browser instead of the internal browser. + LLWeb::loadURL(gSavedSettings.getString("BrowserHome")); } } else if (floater_name == "beacons") From 0fe77c77f1d0198cde6fab8ddc6e9f4580aa2e00 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 11 Jan 2011 15:55:52 +0100 Subject: [PATCH 230/239] Add 'CET Grid' and 'Avatrian Tokyo' to default_grids.xml Also removed most other grids. Will have to clean up this file later. Change the setting 'GridUpdateList' to a temporary test URL. --- .../newview/app_settings/default_grids.xml | 239 +++--------------- .../indra/newview/app_settings/settings.xml | 2 +- 2 files changed, 36 insertions(+), 205 deletions(-) diff --git a/linden/indra/newview/app_settings/default_grids.xml b/linden/indra/newview/app_settings/default_grids.xml index 3f44e4b90..9817d2df5 100644 --- a/linden/indra/newview/app_settings/default_grids.xml +++ b/linden/indra/newview/app_settings/default_grids.xml @@ -1,10 +1,43 @@ <llsd> + <!-- A copy of this file should be available for download from the + uri specified with the Debug Setting 'GridUpdateList', see + indra/newview/app_settings/settings.xml. --> <array> <map> - <key>default_grids_version</key><string>26</string> + <!-- Bumb this number whenever you change a grid entry. + It will then cause all entries with the same nick to be + overwritten in the users private grid_info.xml file next + time they run the viewer. --> + <key>default_grids_version</key><string>1</string> </map> - <!-- Second Life --> + <!-- Avatrian Tokyo --> + <map> + <key>gridnick</key><string>avatriantokyo</string> + <key>gridname</key><string>Avatrian Tokyo</string> + <key>platform</key><string>OpenSim</string> + <key>loginuri</key><string>http://124.107.67.189:8002/</string> + <key>loginpage</key><string>http://imprudenceviewer.org/app/splash/</string> <!-- REMOVE OR CHANGE THIS --> + <key>website</key><string>http://moonworld.cet.edu/os/</string> + <key>register</key><string>http://moonworld.cet.edu/os/portal/index.php</string> + <key>version</key><string>1</string> + </map> + + <!-- CET Grid --> + <map> + <key>gridnick</key><string>cetgrid</string> + <key>gridname</key><string>CETGrid</string> + <key>platform</key><string>OpenSim</string> + <key>loginuri</key><string>http://198.185.178.76:8002/</string> + <key>loginpage</key><string>http://imprudenceviewer.org/app/splash/</string> <!-- REMOVE OR CHANGE THIS --> + <key>website</key><string>http://moonworld.cet.edu/os/</string> + <key>register</key><string>http://moonworld.cet.edu/os/portal/index.php</string> + <key>version</key><string>1</string> + </map> + + <!-- REMOVE EVERYTHING BELOW --> + + <!-- Second Life --> <map> <key>gridnick</key><string>secondlife</string> <key>gridname</key><string>Second Life</string> @@ -19,21 +52,6 @@ <key>version</key><string>0</string> </map> - <!-- Second Life Beta --> - <map> - <key>gridnick</key><string>secondlifebeta</string> - <key>gridname</key><string>Second Life Beta Grid</string> - <key>platform</key><string>SecondLife</string> - <key>loginuri</key><string>https://login.aditi.lindenlab.com/cgi-bin/login.cgi</string> - <key>loginpage</key><string>http://imprudenceviewer.org/app/splash/</string> - <key>helperuri</key><string>http://aditi-secondlife.webdev.lindenlab.com/helpers/</string> - <key>website</key><string>http://secondlife.com/</string> - <key>support</key><string>http://secondlife.com/support/</string> - <key>register</key><string>http://secondlife.com/registration/</string> - <key>password</key><string>http://secondlife.com/account/request.php</string> - <key>version</key><string>1</string> - </map> - <!-- Local Host --> <map> <key>gridnick</key><string>localhost</string> @@ -45,192 +63,5 @@ <key>version</key><string>1</string> </map> - <!-- OSGrid --> - <map> - <key>gridnick</key><string>osgrid</string> - <key>gridname</key><string>OSGrid</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://login.osgrid.org/</string> - <key>loginpage</key><string>http://osgrid.org/splash/</string> - <key>helperuri</key><string>http://helper.osgrid.org/</string> - <key>website</key><string>http://osgrid.org/</string> - <key>support</key><string>http://osgrid.org/</string> - <key>register</key><string>http://www.osgrid.org/index.php/auth/register</string> - <key>password</key><string>http://www.osgrid.org/index.php/auth/forgot_password</string> - <key>version</key><string>1</string> - </map> - - <!-- Legend City Online --> - <map> - <key>gridnick</key><string>legendcityonline</string> - <key>gridname</key><string>Legend City Online</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://login.legendcityonline.com</string> - <key>loginpage</key><string>http://www.legendcityonline.com/welcome.php</string> - <key>helperuri</key><string>https://secure.legendcityonline.com/</string> - <key>website</key><string>http://www.legendcityonline.com/</string> - <key>support</key><string>http://www.legendcityonline.com/</string> - <key>register</key><string>http://www.legendcityonline.com/</string> - <key>password</key><string>http://www.legendcityonline.com/</string> - <key>version</key><string>0</string> - </map> - - <!-- WorldSimTerra --> - <map> - <key>gridnick</key><string>worldsimterra</string> - <key>gridname</key><string>WorldSimTerra</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://wsterra.com:8002</string> - <key>loginpage</key><string>http://wsterra.com/log.php</string> - <key>helperuri</key><string>http://wsterra.com/</string> - <key>website</key><string>http://www.worldsimterra.com/</string> - <key>support</key><string>http://www.worldsimterra.com/</string> - <key>register</key><string>http://www.worldsimterra.com/</string> - <key>password</key><string>http://www.worldsimterra.com/</string> - <key>version</key><string>0</string> - </map> - - <!-- Your Alternative Life --> - <map> - <key>gridnick</key><string>youralternativelife</string> - <key>gridname</key><string>Your Alternative Life</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://grid01.from-ne.com:8002/</string> - <key>loginpage</key><string>http://grid01.from-ne.com/tios/loginscreen3.php</string> - <key>helperuri</key><string>http://grid01.from-ne.com/tios/services/</string> - <key>website</key><string>http://www.youralternativelife.com</string> - <key>support</key><string>http://www.youralternativelife.com</string> - <key>register</key><string>http://www.youralternativelife.com</string> - <key>password</key><string>http://www.youralternativelife.com</string> - <key>version</key><string>0</string> - - </map> - - <!-- The New World Grid --> - <map> - <key>gridnick</key><string>thenewworldgrid</string> - <key>gridname</key><string>The New World Grid</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://grid.newworldgrid.com:8002/</string> - <key>loginpage</key><string>http://account.newworldgrid.com/loginscreen.php</string> - <key>helperuri</key><string>http://account.newworldgrid.com/</string> - <key>website</key><string>http://www.newworldgrid.com/</string> - <key>support</key><string>http://www.newworldgrid.com/</string> - <key>register</key><string>http://www.newworldgrid.com/register</string> - <key>password</key><string>http://account.newworldgrid.com/</string> - <key>version</key><string>0</string> - </map> - - <!-- ReactionGrid --> - <map> - <key>gridnick</key><string>reactiongrid</string> - <key>gridname</key><string>ReactionGrid</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://reactiongrid.com:8008/</string> - <key>loginpage</key><string>http://gsquared.info/portal</string> - <key>website</key><string>http://reactiongrid.com/Default.aspx</string> - <key>support</key><string>http://reactiongrid.com/Support.aspx</string> - <key>register</key><string>http://reactiongrid.com/Register.aspx</string> - <key>password</key><string>http://reactiongrid.com/Support/ResetPassword.aspx</string> - <key>version</key><string>0</string> - </map> - - <!-- Cyberlandia --> - <map> - <key>gridnick</key><string>cyberlandia</string> - <key>gridname</key><string>Cyberlandia</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://grid.cyberlandia.net:8002</string> - <key>loginpage</key><string></string> - <key>helperuri</key><string></string> - <key>website</key><string>http://www.cyberlandia.net</string> - <key>version</key><string>0</string> - </map> - - <!-- Role Play Worlds --> - <map> - <key>gridnick</key><string>roleplayworlds</string> - <key>gridname</key><string>Role Play Worlds</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://grid.roleplayworlds.net:8002/</string> - <key>loginpage</key><string>http://grid.roleplayworlds.net/loginscreen.php</string> - <key>helperuri</key><string>http://grid.roleplayworlds.net/</string> - <key>website</key><string>http://roleplayworlds.net/</string> - <key>register</key><string>http://grid.roleplayworlds.net/index.php?page=create</string> - <key>password</key><string>http://grid.roleplayworlds.net/index.php?page=change</string> - <key>version</key><string>0</string> - </map> - - <!-- GiantGrid --> - <map> - <key>gridnick</key><string>giantgrid</string> - <key>gridname</key><string>GiantGrid</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://Gianttest.no-ip.biz:8002/</string> - <key>loginpage</key><string>http://gianttest.no-ip.biz:80/gridsplash?method=login</string> - <key>helperuri</key><string>http://gianttest.no-ip.biz/giantmap/</string> - <key>version</key><string>0</string> - </map> - - <!-- 3rd Rock Grid --> - <map> - <key>gridnick</key><string>3rdrock</string> - <key>gridname</key><string>3rd Rock Grid</string> - <key>platform</key><string>OpenSim</string> - <key>loginuri</key><string>http://grid.3rdrockgrid.com:8002/</string> - <key>loginpage</key><string>http://3rdrockgrid.com/startpage.php</string> - <key>helperuri</key><string>http://grid.3rdrockgrid.com/money/</string> - <key>website</key><string>http://3rdrockgrid.com/</string> - <key>register</key><string>http://3rdrockgrid.com/</string> - <key>password</key><string>http://3rdrockgrid.com/</string> - <key>support</key><string>http://3rdrockgrid.com/</string> - <key>version</key><string>1</string> - </map> - - <!-- InWorldz --> - <map> - <key>gridname</key> <string>Inworldz</string> - <key>gridnick</key> <string>inworldz</string> - <key>platform</key> <string>OpenSim</string> - <key>loginuri</key> <string>http://inworldz.com:8002/</string> - <key>loginpage</key> <string>http://inworldz.com/loginscreen.php</string> - <key>helperuri</key> <string>http://inworldz.com/</string> - <key>password</key> <string>http://inworldz.com/wpassword</string> - <key>register</key> <string>http://inworldz.com/register</string> - <key>support</key> <string>http://inworldz.com/help</string> - <key>website</key> <string>http://inworldz.com/about/</string> - <key>version</key> <string>1</string> - </map> - - <!-- Meta7 --> - <map> - <key>gridname</key> <string>Meta7</string> - <key>gridnick</key> <string>meta7</string> - <key>platform</key> <string>OpenSim</string> - <key>loginuri</key> <string>http://login.meta7.com/</string> - <key>loginpage</key> <string>http://api.meta7.com/loginscreen.php</string> - <key>helperuri</key> <string>https://secure.meta7.com/</string> - <key>password</key> <string>http://www.meta7.com/resetpass.php</string> - <key>register</key> <string>http://www.meta7.com/register.php</string> - <key>support</key> <string>http://www.meta7.com/support.php</string> - <key>website</key> <string>http://meta7.com/</string> - <key>version</key> <string>0</string> - </map> - - <!-- ScienceSim --> - <map> - <key>gridname</key> <string>IEEE/ACM ScienceSim Virtual World</string> - <key>gridnick</key> <string>sciencesim</string> - <key>platform</key> <string>OpenSim</string> - <key>loginuri</key> <string>http://grid.sciencesim.com/</string> - <key>loginpage</key> <string>http://island.sciencesim.com/scisim/loginscreen.php</string> - <key>helperuri</key> <string></string> - <key>password</key> <string>http://island.sciencesim.com/scisim</string> - <key>register</key> <string>http://island.sciencesim.com/scisim</string> - <key>support</key> <string>http://island.sciencesim.com/wiki</string> - <key>website</key> <string>http://island.sciencesim.com/about/</string> - <key>version</key> <string>0</string> - </map> - </array> </llsd> diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index c946f40f0..c45e0bd0a 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -574,7 +574,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://imprudenceviewer.org/app/grids/</string> + <string>http://ansset/libcw/default_grids.xml</string> </map> <key>GoAction</key> <map> From e8b65bc8fc7b97ddfcb200b351c4dbd4396b8cef Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Tue, 11 Jan 2011 19:06:13 +0100 Subject: [PATCH 231/239] Disable ClientTags --- linden/indra/newview/llstartup.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 0e4bebea6..331bc301f 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -2769,7 +2769,9 @@ bool idle_startup() gAOInvTimer = new AOInvTimer(); } - LLFirstUse::ClientTags(); + // MoonWorld: Don't ask to download a client tag database on first use. + // See the setting ClientTagsListURL in settings.xml if you'd ever want to enable this. + //LLFirstUse::ClientTags(); // Add login location to teleport history 'teleported-into' LLVector3 agent_pos=gAgent.getPositionAgent(); From fbeb8190f86525c9219a7a1960d20f61c314d8b0 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 12 Jan 2011 14:46:38 +0100 Subject: [PATCH 232/239] Removed certain menu items from the viewer GUI. The following menu items are retained: 1. File Menu - Only Snaphot and Quit. 2. Edit Menu - Only Preferences. 3. View Menu - Only Mouselook, Reset View and Zoom Level. 4. World Menu - Only Stop Animating My Avatar. 5. Tools Menu - Completely hidden. 6. Help Menu - Completely hidden. 7. Advanced Menu - Completely hidden. This is achieved by adding attributes moonworld="true" to those items, in indra/newview/skins/default/xui/en-us/menu_login.xml and in indra/newview/skins/default/xui/en-us/menu_viewer.xml that should remain, and of course by adding support for this new attribute. This approach minimizes the size of the patch and therefore allows for easy merging with future upstream changes. It is also client-friendly: the client can easily add or remove these attributes when they change their mind (note that this attribute only works with menu_bar, menu, menu_item_call, menu_item_separator and menu_item_check). --- linden/indra/llui/llmenugl.cpp | 14 ++++++++ linden/indra/llxml/llxmlnode.cpp | 19 +++++++++++ linden/indra/llxml/llxmlnode.h | 2 ++ linden/indra/newview/llvoavatar.cpp | 3 +- .../skins/default/xui/en-us/menu_login.xml | 10 +++--- .../skins/default/xui/en-us/menu_viewer.xml | 34 +++++++++---------- 6 files changed, 59 insertions(+), 23 deletions(-) diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp index 91bb58120..bc43009cb 100644 --- a/linden/indra/llui/llmenugl.cpp +++ b/linden/indra/llui/llmenugl.cpp @@ -2194,9 +2194,16 @@ LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa BOOL create_jump_keys = FALSE; node->getAttributeBOOL("create_jump_keys", create_jump_keys); + // If 'node' (the parent of the menu item 'child') has the attribute moonworld="true", + // then and only then hide all children that do NOT have that attribute. + bool parent_has_moonworld = node->hasMoonWorld(); LLXMLNodePtr child; for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { + if (!child->isMoonWorld(!parent_has_moonworld)) // Parent has attribute and child does not? + { + continue; // Skip it. + } menu->parseChildXML(child, parent, factory); } @@ -3985,8 +3992,15 @@ LLView* LLMenuBarGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory } LLXMLNodePtr child; + // If the menubar 'node' (the parent of the menu item 'child') has the attribute moonworld="true", + // then and only then hide all children that do NOT have that attribute. + bool parent_has_moonworld = node->hasMoonWorld(); for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { + if (!child->isMoonWorld(!parent_has_moonworld)) // Parent has attribute and child does not? + { + continue; // Skip it. + } if (child->hasName("menu")) { LLMenuGL *menu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory); diff --git a/linden/indra/llxml/llxmlnode.cpp b/linden/indra/llxml/llxmlnode.cpp index 5bb501231..0972254a7 100644 --- a/linden/indra/llxml/llxmlnode.cpp +++ b/linden/indra/llxml/llxmlnode.cpp @@ -1241,6 +1241,25 @@ bool LLXMLNode::getAttribute_bool(const char* name, bool& value ) return retval; } +// Return true if this node has the attribute "moonworld". +bool LLXMLNode::hasMoonWorld() +{ + LLXMLNodePtr tmp; + return getAttribute("moonworld", tmp); +} + +// Return true if this node has the attribute "moonworld" and it's set to true, +// or when it doesn't have the attribute and default_value is true. +bool LLXMLNode::isMoonWorld(bool default_value) +{ + if (!hasMoonWorld()) + { + return default_value; + } + bool moonworld; + return getAttribute_bool("moonworld", moonworld) && moonworld; +} + BOOL LLXMLNode::getAttributeBOOL(const char* name, BOOL& value ) { LLXMLNodePtr node; diff --git a/linden/indra/llxml/llxmlnode.h b/linden/indra/llxml/llxmlnode.h index ab1a772ac..3242c0689 100644 --- a/linden/indra/llxml/llxmlnode.h +++ b/linden/indra/llxml/llxmlnode.h @@ -212,6 +212,8 @@ class LLXMLNode : public LLThreadSafeRefCount BOOL hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); } BOOL hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); } const std::string& getID() const { return mID; } + bool hasMoonWorld(); + bool isMoonWorld(bool default_value); U32 getChildCount() const; // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child. diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 6904bb20b..8a2c09460 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -2158,7 +2158,8 @@ void LLVOAvatar::buildCharacter() } } - for (S32 pass = 0; pass < 2; pass++) + // MoonWorld: gAttachSubMenu is gone! + for (S32 pass = 0; gAttachSubMenu && pass < 2; pass++) { for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ) diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_login.xml b/linden/indra/newview/skins/default/xui/en-us/menu_login.xml index 18fb8e632..292c9b033 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_login.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu_bar name="Login Menu" opaque="true" tear_off="false" height="18" bottom="-18"> - <menu create_jump_keys="true" label="File" name="File" opaque="true" tear_off="false"> - <menu_item_call label="Quit" name="Quit" shortcut="control|Q"> +<menu_bar name="Login Menu" opaque="true" tear_off="false" height="18" bottom="-18" moonworld="true"> + <menu create_jump_keys="true" label="File" name="File" opaque="true" tear_off="false" moonworld="true"> + <menu_item_call label="Quit" name="Quit" shortcut="control|Q" moonworld="true"> <on_click function="File.Quit" userdata="" /> </menu_item_call> </menu> - <menu create_jump_keys="true" label="Edit" name="Edit" + <menu create_jump_keys="true" label="Edit" name="Edit" moonworld="true" opaque="true" tear_off="false"> - <menu_item_call label="Preferences..." name="Preferences..." shortcut="control|P"> + <menu_item_call label="Preferences..." name="Preferences..." shortcut="control|P" moonworld="true"> <on_click function="ShowFloater" userdata="preferences" /> </menu_item_call> </menu> diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 01a5b6ee2..8045f8ca6 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu_bar name="Main Menu" drop_shadow="false" follows="left|top|right" +<menu_bar name="Main Menu" drop_shadow="false" follows="left|top|right" moonworld="true" opaque="false" tear_off="false"> <!-- FILE --> - <menu name="File" create_jump_keys="true" label="File" + <menu name="File" create_jump_keys="true" label="File" moonworld="true" opaque="true" tear_off="true"> <menu label="Upload" create_jump_keys="true" name="Upload" opaque="true" tear_off="true"> @@ -80,19 +80,19 @@ <on_enable function="File.EnableSaveAs" /> </menu_item_call> <menu_item_separator /> - <menu_item_call name="Take Snapshot" + <menu_item_call name="Take Snapshot" moonworld="true" label="Take Snapshot" shortcut="control|shift|S"> <on_click function="File.TakeSnapshot" userdata="" /> </menu_item_call> - <menu_item_call name="Snapshot to Disk" + <menu_item_call name="Snapshot to Disk" moonworld="true" label="Snapshot to Disk" shortcut="control|`" useMacCtrl="true"> <on_click function="File.TakeSnapshotToDisk" userdata="" /> </menu_item_call> - <menu_item_separator /> - <menu_item_call name="Quit" label="Quit" + <menu_item_separator moonworld="true" /> + <menu_item_call name="Quit" label="Quit" moonworld="true" shortcut="control|Q"> <on_click function="File.Quit" userdata="" /> </menu_item_call> @@ -102,7 +102,7 @@ <!-- EDIT --> - <menu name="Edit" create_jump_keys="true" label="Edit" + <menu name="Edit" create_jump_keys="true" label="Edit" moonworld="true" opaque="true" tear_off="true"> <menu_item_call name="Undo" enabled="false" label="Undo" shortcut="control|Z"> @@ -273,7 +273,7 @@ userdata="agent" /> </menu_item_call> <menu_item_separator /> - <menu_item_call name="Preferences..." label="Preferences..." + <menu_item_call name="Preferences..." label="Preferences..." moonworld="true" shortcut="control|P"> <on_click function="ShowFloater" userdata="preferences" /> @@ -284,9 +284,9 @@ <!-- VIEW --> - <menu name="View" create_jump_keys="true" label="View" + <menu name="View" create_jump_keys="true" label="View" moonworld="true" opaque="true" tear_off="true"> - <menu_item_call name="Mouselook" label="Mouselook" + <menu_item_call name="Mouselook" label="Mouselook" moonworld="true" shortcut="M"> <on_click function="View.Mouselook" userdata="" /> <on_enable function="View.EnableMouselook" /> @@ -302,7 +302,7 @@ <on_check function="View.CheckJoystickFlycam" /> <on_enable function="View.EnableJoystickFlycam" /> </menu_item_check> - <menu_item_call name="Reset View" label="Reset View" + <menu_item_call name="Reset View" label="Reset View" moonworld="true" shortcut="Esc"> <on_click function="View.ResetView" userdata="" /> </menu_item_call> @@ -439,17 +439,17 @@ <on_check function="View.CheckHUDAttachments" /> </menu_item_check> <menu_item_separator /> - <menu name="Zoom Level" create_jump_keys="true" + <menu name="Zoom Level" create_jump_keys="true" moonworld="true" label="Zoom Level" opaque="true" tear_off="true"> - <menu_item_call name="Zoom In" label="Zoom In" + <menu_item_call name="Zoom In" label="Zoom In" moonworld="true" shortcut="control|0"> <on_click function="View.ZoomIn" userdata="" /> </menu_item_call> - <menu_item_call name="Zoom Default" label="Zoom Default" + <menu_item_call name="Zoom Default" label="Zoom Default" moonworld="true" shortcut="control|9"> <on_click function="View.ZoomDefault" userdata="" /> </menu_item_call> - <menu_item_call name="Zoom Out" label="Zoom Out" + <menu_item_call name="Zoom Out" label="Zoom Out" moonworld="true" shortcut="control|8"> <on_click function="View.ZoomOut" userdata="" /> </menu_item_call> @@ -472,7 +472,7 @@ <!-- WORLD --> - <menu name="World" create_jump_keys="true" label="World" + <menu name="World" create_jump_keys="true" label="World" moonworld="true" opaque="true" tear_off="true"> <menu_item_call name="Chat" label="Chat" shortcut=""> <on_click function="World.Chat" userdata="" /> @@ -515,7 +515,7 @@ <on_check function="World.CheckAutoResponse" userdata="" /> </menu_item_check> <menu_item_separator /> - <menu_item_call name="Stop Animating My Avatar" enabled="false" + <menu_item_call name="Stop Animating My Avatar" enabled="false" moonworld="true" label="Stop Animating My Avatar"> <on_click function="Tools.StopAllAnimations" userdata="" /> </menu_item_call> From eac7d20472b5552683ec04b1420e81281caa39fc Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 12 Jan 2011 15:00:46 +0100 Subject: [PATCH 233/239] Enable LightShare by default. The Setting 'LightShareAllowed' is set to 2 (always allow LightShare being set by the region) and made non-persistent. Also, in the preferences panel the choice to change it has been removed. --- linden/indra/llui/lluictrlfactory.cpp | 9 ++++++++- linden/indra/newview/app_settings/settings.xml | 4 ++-- linden/indra/newview/llprefsadvanced.cpp | 9 +++++---- .../default/xui/en-us/panel_preferences_advanced.xml | 4 ++-- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/linden/indra/llui/lluictrlfactory.cpp b/linden/indra/llui/lluictrlfactory.cpp index 5cfc3ee38..59acf624f 100644 --- a/linden/indra/llui/lluictrlfactory.cpp +++ b/linden/indra/llui/lluictrlfactory.cpp @@ -480,7 +480,14 @@ LLView *LLUICtrlFactory::createCtrlWidget(LLPanel *parent, LLXMLNodePtr node) } parent = mDummyPanel; } - LLView *ctrl = func(node, parent, this); + LLView *ctrl = NULL; + + // MoonWorld: Add widgets at normal, *unless* they have the attribute moonworld="false". + bool moonworld = true; + if (!node->getAttribute_bool("moonworld", moonworld) || moonworld) // Does not have the attribute, or it is set to "true"? + { + ctrl = func(node, parent, this); + } return ctrl; } diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index c45e0bd0a..83bc9df3b 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -658,11 +658,11 @@ <key>Comment</key> <string>Allow LightShare (Windlight settings broadcast from the region): Never (0), Ask (1), or Always (2).</string> <key>Persist</key> - <integer>1</integer> + <integer>0</integer> <key>Type</key> <string>U32</string> <key>Value</key> - <integer>0</integer> + <integer>2</integer> </map> <key>LightShareIgnoreTimer</key> <map> diff --git a/linden/indra/newview/llprefsadvanced.cpp b/linden/indra/newview/llprefsadvanced.cpp index 99bc4fdca..643db377f 100644 --- a/linden/indra/newview/llprefsadvanced.cpp +++ b/linden/indra/newview/llprefsadvanced.cpp @@ -100,8 +100,9 @@ BOOL LLPrefsAdvanced::postBuild() childSetValue("shadows_check", gSavedSettings.getBOOL("ShadowsEnabled")); childSetValue("command_line_check", gSavedSettings.getBOOL("CmdLineChatbarEnabled")); - childSetValue("lightshare_combo", - LLSD((S32)gSavedSettings.getU32("LightShareAllowed"))); + // MoonWorld: this setting is disabled. The combo box doesn't exist anymore. + //childSetValue("lightshare_combo", + // LLSD((S32)gSavedSettings.getU32("LightShareAllowed"))); LLComboBox* crash_behavior_combobox = getChild<LLComboBox>("crash_behavior_combobox"); crash_behavior_combobox->setCurrentByIndex(gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING)); @@ -135,8 +136,8 @@ void LLPrefsAdvanced::apply() gSavedSettings.setBOOL("LanguageIsPublic", childGetValue("language_is_public")); gSavedSettings.setBOOL("AllowMUpose", childGetValue("allow_mupose")); gSavedSettings.setBOOL("AutoCloseOOC", childGetValue("auto_close_ooc")); - gSavedSettings.setU32("LightShareAllowed", - (U32)childGetValue("lightshare_combo").asInteger()); + // MoonWorld: this setting is disabled. The combo box doesn't exist anymore. + //gSavedSettings.setU32("LightShareAllowed", (U32)childGetValue("lightshare_combo").asInteger()); // Need to force a rebake when ClothingLayerProtection toggled for it take effect -- MC if (gSavedSettings.getBOOL("ShowMyClientTagToOthers") != (BOOL)childGetValue("client_name_tag_broadcast_check")) diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml index 1b771b5c4..eeaf094d9 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml @@ -38,11 +38,11 @@ font="SansSerifSmall" height="16" initial_value="false" label="Enable shadows (WARNING: unstable and requires Ultra graphics)" left="12" mouse_opaque="true" name="shadows_check" radio_style="false" width="217" /> - <text bottom_delta="-25" left="16" height="15" width="300" + <text bottom_delta="-25" left="16" height="15" width="300" moonworld="false" follows="top|left"> Allow region WindLight settings (LightShare): </text> - <combo_box name="lightshare_combo" + <combo_box name="lightshare_combo" moonworld="false" bottom_delta="-2" left_delta="250" height="18" width="135" allow_text_entry="false" follows="left|top"> <combo_item type="string" name="never" value="0"> From b98937f94381c5a8c27821b5637fb4e4b6c5fc85 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 12 Jan 2011 15:18:51 +0100 Subject: [PATCH 234/239] Disabled object pie menu's except Touch and Sit. Approach is the same as with normal menu's: The default value of the 'moonworld' attribute (when it is not there) is 'true', causing everything to be added as before. By adding the 'moonworld' attribute, the default for that node's children becomes 'false'. If the attribute is true, the node is added, if it is false (or absent, and the parent has the attribute) then the node and all it's children are skipped. This allows to restrict the pie menu's with only a minimal amount of changes to it's xml file and makes it flexible to enable/disable things later. --- linden/indra/llui/llmenugl.cpp | 8 ++++++++ linden/indra/newview/llvoavatar.cpp | 3 ++- .../skins/default/xui/en-us/legacy_menu_pie_object.xml | 6 +++--- .../newview/skins/default/xui/en-us/menu_pie_object.xml | 6 +++--- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp index bc43009cb..91e0b200b 100644 --- a/linden/indra/llui/llmenugl.cpp +++ b/linden/indra/llui/llmenugl.cpp @@ -3242,9 +3242,17 @@ LLXMLNodePtr LLPieMenu::getXML(bool save_children) const void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory) { + // If 'node' (the parent of the piemenu item 'child') has the attribute moonworld, + // then and only then hide all children that do NOT have that attribute (or have + // it set to false). + bool parent_has_moonworld = node->hasMoonWorld(); LLXMLNodePtr child; for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { + if (!child->isMoonWorld(!parent_has_moonworld)) // Parent has attribute and child does not? + { + continue; // Skip it. + } if (child->hasName(LL_PIE_MENU_TAG)) { // SUBMENU diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 8a2c09460..3067368cd 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -2039,7 +2039,8 @@ void LLVOAvatar::buildCharacter() //------------------------------------------------------------------------- // build the attach and detach menus //------------------------------------------------------------------------- - if (mIsSelf) + // MoonWorld: gAttachPieMenu is no more. + if (gAttachPieMenu && mIsSelf) { // *TODO: Translate gAttachBodyPartPieMenus[0] = NULL; diff --git a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_object.xml b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_object.xml index ff142b599..f1431a117 100644 --- a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_object.xml +++ b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_object.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Object Pie"> +<pie_menu name="Object Pie" moonworld="true"> <menu_item_call enabled="false" label="Open" mouse_opaque="true" name="Open"> <on_click function="Object.Open" /> <on_enable function="Object.EnableOpen" /> @@ -8,11 +8,11 @@ <on_click function="Object.Build" /> <on_enable function="EnableEdit" /> </menu_item_call> - <menu_item_call enabled="false" label="Touch" mouse_opaque="true" name="Object Touch"> + <menu_item_call enabled="false" label="Touch" mouse_opaque="true" name="Object Touch" moonworld="true"> <on_click function="Object.Touch" /> <on_enable function="Object.EnableTouch" userdata="Touch" name="EnableTouch"/> </menu_item_call> - <menu_item_call enabled="false" label="Sit Here" mouse_opaque="true" name="Object Sit"> + <menu_item_call enabled="false" label="Sit Here" mouse_opaque="true" name="Object Sit" moonworld="true"> <on_click function="Object.SitOrStand" /> <on_enable function="Object.EnableSitOrStand" userdata="Sit Here,Stand Up" name="EnableSitOrStand"/> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml b/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml index ec828dfde..97f9dbc65 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Object Pie"> +<pie_menu name="Object Pie" moonworld="true"> <menu_item_call enabled="false" label="Open" mouse_opaque="true" name="Open"> <on_click function="Object.Open" /> <on_enable function="Object.EnableOpen" /> @@ -8,11 +8,11 @@ <on_click function="Object.Buy" /> <on_enable function="Object.EnableBuy" /> </menu_item_call> - <menu_item_call enabled="false" label="Touch" mouse_opaque="true" name="Object Touch"> + <menu_item_call enabled="false" label="Touch" mouse_opaque="true" name="Object Touch" moonworld="true"> <on_click function="Object.Touch" /> <on_enable function="Object.EnableTouch" userdata="Touch" name="EnableTouch"/> </menu_item_call> - <menu_item_call enabled="false" label="Sit Here" mouse_opaque="true" name="Object Sit"> + <menu_item_call enabled="false" label="Sit Here" mouse_opaque="true" name="Object Sit" moonworld="true"> <on_click function="Object.SitOrStand" /> <on_enable function="Object.EnableSitOrStand" userdata="Sit Here,Stand Up" name="EnableSitOrStand"/> </menu_item_call> From 0799339551ca13ad61a5f2bc30c65916883f819c Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 12 Jan 2011 21:42:20 +0100 Subject: [PATCH 235/239] Disable all buttons in the toolbar except Snapshot and Inventory This required more changes to indra/newview/skins/default/xui/en-us/panel_toolbar.xml than adding 'moonworld="true"': that results in the two buttons using up the whole window width. So, I set the width of the buttons to a fixed size of 100 pixels now, and have them follow the right side of the window. --- linden/indra/llui/llpanel.cpp | 8 ++++++++ .../skins/default/xui/en-us/panel_toolbar.xml | 12 ++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index 07e78eda9..7936715a4 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp @@ -1264,8 +1264,16 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor layout_stackp->initFromXML(node, parent); LLXMLNodePtr child; + // If 'node' (the layoutstack) has the attribute moonworld="true", + // then and only then hide all children that do NOT have that attribute. + bool parent_has_moonworld = node->hasMoonWorld(); for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { + if (!child->isMoonWorld(!parent_has_moonworld)) // Parent has attribute and child does not? + { + continue; // Skip it. + } + S32 min_width = 0; S32 min_height = 0; BOOL auto_resize = TRUE; diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_toolbar.xml b/linden/indra/newview/skins/default/xui/en-us/panel_toolbar.xml index 7a82674b4..00a6a737c 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_toolbar.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_toolbar.xml @@ -5,8 +5,8 @@ <string name="Redock Windows">Redock Windows</string> <!-- panel bottom="0" filename="panel_bg_toolbar.xml" height="28" left="0" width="1024" /--> - <layout_stack name="toolbar_stack" follows="left|right|bottom|top" bottom="2" left="1" width="1022" height="26" min_width="200" min_height="26" orientation="horizontal" border_size="0"> - <icon image_name="spacer24.tga" width="2" height="2" follows="left|right" auto_resize="false" color="0,0,0,0" left="0" /> + <layout_stack name="toolbar_stack" follows="left|right|bottom|top" bottom="2" left="1" width="1022" height="26" min_width="200" min_height="26" orientation="horizontal" border_size="0" moonworld="true"> + <icon image_name="spacer24.tga" width="2" height="2" follows="left|right" auto_resize="true" color="0,0,0,0" left="0" moonworld="true" /> <button bottom="0" font="SansSerif" height="24" image_selected="btn_chatbar_selected.tga" scale_image="true" image_unselected="btn_chatbar.tga" label="" left="2" name="chat_btn" @@ -26,13 +26,13 @@ label_selected="Stop Flying" left="0" name="fly_btn" tool_tip="Start flying. Use E/C or PgUp/PgDn to fly up and down." width="40" follows="left|right" user_resize="false"/> - <button bottom="0" font="SansSerif" height="24" label="Snapshot" left="0" + <button bottom="0" font="SansSerif" height="24" label="Snapshot" right="-10" moonworld="true" image_overlay="icn_toolbar_snapshot.tga" image_overlay_alignment="left" image_selected="toolbar_btn_selected.tga" image_unselected="toolbar_btn_enabled.tga" image_disabled="toolbar_btn_disabled.tga" scale_image="true" name="snapshot_btn" tool_tip="Save a screen shot to disk or inventory." - width="50" follows="left|right" user_resize="false"/> + width="100" min_width="100" auto_resize="false" follows="right" user_resize="false"/> <button bottom="0" font="SansSerif" height="24" label="Search" left="0" image_overlay="icn_toolbar_search.tga" image_overlay_alignment="left" image_selected="toolbar_btn_selected.tga" @@ -59,12 +59,12 @@ image_disabled="toolbar_btn_disabled.tga" scale_image="true" name="radar_btn" tool_tip="Map of the area around you. (Ctrl-Shift-M)" width="50" follows="left|right" user_resize="false"/> - <button bottom="0" font="SansSerif" height="24" label="Inventory" left="0" + <button bottom="0" font="SansSerif" height="24" label="Inventory" right="-10" moonworld="true" image_overlay="icn_toolbar_inventory.tga" image_overlay_alignment="left" image_selected="toolbar_btn_selected.tga" image_unselected="toolbar_btn_enabled.tga" image_disabled="toolbar_btn_disabled.tga" scale_image="true" - name="inventory_btn" tool_tip="Your items. (Ctrl-I)" width="50" follows="left|right" user_resize="false"/> + name="inventory_btn" tool_tip="Your items. (Ctrl-I)" width="100" min_width="100" auto_resize="false" follows="right" user_resize="false"/> </layout_stack> </panel> From cc155107bd01704453c36686239aecfc4141b92c Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 12 Jan 2011 21:46:02 +0100 Subject: [PATCH 236/239] Status bar fixup --- linden/indra/newview/llstatusbar.cpp | 8 ++++++-- .../skins/default/xui/en-us/panel_status_bar.xml | 12 ++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp index 3370f7fbd..4f9864b7c 100644 --- a/linden/indra/newview/llstatusbar.cpp +++ b/linden/indra/newview/llstatusbar.cpp @@ -109,7 +109,7 @@ const F32 ICON_TIMER_EXPIRY = 3.f; // How long the balance and health icons sho const F32 ICON_FLASH_FREQUENCY = 2.f; const S32 TEXT_HEIGHT = 18; -static void onClickParcelInfo(void*); +//static void onClickParcelInfo(void*); static void onClickBalance(void*); static void onClickBuyCurrency(void*); static void onClickHealth(void*); @@ -164,7 +164,8 @@ mSquareMetersCommitted(0) childSetAction("buycurrency", onClickBuyCurrency, this ); childSetActionTextbox("BalanceText", onClickBalance ); - childSetActionTextbox("ParcelNameText", onClickParcelInfo ); + // MoonWorld: Don't open About Land when user clicks on parcel name in the status bar. + //childSetActionTextbox("ParcelNameText", onClickParcelInfo ); // TODO: Disable buying currency when connected to non-SL grids // that don't support currency yet -- MC @@ -754,12 +755,15 @@ S32 LLStatusBar::getSquareMetersLeft() const return mSquareMetersCredit - mSquareMetersCommitted; } +// MoonWorld: this function is no longer used. +#if 0 static void onClickParcelInfo(void* data) { LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal()); LLFloaterLand::showInstance(); } +#endif static void onClickBalance(void* data) { diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_status_bar.xml b/linden/indra/newview/skins/default/xui/en-us/panel_status_bar.xml index 46ba64abc..79d5a48cd 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_status_bar.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_status_bar.xml @@ -8,11 +8,11 @@ follows="left|right|bottom" font="SansSerifSmall" h_pad="0" halign="left" height="18" hover="true" left="561" mouse_opaque="true" name="ParcelNameText" text_color="ParcelTextColor" hover_color="ParcelHoverColor" - tool_tip="Name of land parcel on which you are standing. Click for About Land." + tool_tip="Name of land parcel on which you are standing." v_pad="2" width="1039"> parcel name goes here </text> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" moonworld="false" bottom="-20" disabled_color="BalanceTextColor" drop_shadow_visible="true" enabled="true" follows="right|bottom" font="SansSerifSmall" h_pad="0" halign="right" height="18" left="-210" mouse_opaque="true" @@ -20,7 +20,7 @@ v_pad="2" width="76"> Loading... </text> - <button bottom="-18" enabled="true" follows="right|bottom" font="SansSerifSmall" + <button bottom="-18" enabled="true" follows="right|bottom" font="SansSerifSmall" moonworld="false" halign="center" height="18" image_selected="button_enabled_selected_32x128.tga" image_unselected="button_enabled_32x128.tga" label="[CURRENCY]" @@ -82,7 +82,7 @@ tool_tip="Buy this parcel" visible="false" width="16" /> <!-- Totally unsexy button hack to get a sexy bevel for sexy search bevel -brent --> - <button bottom="-17" height="16" left="-95" width="94" + <button bottom="-17" height="16" left="-95" width="94" moonworld="false" image_unselected="sm_rounded_corners_simple.tga" image_selected="sm_rounded_corners_simple.tga" image_hover_selected="sm_rounded_corners_simple.tga" @@ -91,14 +91,14 @@ image_disabled="sm_rounded_corners_simple.tga" label="" scale_image="true" enabled="true" mouse_opaque="false" name="menubar_search_bevel_bg"/> - <line_editor bevel_style="none" border_style="line" border_thickness="0" border_drop_shadow_visible="false" bottom="-16" + <line_editor bevel_style="none" border_style="line" border_thickness="0" border_drop_shadow_visible="false" bottom="-16" moonworld="false" commit_on_focus_lost="false" enabled="true" follows="right|bottom" font="SansSerifSmall" handle_edit_keys_directly="false" height="11" label="Search" left="-94" max_length="254" mouse_opaque="true" name="search_editor" select_all_on_focus_received="false" select_on_focus="false" tab_group="1" tool_tip="Inworld search" width="78" spell_check="true"/> - <button bottom="-17" enabled="true" follows="right|bottom" font="SansSerifSmall" + <button bottom="-17" enabled="true" follows="right|bottom" font="SansSerifSmall" moonworld="false" halign="center" height="16" image_unselected="status_search_btn.png" image_selected="status_search_btn_pressed.png" image_disabled_selected="status_search_btn_pressed.png" image_disabled="status_search_btn.png" label="" label_selected="" left="-16" mouse_opaque="true" name="search_btn" tool_tip="Search Second Life" width="16" scale_image="false"/> From d90b888997cd67ce501d58df906b88deb8e41f63 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Wed, 12 Jan 2011 21:46:55 +0100 Subject: [PATCH 237/239] Change viewer name into "MoonWorld" --- linden/indra/newview/viewerversion.cpp | 2 +- linden/indra/newview/viewerversion.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linden/indra/newview/viewerversion.cpp b/linden/indra/newview/viewerversion.cpp index 95c8f7690..cb541484c 100644 --- a/linden/indra/newview/viewerversion.cpp +++ b/linden/indra/newview/viewerversion.cpp @@ -40,7 +40,7 @@ S32 ViewerVersion::sVersionMinor = 0; S32 ViewerVersion::sVersionPatch = 0; std::string ViewerVersion::sVersionTest = ""; -const std::string ViewerVersion::sViewerName = "Imprudence"; +const std::string ViewerVersion::sViewerName = "MoonWorld"; ViewerVersion::ViewerVersion() { diff --git a/linden/indra/newview/viewerversion.h b/linden/indra/newview/viewerversion.h index d67cee5f2..bd4baec72 100644 --- a/linden/indra/newview/viewerversion.h +++ b/linden/indra/newview/viewerversion.h @@ -49,7 +49,7 @@ class ViewerVersion static S32 getImpPatchVersion() { return sVersionPatch; } // Returns the test version of Imprudence static std::string getImpTestVersion() { return sVersionTest; } - // Returns the name of the viewer. Currently always "Imprudence" + // Returns the name of the viewer. Currently always "MoonWorld" static std::string getImpViewerName() { return sViewerName; } // Returns the major version of Second Life From 371ca2086dae120eeb7dcb2f391ad8879988ecc9 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 14 Jan 2011 20:33:48 +0100 Subject: [PATCH 238/239] Fix up other pie menu's (land, avatar, attachment). As per Dennis' email: Pie Chart on Land ==> not needed, please remove entirely Pie Chart on right click of another avatar ==> not needed, please remove entirely Pie Chart on right click of self ==> please remove all options except for "Take Off" Pie Chart on right click of attachments worn by self ==> please remove all options except for "More.../Detach" --- linden/indra/llui/llmenugl.cpp | 3 +++ linden/indra/llui/llmenugl.h | 2 +- linden/indra/llui/lluictrlfactory.cpp | 6 ++++++ linden/indra/newview/llselectmgr.cpp | 6 +++--- linden/indra/newview/lltoolpie.cpp | 12 +++++++++--- linden/indra/newview/llviewermenu.cpp | 2 +- .../xui/en-us/legacy_menu_pie_attachment.xml | 4 ++-- .../xui/en-us/legacy_menu_pie_avatar.xml | 2 +- .../default/xui/en-us/legacy_menu_pie_land.xml | 2 +- .../default/xui/en-us/legacy_menu_pie_self.xml | 18 +++++++++--------- .../default/xui/en-us/menu_pie_attachment.xml | 6 +++--- .../default/xui/en-us/menu_pie_avatar.xml | 2 +- .../skins/default/xui/en-us/menu_pie_hud.xml | 4 ++-- .../skins/default/xui/en-us/menu_pie_land.xml | 2 +- .../skins/default/xui/en-us/menu_pie_self.xml | 12 ++++++------ 15 files changed, 49 insertions(+), 34 deletions(-) diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp index 91e0b200b..3c3d4ddb7 100644 --- a/linden/indra/llui/llmenugl.cpp +++ b/linden/indra/llui/llmenugl.cpp @@ -3797,6 +3797,9 @@ S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) { + // MoonWorld: Some pie menu's don't exist anymore. + if (!this) return; + S32 width = getRect().getWidth(); S32 height = getRect().getHeight(); diff --git a/linden/indra/llui/llmenugl.h b/linden/indra/llui/llmenugl.h index 63f9d555d..8ab6fc472 100644 --- a/linden/indra/llui/llmenugl.h +++ b/linden/indra/llui/llmenugl.h @@ -434,7 +434,7 @@ class LLMenuGL // background colors static void setDefaultBackgroundColor( const LLColor4& color ) { sDefaultBackgroundColor = color; } - void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; } + void setBackgroundColor( const LLColor4& color ) { if (this) { mBackgroundColor = color; } } const LLColor4& getBackgroundColor() const { return mBackgroundColor; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; } void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); diff --git a/linden/indra/llui/lluictrlfactory.cpp b/linden/indra/llui/lluictrlfactory.cpp index 59acf624f..5e4232e0a 100644 --- a/linden/indra/llui/lluictrlfactory.cpp +++ b/linden/indra/llui/lluictrlfactory.cpp @@ -388,6 +388,12 @@ LLPieMenu *LLUICtrlFactory::buildPieMenu(const std::string &filename, LLView* pa return NULL; } + // MoonWorld: Don't show empty pie menu's. + if (!root->isMoonWorld(true)) // Has explicit attribute moonworld="false" ? + { + return NULL; + } + std::string name("menu"); root->getAttributeString("name", name); diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index b0a6834a5..6496ff376 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -3481,7 +3481,7 @@ void LLSelectMgr::deselectAllIfTooFar() // HACK: Don't deselect when we're navigating to rate an object's // owner or creator. JC - if (gPieObject->getVisible()) + if (gPieObject && gPieObject->getVisible()) { return; } @@ -5505,12 +5505,12 @@ void dialog_refresh_all() gFloaterTools->dirty(); - if( gPieObject->getVisible() ) + if( gPieObject && gPieObject->getVisible() ) { gPieObject->arrange(); } - if( gPieAttachment->getVisible() ) + if( gPieAttachment && gPieAttachment->getVisible() ) { gPieAttachment->arrange(); } diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp index 34735a391..46f122f3d 100644 --- a/linden/indra/newview/lltoolpie.cpp +++ b/linden/indra/newview/lltoolpie.cpp @@ -350,6 +350,8 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) // Spawn pie menu if (mPick.mPickType == LLPickInfo::PICK_LAND) { + if (gPieLand) // MoonWorld: gPieLand is gone! + { LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal ); gMenuHolder->setParcelSelection(selection); gPieLand->show(x, y, mPieMouseButtonDown); @@ -359,15 +361,16 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) effectp->setPositionGlobal(mPick.mPosGlobal); effectp->setColor(LLColor4U(gAgent.getEffectColor())); effectp->setDuration(0.25f); + } } else if (object && is_self) { -// if(gPieSelf) -// { + if(gPieSelf) + { //either at very early startup stage or at late quitting stage, //this event is ignored. gPieSelf->show(x, y, mPieMouseButtonDown); -// } + } } @@ -457,6 +460,8 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) ) { // [/RLVa:KB] + if (gPieObject) // MoonWorld: Allow the object pie menu to be gone. + { gPieObject->show(x, y, mPieMouseButtonDown); // VEFFECT: ShowPie object @@ -466,6 +471,7 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) effectp->setPositionGlobal(mPick.mPosGlobal); effectp->setColor(LLColor4U(gAgent.getEffectColor())); effectp->setDuration(0.25f); + } // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f } else diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index f70cc4199..503613ecd 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -6710,7 +6710,7 @@ class LLWornItemFetchedObserver : public LLInventoryFetchObserver protected: virtual void done() { - gPieAttachment->buildDrawLabels(); + if (gPieAttachment) gPieAttachment->buildDrawLabels(); gInventory.removeObserver(this); delete this; } diff --git a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml index 35f3037c3..ffdae9b32 100644 --- a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml +++ b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_attachment.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Attachment Pie"> +<pie_menu name="Attachment Pie" moonworld="true"> <menu_item_call enabled="false" label="Drop" mouse_opaque="true" name="Drop"> <on_click function="Attachment.Drop" /> <on_enable function="Attachment.EnableDrop" /> @@ -12,7 +12,7 @@ <on_enable function="Object.EnableInspect" /> </menu_item_call> <menu_item_separator /> - <menu_item_call enabled="false" label="Detach" mouse_opaque="true" name="Detach"> + <menu_item_call enabled="false" label="Detach" mouse_opaque="true" name="Detach" moonworld="true"> <on_click function="Attachment.Detach" /> <on_enable function="Attachment.EnableDetach" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_avatar.xml b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_avatar.xml index dcf752157..0ad035448 100644 --- a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_avatar.xml +++ b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_avatar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Avatar Pie"> +<pie_menu name="Avatar Pie" moonworld="false"> <menu_item_call enabled="false" label="Profile" mouse_opaque="true" name="Profile"> <on_click function="ShowAgentProfile" userdata="hit object" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_land.xml b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_land.xml index 766ad1b7c..87cf6193e 100644 --- a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_land.xml +++ b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_land.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Land Pie"> +<pie_menu name="Land Pie" moonworld="false"> <menu_item_call enabled="false" label="About Land" mouse_opaque="true" name="About Land"> <on_click function="ShowFloater" userdata="about land" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_self.xml b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_self.xml index d6409bfd1..cf7f93c1d 100644 --- a/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_self.xml +++ b/linden/indra/newview/skins/default/xui/en-us/legacy_menu_pie_self.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <pie_menu name="Self Pie"> - <menu_item_call enabled="true" label="Profile..." name="Profile..."> + <menu_item_call enabled="true" label="Profile..." name="Profile..." moonworld="false"> <on_click function="ShowAgentProfile" userdata="agent" /> </menu_item_call> - <menu_item_call enabled="true" label="Groups" name="Groups"> + <menu_item_call enabled="true" label="Groups" name="Groups" moonworld="false"> <on_click function="ShowAgentGroups" userdata="agent" /> </menu_item_call> - <menu_item_call enabled="true" label="Inventory" name="Inventory"> + <menu_item_call enabled="true" label="Inventory" name="Inventory" moonworld="false"> <on_click function="ShowFloater" userdata="inventory" /> </menu_item_call> - <menu_item_call enabled="true" label="Stand Up" name="Stand Up"> + <menu_item_call enabled="true" label="Stand Up" name="Stand Up" moonworld="false"> <on_click function="Self.StandUp" userdata="" /> <on_enable function="Self.EnableStandUp" /> </menu_item_call> - <menu_item_call enabled="true" label="Friends" name="Friends"> + <menu_item_call enabled="true" label="Friends" name="Friends" moonworld="false"> <on_click function="ShowFloater" userdata="friends" /> </menu_item_call> - <menu_item_call enabled="true" label="Gestures" name="Gestures"> + <menu_item_call enabled="true" label="Gestures" name="Gestures" moonworld="false"> <on_click function="ShowFloater" userdata="gestures" /> </menu_item_call> <pie_menu enabled="true" label="Take Off >" name="Take Off >"> @@ -84,16 +84,16 @@ </menu_item_call> </pie_menu> <menu_item_separator /> - <pie_menu enabled="true" label="HUD >" name="Object Detach HUD" /> + <pie_menu enabled="true" label="HUD >" name="Object Detach HUD" moonworld="false" /> <menu_item_separator /> - <pie_menu enabled="true" label="Detach >" name="Object Detach" /> + <pie_menu enabled="true" label="Detach >" name="Object Detach" moonworld="false" /> <menu_item_separator /> <menu_item_call enabled="true" label="Detach All" name="Detach All"> <on_click function="Self.RemoveAllAttachments" userdata="" /> <on_enable function="Self.EnableRemoveAllAttachments" /> </menu_item_call> </pie_menu> - <menu_item_call enabled="true" label="Appearance..." name="Appearance..."> + <menu_item_call enabled="true" label="Appearance..." name="Appearance..." moonworld="false"> <on_click function="ShowFloater" userdata="appearance" /> <on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml b/linden/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml index 439728564..200795616 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Attachment Pie"> +<pie_menu name="Attachment Pie" moonworld="true"> <menu_item_call enabled="true" label="Profile..." name="Profile..."> <on_click function="ShowAgentProfile" userdata="agent" /> </menu_item_call> @@ -21,13 +21,13 @@ <on_click function="ShowFloater" userdata="appearance" /> <on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> - <pie_menu label="More >" name="More >"> + <pie_menu label="More >" name="More >" moonworld="true"> <menu_item_call enabled="false" label="Drop" mouse_opaque="true" name="Drop"> <on_click function="Attachment.Drop" /> <on_enable function="Attachment.EnableDrop" /> </menu_item_call> <menu_item_separator /> - <menu_item_call enabled="false" label="Detach" mouse_opaque="true" name="Detach"> + <menu_item_call enabled="false" label="Detach" mouse_opaque="true" name="Detach" moonworld="true"> <on_click function="Attachment.Detach" /> <on_enable function="Attachment.EnableDetach" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml b/linden/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml index c87d7de8d..134b82b29 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Avatar Pie"> +<pie_menu name="Avatar Pie" moonworld="false"> <menu_item_call enabled="false" label="Profile" mouse_opaque="true" name="Profile"> <on_click function="ShowAgentProfile" userdata="hit object" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_pie_hud.xml b/linden/indra/newview/skins/default/xui/en-us/menu_pie_hud.xml index 64bb77945..967c6c0f6 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_pie_hud.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_pie_hud.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <pie_menu name="HUD Pie"> - <menu_item_call enabled="false" label="Drop" mouse_opaque="true" name="Drop"> + <menu_item_call enabled="false" label="Drop" mouse_opaque="true" name="Drop" moonworld="false"> <on_click function="Attachment.Drop" /> <on_enable function="Attachment.EnableDrop" /> </menu_item_call> @@ -10,7 +10,7 @@ <on_enable function="Attachment.EnableTouch" userdata="Touch" /> </menu_item_call> <menu_item_separator /> - <menu_item_call enabled="true" label="Inspect" mouse_opaque="true" name="Object Inspect"> + <menu_item_call enabled="true" label="Inspect" mouse_opaque="true" name="Object Inspect" moonworld="false"> <on_click function="Object.Inspect" /> <on_enable function="Object.EnableInspect" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_pie_land.xml b/linden/indra/newview/skins/default/xui/en-us/menu_pie_land.xml index af3fcd620..27772268f 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_pie_land.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_pie_land.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<pie_menu name="Land Pie"> +<pie_menu name="Land Pie" moonworld="false"> <menu_item_call enabled="false" label="About Land" mouse_opaque="true" name="About Land"> <on_click function="ShowFloater" userdata="about land" /> </menu_item_call> diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_pie_self.xml b/linden/indra/newview/skins/default/xui/en-us/menu_pie_self.xml index b8d69dad0..fe2d6223a 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_pie_self.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_pie_self.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <pie_menu name="Self Pie"> - <menu_item_call enabled="true" label="Profile..." name="Profile..."> + <menu_item_call enabled="true" label="Profile..." name="Profile..." moonworld="false"> <on_click function="ShowAgentProfile" userdata="agent" /> </menu_item_call> - <menu_item_call enabled="true" label="Groups" name="Groups"> + <menu_item_call enabled="true" label="Groups" name="Groups" moonworld="false"> <on_click function="ShowAgentGroups" userdata="agent" /> </menu_item_call> <menu_item_separator /> @@ -11,10 +11,10 @@ <on_click function="Self.StandUp" userdata="" /> <on_enable function="Self.EnableStandUp" /> </menu_item_call> - <menu_item_call enabled="true" label="Friends" name="Friends"> + <menu_item_call enabled="true" label="Friends" name="Friends" moonworld="false"> <on_click function="ShowFloater" userdata="friends" /> </menu_item_call> - <menu_item_call enabled="true" label="Appearance..." name="Appearance..."> + <menu_item_call enabled="true" label="Appearance..." name="Appearance..." moonworld="false"> <on_click function="ShowFloater" userdata="appearance" /> <on_enable function="Edit.EnableCustomizeAvatar" /> </menu_item_call> @@ -88,9 +88,9 @@ <on_enable function="Self.EnableRemoveAllAttachments" /> </menu_item_call> <menu_item_separator /> - <pie_menu enabled="true" label="Detach >" name="Object Detach" /> + <pie_menu enabled="true" label="Detach >" name="Object Detach" moonworld="false" /> <menu_item_separator /> - <pie_menu enabled="true" label="HUD >" name="Object Detach HUD" /> + <pie_menu enabled="true" label="HUD >" name="Object Detach HUD" moonworld="false" /> <menu_item_separator /> </pie_menu> <menu_item_separator /> From d97f540e020e0d638cee9f755578ed40a5ad8c58 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood <Aleric.Inglewood@gmail.com> Date: Fri, 14 Jan 2011 20:37:10 +0100 Subject: [PATCH 239/239] Disable automatic fly on Page Up --- linden/indra/newview/app_settings/settings.xml | 4 ++-- .../skins/default/xui/en-us/panel_preferences_input.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 83bc9df3b..11ae20afa 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -2589,11 +2589,11 @@ <key>Comment</key> <string>Fly by holding jump key or using "Fly" command (FALSE = fly by using "Fly" command only)</string> <key>Persist</key> - <integer>1</integer> + <integer>0</integer> <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>AvatarAxisDeadZone0</key> <map> diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml index 70c84644a..3d19a4d8c 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml @@ -24,13 +24,13 @@ follows="left|top" font="SansSerifSmall" height="16" initial_value="false" label="Show avatar in mouselook" left="148" mouse_opaque="true" name="first_person_avatar_visible" radio_style="false" width="256" /> - <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" + <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" moonworld="false" bottom_delta="-30" drop_shadow_visible="true" enabled="true" follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10" mouse_opaque="true" name=" Auto Fly Options:" v_pad="0" width="266"> Auto-Fly: </text> - <check_box bottom_delta="-6" enabled="true" follows="left|top" + <check_box bottom_delta="-6" enabled="true" follows="left|top" moonworld="false" font="SansSerifSmall" height="16" label="Fly/land on holding up/down" left="148" mouse_opaque="true" name="automatic_fly" radio_style="false" width="178" />