mirror of
https://github.com/FirestormViewer/phoenix-firestorm.git
synced 2026-08-14 00:48:30 +00:00
Merge branch 'develop' of https://github.com/secondlife/viewer
# Conflicts: # .github/workflows/build.yaml # indra/newview/llappdelegate-objc.mm # indra/newview/llappviewer.cpp # indra/newview/llconversationlog.cpp # indra/newview/llconversationloglistitem.cpp # indra/newview/llpanelprofile.cpp # indra/newview/llpanelprofile.h # indra/newview/llspeakers.cpp # indra/newview/llviewercontrol.cpp # indra/newview/pipeline.cpp # indra/newview/skins/default/xui/en/menu_viewer.xml # indra/newview/viewer_manifest.py
This commit is contained in:
@@ -362,8 +362,9 @@ jobs:
|
||||
|
||||
post-windows-symbols:
|
||||
env:
|
||||
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
|
||||
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
|
||||
BUGSPLAT_DATABASE: "${{ secrets.BUGSPLAT_DATABASE }}"
|
||||
SYMBOL_UPLOAD_CLIENT_ID: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
SYMBOL_UPLOAD_CLIENT_SECRET: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
needs: build
|
||||
if: needs.build.outputs.configuration == 'Release'
|
||||
runs-on: ubuntu-latest
|
||||
@@ -374,51 +375,56 @@ jobs:
|
||||
name: Windows-app
|
||||
path: _artifacts
|
||||
- name: Download Windows Symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: Windows-symbols
|
||||
- name: Extract viewer pdb
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xJf "${{ needs.build.outputs.viewer_channel }}.sym.tar.xz" -C _artifacts
|
||||
- name: Post Windows symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife-3p/symbol-upload@v10
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: BugSplat-Git/symbol-upload@095d163ae9ceb006d286a731dcd35cf6a1b458c8
|
||||
with:
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
clientId: "${{ env.SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
clientSecret: "${{ env.SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
database: "${{ env.BUGSPLAT_DATABASE }}"
|
||||
application: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }}
|
||||
directory: _artifacts
|
||||
files: "**/{SecondLifeViewer.exe,llwebrtc.dll,*.pdb}"
|
||||
node-version: "22"
|
||||
dumpSyms: false
|
||||
|
||||
post-mac-symbols:
|
||||
env:
|
||||
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
|
||||
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
|
||||
BUGSPLAT_DATABASE: "${{ secrets.BUGSPLAT_DATABASE }}"
|
||||
SYMBOL_UPLOAD_CLIENT_ID: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
SYMBOL_UPLOAD_CLIENT_SECRET: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
needs: build
|
||||
if: needs.build.outputs.configuration == 'Release'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download Mac Symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: macOS-symbols
|
||||
- name: Post Mac symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife-3p/symbol-upload@v10
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: BugSplat-Git/symbol-upload@095d163ae9ceb006d286a731dcd35cf6a1b458c8
|
||||
with:
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
clientId: "${{ env.SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
clientSecret: "${{ env.SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
database: "${{ env.BUGSPLAT_DATABASE }}"
|
||||
application: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }} (${{ needs.build.outputs.viewer_version }})
|
||||
directory: .
|
||||
files: "**/*.xcarchive.zip"
|
||||
node-version: "22"
|
||||
dumpSyms: false
|
||||
|
||||
release:
|
||||
needs: [setup, build, sign-and-package-windows, sign-and-package-mac]
|
||||
|
||||
+4
-4
@@ -468,11 +468,11 @@
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>cd1f1d55a2488657ec2253774b3a414621f81b24</string>
|
||||
<string>9bcafdd7e1df6b92096fa850627d4f3437630d4a</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.1.5-71fc41e/bugsplat-1.1.1-9599607655-darwin64-9599607655.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.2.6-a475cbb/bugsplat-1.2.6-19430122611-darwin64-19430122611.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
@@ -482,11 +482,11 @@
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9fb0615d17988bd89a2e5ae6d4d19e150afb54a9</string>
|
||||
<string>4e9f0c1cdbc1cebf6185ecc45228ced7f9af1532</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.1.5-71fc41e/bugsplat-5.0.1.0-9599607655-windows64-9599607655.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.2.6-a475cbb/bugsplat-6.1.1.0-19430122611-windows64-19430122611.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
||||
@@ -23,8 +23,14 @@ if (USE_BUGSPLAT)
|
||||
elseif (DARWIN)
|
||||
find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
|
||||
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
find_library(CRASHREPORTED_LIBRARIES CrashReporter REQUIRED
|
||||
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
find_library(HOCKEYSDK_LIBRARIES HockeySDK REQUIRED
|
||||
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
target_link_libraries( ll::bugsplat INTERFACE
|
||||
${BUGSPLAT_LIBRARIES}
|
||||
${CRASHREPORTED_LIBRARIES}
|
||||
${HOCKEYSDK_LIBRARIES}
|
||||
)
|
||||
else (WINDOWS) #ie: Linux...
|
||||
add_compile_definitions(__STDC_FORMAT_MACROS)
|
||||
|
||||
@@ -457,7 +457,8 @@ public:
|
||||
("slot", LLSD::Integer(mIndex))
|
||||
("name", whichfile(mIndex))
|
||||
("desc", mDesc)
|
||||
("eof", state == CLOSED));
|
||||
("eof", state == CLOSED)
|
||||
("exhst", state == EXHAUSTED));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -739,32 +739,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
// *NOTE:Mani - I didn't find any docs that assure me that machdep.cpu.feature_bits will always be
|
||||
// The feature bits I think it is. Here's a test:
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
#if defined(__i386__) && defined(__PIC__)
|
||||
/* %ebx may be the PIC register. */
|
||||
#define __cpuid(level, a, b, c, d) \
|
||||
__asm__ ("xchgl\t%%ebx, %1\n\t" \
|
||||
"cpuid\n\t" \
|
||||
"xchgl\t%%ebx, %1\n\t" \
|
||||
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
|
||||
: "0" (level))
|
||||
#else
|
||||
#define __cpuid(level, a, b, c, d) \
|
||||
__asm__ ("cpuid\n\t" \
|
||||
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
|
||||
: "0" (level))
|
||||
#endif
|
||||
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
__cpuid(0x1, eax, ebx, ecx, edx);
|
||||
if(feature_infos[0] != (S32)edx)
|
||||
{
|
||||
LL_WARNS() << "machdep.cpu.feature_bits doesn't match expected cpuid result!" << LL_ENDL;
|
||||
}
|
||||
#endif // LL_RELEASE_FOR_DOWNLOAD
|
||||
|
||||
// @TODO: Audit our usage of machdep.cpu.feature_bits.
|
||||
|
||||
uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
|
||||
S32 *ext_feature_infos = (S32*)(&ext_feature_info);
|
||||
|
||||
@@ -1207,8 +1207,8 @@ namespace tut
|
||||
{
|
||||
set_test_name("ReadPipe \"eof\" event");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
"from __future__ import print_function\n"
|
||||
"print('Hello from Python!')\n");
|
||||
"import time\n"
|
||||
"time.sleep(1.5)\n");
|
||||
py.mParams.files.add(LLProcess::FileParam()); // stdin
|
||||
py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
|
||||
py.launch();
|
||||
|
||||
@@ -517,7 +517,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
||||
{ //search from the current gpu class down to class 1 to find the most relevant shader
|
||||
std::stringstream fname;
|
||||
fname << getShaderDirPrefix();
|
||||
fname << gpu_class << "/" << filename;
|
||||
fname << gpu_class << gDirUtilp->getDirDelimiter() << filename;
|
||||
|
||||
open_file_name = fname.str();
|
||||
|
||||
@@ -546,7 +546,14 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
|
||||
if (gDirUtilp->fileExists(open_file_name))
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GLSL Shader file failed to open: " << open_file_name << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -863,6 +870,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
||||
//load source
|
||||
if (ret)
|
||||
{
|
||||
LL_DEBUGS("ShaderLoading") << "glCreateShader done" << LL_ENDL;
|
||||
glShaderSource(ret, shader_code_count, (const GLchar**)shader_code_text, NULL);
|
||||
|
||||
error = glGetError();
|
||||
@@ -877,6 +885,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
||||
//compile source
|
||||
if (ret)
|
||||
{
|
||||
LL_DEBUGS("ShaderLoading") << "glShaderSource done" << U32(ret) << LL_ENDL;
|
||||
glCompileShader(ret);
|
||||
|
||||
error = glGetError();
|
||||
@@ -891,6 +900,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
||||
if (error == GL_NO_ERROR)
|
||||
{
|
||||
//check for errors
|
||||
LL_DEBUGS("ShaderLoading") << "glCompileShader done" << U32(ret) << LL_ENDL;
|
||||
GLint success = GL_TRUE;
|
||||
glGetShaderiv(ret, GL_COMPILE_STATUS, &success);
|
||||
|
||||
@@ -907,6 +917,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("ShaderLoading") << "loadShaderFile() completed, ret: " << U32(ret) << LL_ENDL;
|
||||
ret = 0;
|
||||
}
|
||||
stop_glerror();
|
||||
|
||||
@@ -3830,7 +3830,6 @@ S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offs
|
||||
void LLTextSegment::updateLayout(const LLTextBase& editor) {}
|
||||
F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; }
|
||||
bool LLTextSegment::canEdit() const { return false; }
|
||||
bool LLTextSegment::getPermitsEmoji() const { return true; }
|
||||
void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
|
||||
void LLTextSegment::linkToDocument(LLTextBase*) {}
|
||||
const LLUIColor& LLTextSegment::getColor() const { static const LLUIColor white = LLUIColorTable::instance().getColor("White", LLColor4::white); return white; }
|
||||
@@ -3874,6 +3873,11 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
|
||||
{
|
||||
mFontHeight = mStyle->getFont()->getLineHeight();
|
||||
mCanEdit = !mStyle->getDrawHighlightBg();
|
||||
if (!mCanEdit)
|
||||
{
|
||||
// Emoji shouldn't split the segment with the mention.
|
||||
mPermitsEmoji = false;
|
||||
}
|
||||
|
||||
LLUIImagePtr image = mStyle->getImage();
|
||||
if (image.notNull())
|
||||
@@ -4407,6 +4411,7 @@ LLInlineViewSegment::LLInlineViewSegment(const Params& p, S32 start, S32 end)
|
||||
mTopPad(p.top_pad),
|
||||
mBottomPad(p.bottom_pad)
|
||||
{
|
||||
mPermitsEmoji = false;
|
||||
}
|
||||
|
||||
LLInlineViewSegment::~LLInlineViewSegment()
|
||||
|
||||
@@ -61,13 +61,15 @@ class LLTextSegment
|
||||
public:
|
||||
LLTextSegment(S32 start, S32 end)
|
||||
: mStart(start),
|
||||
mEnd(end)
|
||||
mEnd(end),
|
||||
mPermitsEmoji(true)
|
||||
{}
|
||||
virtual ~LLTextSegment();
|
||||
virtual LLTextSegmentPtr clone(LLTextBase& terget) const { return new LLTextSegment(mStart, mEnd); }
|
||||
static LLStyleSP cloneStyle(LLTextBase& target, const LLStyle* source);
|
||||
|
||||
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
|
||||
bool getPermitsEmoji() const { return mPermitsEmoji; };
|
||||
|
||||
virtual bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
|
||||
virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
|
||||
@@ -87,7 +89,6 @@ public:
|
||||
virtual void updateLayout(const class LLTextBase& editor);
|
||||
virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
|
||||
virtual bool canEdit() const;
|
||||
virtual bool getPermitsEmoji() const;
|
||||
virtual void unlinkFromDocument(class LLTextBase* editor);
|
||||
virtual void linkToDocument(class LLTextBase* editor);
|
||||
|
||||
@@ -126,6 +127,8 @@ public:
|
||||
protected:
|
||||
S32 mStart;
|
||||
S32 mEnd;
|
||||
|
||||
bool mPermitsEmoji;
|
||||
};
|
||||
|
||||
class LLNormalTextSegment : public LLTextSegment
|
||||
@@ -256,7 +259,6 @@ public:
|
||||
/*virtual*/ void updateLayout(const class LLTextBase& editor);
|
||||
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
|
||||
/*virtual*/ bool canEdit() const { return false; }
|
||||
/*virtual*/ bool getPermitsEmoji() const { return false; }
|
||||
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
|
||||
/*virtual*/ void linkToDocument(class LLTextBase* editor);
|
||||
|
||||
|
||||
@@ -100,16 +100,19 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa
|
||||
std::string base_filename = search_paths.front();
|
||||
if (!base_filename.empty())
|
||||
{
|
||||
LLUICtrlFactory::instance().pushFileName(base_filename);
|
||||
LLUICtrlFactory *factory = LLUICtrlFactory::getInstance();
|
||||
factory->mFileNames.push_back(base_filename);
|
||||
|
||||
if (!LLXMLNode::getLayeredXMLNode(root_node, search_paths))
|
||||
if (LLXMLNode::getLayeredXMLNode(root_node, search_paths))
|
||||
{
|
||||
LLXUIParser parser;
|
||||
parser.readXUI(root_node, block, base_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Couldn't parse widget from: " << base_filename << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LLXUIParser parser;
|
||||
parser.readXUI(root_node, block, base_filename);
|
||||
LLUICtrlFactory::instance().popFileName();
|
||||
factory->mFileNames.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -919,14 +919,17 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
|
||||
config.set_max_port(60100);
|
||||
|
||||
webrtc::PeerConnectionDependencies pc_dependencies(this);
|
||||
if (mPeerConnectionFactory == nullptr)
|
||||
// Other thread manages mPeerConnectionFactory's lifetime and it can be reset
|
||||
// at any momment, create own scoped_refptr (atomic).
|
||||
webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory = mPeerConnectionFactory;
|
||||
if (peer_connection_factory == nullptr)
|
||||
{
|
||||
RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection, factory doesn't exist";
|
||||
// Too early?
|
||||
mPendingJobs--;
|
||||
return;
|
||||
}
|
||||
auto error_or_peer_connection = mPeerConnectionFactory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
|
||||
auto error_or_peer_connection = peer_connection_factory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
|
||||
if (error_or_peer_connection.ok())
|
||||
{
|
||||
mPeerConnection = std::move(error_or_peer_connection.value());
|
||||
@@ -959,10 +962,10 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
|
||||
audioOptions.noise_suppression = true;
|
||||
audioOptions.init_recording_on_send = false;
|
||||
|
||||
mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream");
|
||||
mLocalStream = peer_connection_factory->CreateLocalMediaStream("SLStream");
|
||||
|
||||
webrtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
|
||||
mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(audioOptions).get()));
|
||||
peer_connection_factory->CreateAudioTrack("SLAudio", peer_connection_factory->CreateAudioSource(audioOptions).get()));
|
||||
audio_track->set_enabled(false);
|
||||
mLocalStream->AddTrack(audio_track);
|
||||
|
||||
|
||||
@@ -36,16 +36,17 @@
|
||||
std::string secondLogPath;
|
||||
}
|
||||
|
||||
@property (assign) IBOutlet LLNSWindow *window;
|
||||
@property (assign) IBOutlet NSWindow *inputWindow;
|
||||
@property (assign) IBOutlet LLNonInlineTextView *inputView;
|
||||
@property (assign) IBOutlet LLNSWindow * _Nullable window;
|
||||
@property (assign) IBOutlet NSWindow * _Nullable inputWindow;
|
||||
@property (assign) IBOutlet LLNonInlineTextView * _Nullable inputView;
|
||||
|
||||
@property (retain) NSString *currentInputLanguage;
|
||||
@property (retain) NSString * _Nullable currentInputLanguage;
|
||||
|
||||
- (void) oneFrame;
|
||||
- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
|
||||
- (void) showInputWindow:(bool)show withEvent:(nullable NSEvent *)textEvent;
|
||||
- (void) languageUpdated;
|
||||
- (bool) romanScript;
|
||||
- (void) setBugsplatValue:(nullable NSString *)value forAttribute:(nullable NSString *)attribute;
|
||||
@end
|
||||
|
||||
@interface LLApplication : NSApplication
|
||||
|
||||
@@ -2594,16 +2594,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
||||
// Comes after WM_QUERYENDSESSION
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENDSESSION");
|
||||
LL_INFOS("Window") << "Received WM_ENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL;
|
||||
unsigned int end_session_flags = (U32)w_param;
|
||||
if (end_session_flags == 0)
|
||||
{
|
||||
// session is not actually ending
|
||||
return 0;
|
||||
}
|
||||
unsigned int end_session_flags = (U32)l_param;
|
||||
|
||||
if ((end_session_flags & ENDSESSION_CLOSEAPP)
|
||||
|| (end_session_flags & ENDSESSION_CRITICAL)
|
||||
|| (end_session_flags & ENDSESSION_LOGOFF))
|
||||
if (w_param == TRUE // if true, session is ending
|
||||
|| end_session_flags == 0 // not possible to determine type of the event
|
||||
// || (end_session_flags & ENDSESSION_CLOSEAPP)) system update or low resources, must be acompanied by w_param == TRUE
|
||||
|| (end_session_flags & ENDSESSION_CRITICAL) // will shutdown regardless of app state
|
||||
|| (end_session_flags & ENDSESSION_LOGOFF)) // logoff, can delay shutdown
|
||||
{
|
||||
window_imp->post([=]()
|
||||
{
|
||||
@@ -2612,13 +2609,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
||||
{
|
||||
// Get the app to initiate cleanup.
|
||||
window_imp->mCallbacks->handleQuit(window_imp);
|
||||
// The app is responsible for calling destroyWindow when done with GL
|
||||
}
|
||||
});
|
||||
// Give app a second to finish up. That's not enough for a clean exit,
|
||||
// but better than nothing.
|
||||
// Todo: sync this better, some kind of waitForResult? Can't wait forever,
|
||||
// but can potentially use ShutdownBlockReasonCreate for a bigger delay.
|
||||
// but for ENDSESSION_LOGOFF can potentially use ShutdownBlockReasonCreate
|
||||
// for a bigger delay.
|
||||
ms_sleep(1000);
|
||||
}
|
||||
// Don't need to post quit or destroy window,
|
||||
|
||||
@@ -10656,7 +10656,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
||||
<key>RenderAvatarCloth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>DEPRECATED - only false supported - Controls if avatars use wavy cloth</string>
|
||||
<string>Controls if system avatar clothes use wavy cloth</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
||||
@@ -28,6 +28,9 @@ uniform mat4 projection_matrix;
|
||||
in vec3 position;
|
||||
in vec3 normal;
|
||||
in vec2 texcoord0;
|
||||
#ifdef AVATAR_CLOTH
|
||||
in vec4 clothing;
|
||||
#endif
|
||||
|
||||
mat4 getSkinnedTransform();
|
||||
|
||||
@@ -37,6 +40,15 @@ out vec3 vary_normal;
|
||||
out vec2 vary_texcoord0;
|
||||
out vec3 vary_position;
|
||||
|
||||
#ifdef AVATAR_CLOTH
|
||||
uniform vec4 gWindDir;
|
||||
uniform vec4 gSinWaveParams;
|
||||
uniform vec4 gGravity;
|
||||
|
||||
const vec4 gMinMaxConstants = vec4(1.0, 0.166666, 0.0083143, .00018542); // #minimax-generated coefficients
|
||||
const vec4 gPiConstants = vec4(0.159154943, 6.28318530, 3.141592653, 1.5707963); // # {1/2PI, 2PI, PI, PI/2}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vary_texcoord0 = texcoord0;
|
||||
@@ -46,16 +58,78 @@ void main()
|
||||
|
||||
vec4 pos_in = vec4(position.xyz, 1.0);
|
||||
mat4 trans = getSkinnedTransform();
|
||||
pos.x = dot(trans[0], pos_in);
|
||||
pos.y = dot(trans[1], pos_in);
|
||||
pos.z = dot(trans[2], pos_in);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, normal);
|
||||
norm.y = dot(trans[1].xyz, normal);
|
||||
norm.z = dot(trans[2].xyz, normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
#ifdef AVATAR_CLOTH
|
||||
//wind
|
||||
vec4 windEffect;
|
||||
windEffect = vec4(dot(norm, gWindDir.xyz));
|
||||
pos.x = dot(trans[2], pos_in);
|
||||
windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015)
|
||||
+ windEffect.xyz;
|
||||
windEffect.w = windEffect.w * 2.0 + 1.0; // move wind offset value to [-1, 3]
|
||||
windEffect.w = windEffect.w*gWindDir.w; // modulate wind strength
|
||||
|
||||
windEffect.xyz = windEffect.xyz*gSinWaveParams.xyz
|
||||
+vec3(gSinWaveParams.w); // use sin wave params to scale and offset input
|
||||
|
||||
//reduce to period of 2 PI
|
||||
vec4 temp1, temp0, temp2, offsetPos;
|
||||
temp1.xyz = windEffect.xyz * gPiConstants.x; // change input as multiple of [0-2PI] to [0-1]
|
||||
temp0.y = mod(temp1.x,1.0);
|
||||
windEffect.x = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
|
||||
temp1.z = temp1.z - gPiConstants.w; // shift normal oscillation by PI/2
|
||||
temp0.y = mod(temp1.z,1.0);
|
||||
|
||||
windEffect.z = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
|
||||
windEffect.xyz = windEffect.xyz + vec3(-3.141592); // offset to [-PI, PI]
|
||||
|
||||
//calculate sinusoid
|
||||
vec4 sinWave;
|
||||
temp1 = windEffect*windEffect;
|
||||
sinWave = -temp1 * gMinMaxConstants.w
|
||||
+ vec4(gMinMaxConstants.z); // y = -(x^2)/7! + 1/5!
|
||||
sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y); // y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3!
|
||||
sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x); // y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1
|
||||
sinWave = sinWave * windEffect; // y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1)
|
||||
|
||||
// sinWave.x holds sin(norm . wind_direction) with primary frequency
|
||||
// sinWave.y holds sin(norm . wind_direction) with secondary frequency
|
||||
// sinWave.z hold cos(norm . wind_direction) with primary frequency
|
||||
sinWave.xyz = sinWave.xyz * gWindDir.w
|
||||
+ vec3(windEffect.w); // multiply by wind strength in gWindDir.w [-wind, wind]
|
||||
|
||||
// add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1]
|
||||
temp1 = vec4(dot(norm, gGravity.xyz)); // how much is this normal facing in direction of gGravity?
|
||||
temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0)); // clamp [-1, 1] to [-1, 0.2]
|
||||
temp1 = temp1*vec4(1.5,0.0,0.0,0.0); // scale from [-1,0.2] to [-1.5, 0.3]
|
||||
sinWave.x = sinWave.x + temp1.x; // add gGravity effect to sinwave (only primary frequency)
|
||||
sinWave.xyz = sinWave.xyz * clothing.w; // modulate by clothing coverage
|
||||
|
||||
sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0)); // clamp to underlying body shape
|
||||
offsetPos = clothing * sinWave.x; // multiply wind effect times clothing displacement
|
||||
temp2 = gWindDir*sinWave.z + vec4(norm,0); // calculate normal offset due to wind oscillation
|
||||
offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+pos_in; // add to offset vertex position, and zero out effect from w
|
||||
norm += temp2.xyz*2.0; // add sin wave effect on normals (exaggerated)
|
||||
|
||||
//renormalize normal (again)
|
||||
norm = normalize(norm);
|
||||
|
||||
pos.x = dot(trans[0], offsetPos);
|
||||
pos.y = dot(trans[1], offsetPos);
|
||||
pos.z = dot(trans[2], offsetPos);
|
||||
pos.w = 1.0;
|
||||
#else
|
||||
pos.x = dot(trans[0], pos_in);
|
||||
pos.y = dot(trans[1], pos_in);
|
||||
pos.z = dot(trans[2], pos_in);
|
||||
pos.w = 1.0;
|
||||
#endif
|
||||
|
||||
vary_normal = norm;
|
||||
|
||||
vary_position = pos.xyz;
|
||||
|
||||
@@ -33,10 +33,11 @@
|
||||
#include "../llviewertexturelist.h"
|
||||
#include "../pipeline.h"
|
||||
#include "buffer_util.h"
|
||||
#include <boost/url.hpp>
|
||||
#include "llimagejpeg.h"
|
||||
#include "../llskinningutil.h"
|
||||
|
||||
#include <future>
|
||||
|
||||
using namespace LL::GLTF;
|
||||
using namespace boost::json;
|
||||
|
||||
@@ -960,8 +961,40 @@ LLViewerFetchedTexture* fetch_texture(const LLUUID& id);
|
||||
bool Image::prep(Asset& asset, bool loadIntoVRAM)
|
||||
{
|
||||
mLoadIntoTexturePipe = loadIntoVRAM;
|
||||
|
||||
LLUUID id;
|
||||
if (mUri.size() == UUID_STR_SIZE && LLUUID::parseUUID(mUri, &id) && id.notNull())
|
||||
{ // loaded from an asset, fetch the texture from the asset system
|
||||
LL_DEBUGS("GLTF") << "Loading image from an id" << id<< LL_ENDL;
|
||||
}
|
||||
else if (mUri.find("data:") == 0)
|
||||
{ // embedded in a data URI, load the texture from the URI
|
||||
LL_WARNS("GLTF") << "Data URIs not yet supported" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Image::prepImpl containes code that must run on the main thread
|
||||
std::promise<bool> prep_promise;
|
||||
std::future<bool> prep_future = prep_promise.get_future();
|
||||
|
||||
LLAppViewer::instance()->postToMainCoro([this, &asset, id, &prep_promise]() mutable {
|
||||
try {
|
||||
bool result = prepImpl(asset, id);
|
||||
prep_promise.set_value(result);
|
||||
}
|
||||
catch (...) {
|
||||
// Propagate exception to the waiting thread
|
||||
prep_promise.set_exception(std::current_exception());
|
||||
}
|
||||
});
|
||||
|
||||
// Block until prep is done on the main thread
|
||||
return prep_future.get();
|
||||
}
|
||||
|
||||
bool Image::prepImpl(Asset& asset, const LLUUID& id)
|
||||
{
|
||||
if (id.notNull())
|
||||
{ // loaded from an asset, fetch the texture from the asset system
|
||||
mTexture = fetch_texture(id);
|
||||
}
|
||||
|
||||
@@ -320,6 +320,8 @@ namespace LL
|
||||
void clearData(Asset& asset);
|
||||
|
||||
bool prep(Asset& asset, bool loadIntoVRAM);
|
||||
private:
|
||||
bool prepImpl(Asset& asset, const LLUUID& id);
|
||||
};
|
||||
|
||||
// Render Batch -- vertex buffer and list of primitives to render using
|
||||
|
||||
@@ -602,11 +602,12 @@ LLGLTFLoader::LLGLTFImportMaterial LLGLTFLoader::processMaterial(S32 material_in
|
||||
if (material->mPbrMetallicRoughness.mBaseColorTexture.mIndex >= 0)
|
||||
{
|
||||
S32 texIndex = material->mPbrMetallicRoughness.mBaseColorTexture.mIndex;
|
||||
std::string filename = processTexture(texIndex, "base_color", material->mName);
|
||||
std::string full_path;
|
||||
std::string filename = processTexture(full_path, texIndex, "base_color", material->mName);
|
||||
|
||||
if (!filename.empty())
|
||||
{
|
||||
impMat.mDiffuseMapFilename = filename;
|
||||
impMat.mDiffuseMapFilename = full_path;
|
||||
impMat.mDiffuseMapLabel = material->mName.empty() ? filename : material->mName;
|
||||
|
||||
// Check if the texture is already loaded
|
||||
@@ -637,7 +638,7 @@ LLGLTFLoader::LLGLTFImportMaterial LLGLTFLoader::processMaterial(S32 material_in
|
||||
return cachedMat;
|
||||
}
|
||||
|
||||
std::string LLGLTFLoader::processTexture(S32 texture_index, const std::string& texture_type, const std::string& material_name)
|
||||
std::string LLGLTFLoader::processTexture(std::string& full_path_out, S32 texture_index, const std::string& texture_type, const std::string& material_name)
|
||||
{
|
||||
S32 sourceIndex;
|
||||
if (!validateTextureIndex(texture_index, sourceIndex))
|
||||
@@ -661,6 +662,12 @@ std::string LLGLTFLoader::processTexture(S32 texture_index, const std::string& t
|
||||
{
|
||||
// Uri might be escaped
|
||||
filename = LLURI::unescape(filename);
|
||||
full_path = dir + gDirUtilp->getDirDelimiter() + filename;
|
||||
}
|
||||
|
||||
if (gDirUtilp->fileExists(full_path))
|
||||
{
|
||||
full_path_out = full_path;
|
||||
}
|
||||
|
||||
LL_INFOS("GLTF_IMPORT") << "Found texture: " << filename << " for material: " << material_name << LL_ENDL;
|
||||
|
||||
@@ -149,7 +149,7 @@ private:
|
||||
void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params);
|
||||
bool addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx);
|
||||
LLGLTFImportMaterial processMaterial(S32 material_index, S32 fallback_index);
|
||||
std::string processTexture(S32 texture_index, const std::string& texture_type, const std::string& material_name);
|
||||
std::string processTexture(std::string& full_path_out, S32 texture_index, const std::string& texture_type, const std::string& material_name);
|
||||
bool validateTextureIndex(S32 texture_index, S32& source_index);
|
||||
std::string generateMaterialName(S32 material_index, S32 fallback_index = -1);
|
||||
bool populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats);
|
||||
|
||||
@@ -28,9 +28,11 @@
|
||||
#if defined(LL_BUGSPLAT)
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <vector>
|
||||
@import BugsplatMac;
|
||||
@import CrashReporter;
|
||||
@import HockeySDK;
|
||||
@import BugSplatMac;
|
||||
// derived from BugsplatMac's BugsplatTester/AppDelegate.m
|
||||
@interface LLAppDelegate () <BugsplatStartupManagerDelegate>
|
||||
@interface LLAppDelegate () <BugSplatDelegate>
|
||||
@end
|
||||
#endif
|
||||
#include "llwindowmacosx-objc.h"
|
||||
@@ -68,13 +70,22 @@
|
||||
|
||||
#if defined(LL_BUGSPLAT)
|
||||
infos("bugsplat setup");
|
||||
// Engage BugsplatStartupManager *before* calling initViewer() to handle
|
||||
// Engage BugSplat *before* calling initViewer() to handle
|
||||
// any crashes during initialization.
|
||||
// https://www.bugsplat.com/docs/platforms/os-x#initialization
|
||||
[BugsplatStartupManager sharedManager].autoSubmitCrashReport = NO;
|
||||
[BugsplatStartupManager sharedManager].askUserDetails = YES;
|
||||
[BugsplatStartupManager sharedManager].delegate = self;
|
||||
[[BugsplatStartupManager sharedManager] start];
|
||||
|
||||
// Initialize BugSplat
|
||||
[[BugSplat shared] setDelegate:self];
|
||||
[[BugSplat shared] setAutoSubmitCrashReport:NO];
|
||||
[[BugSplat shared] setPersistUserDetails:NO];
|
||||
[[BugSplat shared] setAskUserDetails:YES];
|
||||
[BugSplat shared].expirationTimeInterval = 0;
|
||||
[[BugSplat shared] start];
|
||||
|
||||
// Optionally, add some attributes to your crash reports.
|
||||
// Attributes are artibrary key/value pairs that are searchable in the BugSplat dashboard.
|
||||
// [[BugSplat shared] setValue:@"Value of Plain Attribute" forAttribute:@"PlainAttribute"];
|
||||
|
||||
#endif
|
||||
infos("post-bugsplat setup");
|
||||
|
||||
@@ -213,9 +224,52 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
- (void) setBugsplatValue:(nullable NSString *)value forAttribute:(NSString *)attribute
|
||||
{
|
||||
//[[BugSplat shared] setValue:@"Value of not so plain <value> Attribute" forAttribute:@"NotSoPlainAttribute"];
|
||||
[[BugSplat shared] setValue:value forAttribute:attribute];
|
||||
}
|
||||
|
||||
#if defined(LL_BUGSPLAT)
|
||||
|
||||
- (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
- (void)bugSplatWillSendCrashReport:(BugSplat *)bugSplat
|
||||
{
|
||||
infos("bugSplatWillSendCrashReport");
|
||||
}
|
||||
|
||||
- (void)bugSplatWillSendCrashReportsAlways:(BugSplat *)bugSplat
|
||||
{
|
||||
infos("bugSplatWillSendCrashReportsAlways");
|
||||
}
|
||||
|
||||
- (void)bugSplatDidFinishSendingCrashReport:(BugSplat *)bugSplat
|
||||
{
|
||||
infos("bugSplatDidFinishSendingCrashReport");
|
||||
|
||||
if(!secondLogPath.empty())
|
||||
{
|
||||
boost::filesystem::remove(secondLogPath);
|
||||
}
|
||||
clearDumpLogsDir();
|
||||
}
|
||||
|
||||
- (void)bugSplatWillCancelSendingCrashReport:(BugSplat *)bugSplat
|
||||
{
|
||||
infos("bugSplatWillCancelSendingCrashReport");
|
||||
}
|
||||
|
||||
- (void)bugSplatWillShowSubmitCrashReportAlert:(BugSplat *)bugSplat
|
||||
{
|
||||
infos("bugSplatWillShowSubmitCrashReportAlert");
|
||||
}
|
||||
|
||||
- (void)bugSplat:(BugSplat *)bugSplat didFailWithError:(NSError *)error
|
||||
{
|
||||
std::string error_str([[error localizedDescription] UTF8String]);
|
||||
infos("bugSplat:didFailWithError: " + error_str);
|
||||
}
|
||||
|
||||
- (NSString *)applicationLogForBugSplat:(BugSplat *)bugSplat;
|
||||
{
|
||||
CrashMetadata& meta(CrashMetadata_instance());
|
||||
// As of BugsplatMac 1.0.6, userName and userEmail properties are now
|
||||
@@ -226,16 +280,21 @@
|
||||
// report we are about to send.
|
||||
infos("applicationLogForBugsplatStartupManager setting userName = '" +
|
||||
meta.agentFullname + '"');
|
||||
bugsplatStartupManager.userName =
|
||||
bugSplat.userName =
|
||||
[NSString stringWithCString:meta.agentFullname.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
// Use the email field for OS version, just as we do on Windows, until
|
||||
// BugSplat provides more metadata fields.
|
||||
infos("applicationLogForBugsplatStartupManager setting userEmail = '" +
|
||||
meta.OSInfo + '"');
|
||||
bugsplatStartupManager.userEmail =
|
||||
bugSplat.userEmail =
|
||||
[NSString stringWithCString:meta.OSInfo.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
//bugSplat.userID =
|
||||
// [NSString stringWithCString:meta.regionName.c_str()
|
||||
// encoding:NSUTF8StringEncoding];
|
||||
|
||||
// This strangely-named override method's return value contributes the
|
||||
// User Description metadata field.
|
||||
infos("applicationLogForBugsplatStartupManager -> '" + meta.fatalMessage + "'");
|
||||
@@ -243,7 +302,8 @@
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)applicationKeyForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager signal:(NSString *)signal exceptionName:(NSString *)exceptionName exceptionReason:(NSString *)exceptionReason {
|
||||
- (NSString *)applicationKeyForBugSplat:(BugSplat *)bugSplat signal:(NSString *)signal exceptionName:(NSString *)exceptionName exceptionReason:(NSString *)exceptionReason
|
||||
{
|
||||
// TODO: exceptionName, exceptionReason
|
||||
|
||||
// Windows sends location within region as well, but that's because
|
||||
@@ -258,27 +318,6 @@
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)defaultUserNameForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
|
||||
std::string agentFullname(CrashMetadata_instance().agentFullname);
|
||||
infos("defaultUserNameForBugsplatStartupManager -> '" + agentFullname + "'");
|
||||
return [NSString stringWithCString:agentFullname.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)defaultUserEmailForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
|
||||
// Use the email field for OS version, just as we do on Windows, until
|
||||
// BugSplat provides more metadata fields.
|
||||
std::string OSInfo(CrashMetadata_instance().OSInfo);
|
||||
infos("defaultUserEmailForBugsplatStartupManager -> '" + OSInfo + "'");
|
||||
return [NSString stringWithCString:OSInfo.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
{
|
||||
infos("bugsplatStartupManagerWillSendCrashReport");
|
||||
}
|
||||
|
||||
struct AttachmentInfo
|
||||
{
|
||||
AttachmentInfo(const std::string& path, const std::string& type):
|
||||
@@ -290,7 +329,7 @@ struct AttachmentInfo
|
||||
std::string pathname, basename, mimetype;
|
||||
};
|
||||
|
||||
- (NSArray<BugsplatAttachment *> *)attachmentsForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
- (NSArray<BugSplatAttachment *> *)attachmentsForBugSplat:(BugSplat *)bugSplat
|
||||
{
|
||||
//const CrashMetadata& metadata(CrashMetadata_instance());
|
||||
|
||||
@@ -312,12 +351,12 @@ struct AttachmentInfo
|
||||
// info.push_back(AttachmentInfo(secondLogPath, "text/xml"));
|
||||
//}
|
||||
|
||||
// We "happen to know" that info[0].basename is "SecondLife.old" -- due to
|
||||
// We "happen to know" that info[0].basename is "SecondLife.crash" -- due to
|
||||
// the fact that BugsplatMac only notices a crash during the viewer run
|
||||
// following the crash.
|
||||
// The Bugsplat service doesn't respect the MIME type above when returning
|
||||
// the log data to a browser, so take this opportunity to rename the file
|
||||
// from <base>.old to <base>_log.txt
|
||||
// from <base>.crash to <base>_log.txt
|
||||
// info[0].basename =
|
||||
// boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt";
|
||||
// infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename);
|
||||
@@ -335,8 +374,8 @@ struct AttachmentInfo
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSData *nsdata = [NSData dataWithContentsOfFile:nspathname];
|
||||
|
||||
BugsplatAttachment *attachment =
|
||||
[[BugsplatAttachment alloc] initWithFilename:nsbasename
|
||||
BugSplatAttachment *attachment =
|
||||
[[BugSplatAttachment alloc] initWithFilename:nsbasename
|
||||
attachmentData:nsdata
|
||||
contentType:nsmimetype];
|
||||
|
||||
@@ -347,26 +386,6 @@ struct AttachmentInfo
|
||||
return attachments;
|
||||
}
|
||||
|
||||
- (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
{
|
||||
infos("Sent crash report to BugSplat");
|
||||
|
||||
if(!secondLogPath.empty())
|
||||
{
|
||||
boost::filesystem::remove(secondLogPath);
|
||||
}
|
||||
clearDumpLogsDir();
|
||||
}
|
||||
|
||||
- (void)bugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager didFailWithError:(NSError *)error
|
||||
{
|
||||
// TODO: message string from NSError
|
||||
infos("Could not send crash report to BugSplat");
|
||||
NSString *pStr = [NSString stringWithFormat:@"%@", error];
|
||||
std::string bar = std::string([pStr UTF8String]);
|
||||
infos(bar);
|
||||
}
|
||||
|
||||
#endif // LL_BUGSPLAT
|
||||
|
||||
@end
|
||||
|
||||
@@ -755,14 +755,12 @@ LLAppViewer::LLAppViewer()
|
||||
// that touches files should really go through the lldir API
|
||||
|
||||
// <FS:ND> Init our custom directories, not from SecondLife
|
||||
|
||||
// gDirUtilp->initAppDirs("SecondLife");
|
||||
#if ADDRESS_SIZE == 64
|
||||
gDirUtilp->initAppDirs( APP_NAME + "_x64" );
|
||||
gDirUtilp->initAppDirs(APP_NAME + "_x64");
|
||||
#else
|
||||
gDirUtilp->initAppDirs(APP_NAME);
|
||||
#endif
|
||||
|
||||
// </FS:ND>
|
||||
|
||||
//
|
||||
@@ -4378,13 +4376,18 @@ void LLAppViewer::writeSystemInfo()
|
||||
if (! gDebugInfo.has("Dynamic") )
|
||||
gDebugInfo["Dynamic"] = LLSD::emptyMap();
|
||||
|
||||
// <FS:ND> we don't want this (otherwise set filename to Firestorm.old/log
|
||||
// #if LL_WINDOWS && !LL_BUGSPLAT
|
||||
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
|
||||
// #else
|
||||
// //Not ideal but sufficient for good reporting.
|
||||
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
|
||||
// #endif
|
||||
// <FS:ND> we don't want this (otherwise set filename to Firestorm.old/log)
|
||||
//#if LL_DARWIN
|
||||
// // crash processing in CrashMetadataSingleton reads SLLog
|
||||
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.crash");
|
||||
//#elif LL_WINDOWS && !LL_BUGSPLAT
|
||||
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
|
||||
//#else
|
||||
// // Far from ideal, especially when multiple instances get involved.
|
||||
// // Note that attachmentsForBugSplat expects .old extendion.
|
||||
// // Todo: improve.
|
||||
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
|
||||
//#endif
|
||||
// </FS:ND>
|
||||
|
||||
gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
|
||||
@@ -4817,6 +4820,24 @@ void LLAppViewer::processMarkerFiles()
|
||||
}
|
||||
LLAPRFile::remove(error_marker_file);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Looks like we are not using this at all!?
|
||||
//#if LL_DARWIN
|
||||
// if (!mSecondInstance && gLastExecEvent != LAST_EXEC_NORMAL)
|
||||
// {
|
||||
// // While windows reports crashes immediately, mac reports next run and
|
||||
// // may take a while to trigger crash report so it has a special file.
|
||||
// // Remove .crash file if exists
|
||||
// std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
|
||||
// "SecondLife.old");
|
||||
// std::string crash_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
|
||||
// "SecondLife.crash");
|
||||
// LLFile::remove(crash_log_file);
|
||||
// // Rename ".old" log file to ".crash"
|
||||
// LLFile::rename(old_log_file, crash_log_file);
|
||||
// }
|
||||
//#endif
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
void LLAppViewer::removeMarkerFiles()
|
||||
@@ -5206,6 +5227,8 @@ bool LLAppViewer::initCache()
|
||||
LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL;
|
||||
gSavedSettings.setString("CacheLocation", "");
|
||||
gSavedSettings.setString("CacheLocationTopFolder", "");
|
||||
gSavedSettings.setString("NewCacheLocation", "");
|
||||
gSavedSettings.setString("NewCacheLocationTopFolder", "");
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Sound cache
|
||||
|
||||
@@ -165,9 +165,12 @@ void LLConversation::setListenIMFloaterOpened()
|
||||
// if floater is already opened or this conversation doesn't have unread offline messages
|
||||
if (mHasOfflineIMs && !offline_ims_visible)
|
||||
{
|
||||
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
|
||||
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
|
||||
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback([this](const LLUUID& session_id)
|
||||
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback([this](const LLUUID& session_id)
|
||||
// </FS:CR>
|
||||
{
|
||||
onIMFloaterShown(session_id);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -56,9 +56,12 @@ LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conve
|
||||
|
||||
if (mConversation->hasOfflineMessages() && !ims_are_read)
|
||||
{
|
||||
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
|
||||
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
|
||||
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback([this](const LLUUID& session_id)
|
||||
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback([this](const LLUUID& session_id)
|
||||
// </FS:CR>
|
||||
{
|
||||
onIMFloaterShown(session_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -938,7 +938,10 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
|
||||
LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
|
||||
LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
|
||||
mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));
|
||||
mVObjp->updateLOD();
|
||||
if (mVObjp)
|
||||
{
|
||||
mVObjp->updateLOD();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -949,7 +952,10 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
|
||||
|
||||
pos -= camera.getOrigin();
|
||||
mDistanceWRTCamera = ll_round(pos.magVec(), 0.01f);
|
||||
mVObjp->updateLOD();
|
||||
if (mVObjp)
|
||||
{
|
||||
mVObjp->updateLOD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -961,6 +967,11 @@ void LLDrawable::updateTexture()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mVObjp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (getNumFaces() != mVObjp->getNumTEs())
|
||||
{ //drawable is transitioning its face count
|
||||
return;
|
||||
|
||||
@@ -903,7 +903,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
|
||||
if (LLPipeline::RenderAvatarCloth)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("shader level > CLOTH"); // <FS:Beq/> Tracy markup
|
||||
LLMatrix4 rot_mat;
|
||||
|
||||
@@ -45,12 +45,6 @@ extern U32 gFrameCount;
|
||||
class LLDrawPoolAvatar : public LLFacePool
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
SHADER_LEVEL_BUMP = 2,
|
||||
SHADER_LEVEL_CLOTH = 3
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
|
||||
@@ -55,8 +55,6 @@
|
||||
|
||||
// static
|
||||
LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
|
||||
LL::WorkQueue::weak_t LLBumpImageList::sMainQueue;
|
||||
LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue;
|
||||
LLRenderTarget LLBumpImageList::sRenderTarget;
|
||||
|
||||
// static
|
||||
@@ -632,8 +630,6 @@ void LLBumpImageList::init()
|
||||
llassert( mDarknessEntries.size() == 0 );
|
||||
|
||||
LLStandardBumpmap::restoreGL();
|
||||
sMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
|
||||
}
|
||||
|
||||
void LLBumpImageList::clear()
|
||||
|
||||
@@ -152,8 +152,6 @@ private:
|
||||
typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
|
||||
bump_image_map_t mBrightnessEntries;
|
||||
bump_image_map_t mDarknessEntries;
|
||||
static LL::WorkQueue::weak_t sMainQueue;
|
||||
static LL::WorkQueue::weak_t sTexUpdateQueue;
|
||||
static LLRenderTarget sRenderTarget;
|
||||
};
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index; }
|
||||
|
||||
void setWorldMatrix(const LLMatrix4& mat);
|
||||
const LLTextureEntry* getTextureEntry() const { return mVObjp->getTE(mTEOffset); }
|
||||
const LLTextureEntry* getTextureEntry() const { return mVObjp ? mVObjp->getTE(mTEOffset) : nullptr; }
|
||||
|
||||
LLFacePool* getPool() const { return mDrawPoolp; }
|
||||
U32 getPoolType() const { return mPoolType; }
|
||||
|
||||
@@ -41,6 +41,7 @@ LLFloaterBulkUpload::LLFloaterBulkUpload(const LLSD& key)
|
||||
mUploadCost = key["upload_cost"].asInteger();
|
||||
mUploadCount = key["upload_count"].asInteger();
|
||||
mHas2kTextures = key["has_2k_textures"].asBoolean();
|
||||
mDestinationFolderId = key["dest"];
|
||||
if (key["files"].isArray())
|
||||
{
|
||||
const LLSD& files = key["files"];
|
||||
@@ -125,7 +126,7 @@ void LLFloaterBulkUpload::onUpload2KCheckBox()
|
||||
|
||||
void LLFloaterBulkUpload::onClickUpload()
|
||||
{
|
||||
do_bulk_upload(mFiles, mAllow2kTextures);
|
||||
do_bulk_upload(mFiles, mAllow2kTextures, mDestinationFolderId);
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ private:
|
||||
std::vector<std::string> mFiles;
|
||||
bool mAllow2kTextures = true;
|
||||
bool mHas2kTextures = false;
|
||||
LLUUID mDestinationFolderId;
|
||||
S32 mUploadCost = 0;
|
||||
S32 mUploadCount = 0;
|
||||
};
|
||||
|
||||
@@ -171,7 +171,7 @@ void LLFloaterExperiences::onOpen( const LLSD& key )
|
||||
refreshContents();
|
||||
return;
|
||||
}
|
||||
region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterExperiences::refreshContents, this));
|
||||
mCapsReceivedConnection = region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterExperiences::refreshContents, this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -231,6 +231,7 @@ bool LLFloaterExperiences::updatePermissions( const LLSD& permission )
|
||||
|
||||
void LLFloaterExperiences::onClose( bool app_quitting )
|
||||
{
|
||||
mCapsReceivedConnection.disconnect();
|
||||
LLEventPumps::instance().obtain("experience_permission").stopListening("LLFloaterExperiences");
|
||||
LLFloater::onClose(app_quitting);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ private:
|
||||
static void retrieveExperienceListCoro(std::string url, LLHandle<LLFloaterExperiences> hparent,
|
||||
NameMap_t tabMapping, std::string errorNotify, Callback_t cback, invokationFn_t invoker);
|
||||
std::vector<LLUUID> mPrepurchaseIds;
|
||||
boost::signals2::scoped_connection mCapsReceivedConnection;
|
||||
};
|
||||
|
||||
#endif //LL_LLFLOATEREXPERIENCES_H
|
||||
|
||||
@@ -438,7 +438,8 @@ void LLFloaterImagePreview::onBtnOK()
|
||||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
expected_upload_cost
|
||||
expected_upload_cost,
|
||||
mDestinationFolderId
|
||||
));
|
||||
|
||||
upload_new_resource(assetUploadInfo);
|
||||
|
||||
@@ -487,13 +487,13 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
|
||||
names_requested.push_back(owner_id);
|
||||
if (is_group_owned)
|
||||
{
|
||||
gCacheName->getGroup(owner_id,
|
||||
mGroupNameCacheConnection = gCacheName->getGroup(owner_id,
|
||||
boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
|
||||
this, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAvatarNameCache::get(owner_id,
|
||||
mAvatarNameCacheConnection = LLAvatarNameCache::get(owner_id,
|
||||
boost::bind(&LLPanelScriptLimitsRegionMemory::onAvatarNameCache,
|
||||
this, _1, _2));
|
||||
}
|
||||
|
||||
@@ -136,6 +136,9 @@ private:
|
||||
|
||||
std::vector<LLSD> mObjectListItems;
|
||||
|
||||
boost::signals2::scoped_connection mAvatarNameCacheConnection;
|
||||
boost::signals2::scoped_connection mGroupNameCacheConnection;
|
||||
|
||||
void getLandScriptResourcesCoro(std::string url);
|
||||
void getLandScriptSummaryCoro(std::string url);
|
||||
void getLandScriptDetailsCoro(std::string url);
|
||||
|
||||
@@ -695,7 +695,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
|
||||
// This could be anything. For now, just refresh the item.
|
||||
if (mask & LLInventoryObserver::INTERNAL)
|
||||
{
|
||||
if (view_item)
|
||||
if (view_item && view_item->getViewModelItem())
|
||||
{
|
||||
view_item->refresh();
|
||||
}
|
||||
@@ -714,7 +714,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
|
||||
|
||||
if (mask & LLInventoryObserver::UPDATE_FAVORITE)
|
||||
{
|
||||
if (view_item)
|
||||
if (view_item && view_item->getViewModelItem())
|
||||
{
|
||||
view_item->refresh();
|
||||
LLFolderViewFolder* parent = view_item->getParentFolder();
|
||||
|
||||
@@ -716,24 +716,28 @@ bool LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
|
||||
// handle attachments in local space
|
||||
if (object->isAttachment() && object->mDrawable.notNull())
|
||||
{
|
||||
// calculate local version of relative move
|
||||
LLQuaternion objWorldRotation = object->mDrawable->mXform.getParent()->getWorldRotation();
|
||||
objWorldRotation.transQuat();
|
||||
|
||||
LLVector3 old_position_local = object->getPosition();
|
||||
LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
|
||||
|
||||
//RN: I forget, but we need to do this because of snapping which doesn't often result
|
||||
// in position changes even when the mouse moves
|
||||
object->setPosition(new_position_local);
|
||||
rebuild(object);
|
||||
gAgentAvatarp->clampAttachmentPositions();
|
||||
new_position_local = object->getPosition();
|
||||
|
||||
if (selectNode->mIndividualSelection)
|
||||
LLXform* object_xform_parent = object->mDrawable->mXform.getParent();
|
||||
if (object_xform_parent)
|
||||
{
|
||||
// counter-translate child objects if we are moving the root as an individual
|
||||
object->resetChildrenPosition(old_position_local - new_position_local, true);
|
||||
// calculate local version of relative move
|
||||
LLQuaternion objWorldRotation = object_xform_parent->getWorldRotation();
|
||||
objWorldRotation.transQuat();
|
||||
|
||||
LLVector3 old_position_local = object->getPosition();
|
||||
LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
|
||||
|
||||
//RN: I forget, but we need to do this because of snapping which doesn't often result
|
||||
// in position changes even when the mouse moves
|
||||
object->setPosition(new_position_local);
|
||||
rebuild(object);
|
||||
gAgentAvatarp->clampAttachmentPositions();
|
||||
new_position_local = object->getPosition();
|
||||
|
||||
if (selectNode->mIndividualSelection)
|
||||
{
|
||||
// counter-translate child objects if we are moving the root as an individual
|
||||
object->resetChildrenPosition(old_position_local - new_position_local, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1997,12 +1997,14 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind
|
||||
{
|
||||
// Prespecified material
|
||||
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
|
||||
me->mUploadFolder = dest_folder;
|
||||
me->loadMaterial(model_in, filename, index);
|
||||
}
|
||||
else if (model_in.materials.size() == 1)
|
||||
{
|
||||
// Only one material, just load it
|
||||
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
|
||||
me->mUploadFolder = dest_folder;
|
||||
me->loadMaterial(model_in, filename, 0);
|
||||
}
|
||||
else
|
||||
@@ -2028,11 +2030,12 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind
|
||||
material_list.push_back(LLTrans::getString("material_batch_import_text"));
|
||||
|
||||
LLFloaterComboOptions::showUI(
|
||||
[model_in, filename](const std::string& option, S32 index)
|
||||
[model_in, filename, dest_folder](const std::string& option, S32 index)
|
||||
{
|
||||
if (index >= 0) // -1 on cancel
|
||||
{
|
||||
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
|
||||
me->mUploadFolder = dest_folder;
|
||||
me->loadMaterial(model_in, filename, index);
|
||||
}
|
||||
},
|
||||
@@ -2458,7 +2461,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::
|
||||
if (index == model_in.materials.size())
|
||||
{
|
||||
// bulk upload all the things
|
||||
upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true, LLUUID::null);
|
||||
upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true, mUploadFolder);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1214,26 +1214,22 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
|
||||
bool missing_asset = false;
|
||||
{
|
||||
LLGLenum image_format = GL_RGB;
|
||||
bool has_alpha = false;
|
||||
bool identical_image_format = false;
|
||||
LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset);
|
||||
LLSelectedTE::getImageFormat(image_format, has_alpha, identical_image_format, missing_asset);
|
||||
|
||||
if (!missing_asset)
|
||||
{
|
||||
mIsAlpha = false;
|
||||
mIsAlpha = has_alpha;
|
||||
switch (image_format)
|
||||
{
|
||||
case GL_RGBA:
|
||||
case GL_ALPHA:
|
||||
{
|
||||
mIsAlpha = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_RGB:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
|
||||
LL_WARNS() << "Unexpected tex format in LLPanelFace..." << LL_ENDL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3400,23 +3396,22 @@ void LLPanelFace::onSelectTexture()
|
||||
sendTexture();
|
||||
|
||||
LLGLenum image_format;
|
||||
bool has_alpha;
|
||||
bool identical_image_format = false;
|
||||
bool missing_asset = false;
|
||||
LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset);
|
||||
LLSelectedTE::getImageFormat(image_format, has_alpha, identical_image_format, missing_asset);
|
||||
|
||||
U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
|
||||
if (!missing_asset)
|
||||
{
|
||||
U32 alpha_mode = has_alpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
|
||||
switch (image_format)
|
||||
{
|
||||
case GL_RGBA:
|
||||
case GL_ALPHA:
|
||||
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
|
||||
break;
|
||||
case GL_RGB:
|
||||
break;
|
||||
default:
|
||||
LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
|
||||
LL_WARNS() << "Unexpected tex format in LLPanelFace..." << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5391,12 +5386,13 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical
|
||||
identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr);
|
||||
}
|
||||
|
||||
void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face, bool& missing_asset)
|
||||
void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& has_alpha, bool& identical_face, bool& missing_asset)
|
||||
{
|
||||
struct LLSelectedTEGetmatId : public LLSelectedTEFunctor
|
||||
{
|
||||
LLSelectedTEGetmatId()
|
||||
: mImageFormat(GL_RGB)
|
||||
, mHasAlpha(false)
|
||||
, mIdentical(true)
|
||||
, mMissingAsset(false)
|
||||
, mFirstRun(true)
|
||||
@@ -5411,6 +5407,10 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return,
|
||||
{
|
||||
format = image->getPrimaryFormat();
|
||||
missing = image->isMissingAsset();
|
||||
if (format == GL_RGBA || format == GL_ALPHA)
|
||||
{
|
||||
mHasAlpha = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mFirstRun)
|
||||
@@ -5427,6 +5427,7 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return,
|
||||
return true;
|
||||
}
|
||||
LLGLenum mImageFormat;
|
||||
bool mHasAlpha;
|
||||
bool mIdentical;
|
||||
bool mMissingAsset;
|
||||
bool mFirstRun;
|
||||
@@ -5434,6 +5435,7 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return,
|
||||
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
|
||||
|
||||
image_format_to_return = func.mImageFormat;
|
||||
has_alpha = func.mHasAlpha;
|
||||
identical_face = func.mIdentical;
|
||||
missing_asset = func.mMissingAsset;
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ public:
|
||||
{
|
||||
public:
|
||||
static void getFace(class LLFace*& face_to_return, bool& identical_face);
|
||||
static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face, bool& missing_asset);
|
||||
static void getImageFormat(LLGLenum& image_format_to_return, bool& has_alpha, bool& identical_face, bool& missing_asset);
|
||||
static void getTexId(LLUUID& id, bool& identical);
|
||||
static void getPbrMaterialId(LLUUID& id, bool& identical, bool& has_pbr, bool& has_faces_without_pbr);
|
||||
static void getObjectScaleS(F32& scale_s, bool& identical);
|
||||
|
||||
@@ -737,6 +737,10 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife()
|
||||
{
|
||||
mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
if (mMenuNameCacheConnection.connected())
|
||||
{
|
||||
mMenuNameCacheConnection.disconnect();
|
||||
}
|
||||
|
||||
// <FS:Ansariel> RLVa support
|
||||
if (mRlvBehaviorCallbackConnection.connected())
|
||||
@@ -2045,7 +2049,7 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
|
||||
}
|
||||
else if (item_name == "edit_display_name")
|
||||
{
|
||||
LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
|
||||
mMenuNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
|
||||
LLFirstUse::setDisplayName(false);
|
||||
}
|
||||
else if (item_name == "edit_partner")
|
||||
|
||||
@@ -289,6 +289,7 @@ private:
|
||||
LLUUID mImageId;
|
||||
|
||||
boost::signals2::connection mAvatarNameCacheConnection;
|
||||
boost::signals2::connection mMenuNameCacheConnection;
|
||||
|
||||
// <FS:Ansariel> RLVa support
|
||||
boost::signals2::connection mRlvBehaviorCallbackConnection;
|
||||
|
||||
@@ -82,7 +82,7 @@ void LLSpeaker::lookupName()
|
||||
if(!gCacheName)
|
||||
return;
|
||||
// </FS:Zi>
|
||||
LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _1, _2)); // todo: can be group???
|
||||
mAvatarNameCacheConnection = LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _1, _2)); // todo: can be group???
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,9 @@ public:
|
||||
bool mIsModerator;
|
||||
bool mModeratorMutedVoice;
|
||||
bool mModeratorMutedText;
|
||||
|
||||
private:
|
||||
boost::signals2::scoped_connection mAvatarNameCacheConnection;
|
||||
};
|
||||
|
||||
class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent
|
||||
|
||||
@@ -713,6 +713,32 @@ bool idle_startup()
|
||||
LLStringOps::sAM = LLTrans::getString("dateTimeAM");
|
||||
LLStringOps::sPM = LLTrans::getString("dateTimePM");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring utf16str = ll_convert<std::wstring>(val);
|
||||
if (utf16str.size() > 4)
|
||||
{
|
||||
LL_DEBUGS("InitInfo") << "Current locale \"" << locale << "\" "
|
||||
<< "has impracitcally long AM/PM time format" << LL_ENDL;
|
||||
// fallback to declarations in strings.xml
|
||||
LLStringOps::sAM = LLTrans::getString("dateTimeAM");
|
||||
LLStringOps::sPM = LLTrans::getString("dateTimePM");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Some locales (as well some of our own dateTimeAM/PM) return long
|
||||
// strings for AM/PM which aren't practical to display in the UI.
|
||||
// Hardcode to "AM"/"PM" in those cases.
|
||||
std::wstring utf16str = ll_convert<std::wstring>(LLStringOps::sAM);
|
||||
if (utf16str.size() > 4)
|
||||
{
|
||||
LLStringOps::sAM = "AM";
|
||||
}
|
||||
utf16str = ll_convert<std::wstring>(LLStringOps::sPM);
|
||||
if (utf16str.size() > 4)
|
||||
{
|
||||
LLStringOps::sPM = "PM";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -306,17 +306,19 @@ void LLResourceUploadInfo::assignDefaults()
|
||||
{
|
||||
mDescription = "(No Description)";
|
||||
}
|
||||
|
||||
if (mAssetType == LLAssetType::AT_GLTF ||
|
||||
mAssetType == LLAssetType::AT_GLTF_BIN)
|
||||
if (mFolderId.isNull()) // don't overwrite if destination is already specified
|
||||
{
|
||||
mFolderId = LLUUID::null;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFolderId = gInventory.findUserDefinedCategoryUUIDForType(
|
||||
(mDestinationFolderType == LLFolderType::FT_NONE) ?
|
||||
(LLFolderType::EType)mAssetType : mDestinationFolderType);
|
||||
if (mAssetType == LLAssetType::AT_GLTF ||
|
||||
mAssetType == LLAssetType::AT_GLTF_BIN)
|
||||
{
|
||||
mFolderId = LLUUID::null;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFolderId = gInventory.findUserDefinedCategoryUUIDForType(
|
||||
(mDestinationFolderType == LLFolderType::FT_NONE) ?
|
||||
(LLFolderType::EType)mAssetType : mDestinationFolderType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1337,6 +1337,7 @@ void settings_setup_listeners()
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "ChatConsoleFontSize", handleChatFontSizeChanged);
|
||||
setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); // <FS:Ansariel> Keep custom chat persist time
|
||||
setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
|
||||
|
||||
@@ -545,7 +545,7 @@ void upload_single_file(
|
||||
return;
|
||||
}
|
||||
|
||||
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
|
||||
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLUUID& dest)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
|
||||
{
|
||||
@@ -665,7 +665,8 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
|
||||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight())
|
||||
LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight()),
|
||||
dest
|
||||
));
|
||||
|
||||
upload_new_resource(assetUploadInfo);
|
||||
@@ -681,7 +682,8 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
|
||||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
expected_upload_cost);
|
||||
expected_upload_cost,
|
||||
dest);
|
||||
LLResourceUploadInfo::ptr_t uploadInfo(info_p);
|
||||
|
||||
upload_new_resource(uploadInfo);
|
||||
@@ -702,14 +704,14 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
|
||||
// Todo:
|
||||
// 1. Decouple bulk upload from material editor
|
||||
// 2. Take into account possiblity of identical textures
|
||||
LLMaterialEditor::uploadMaterialFromModel(filename, model, i);
|
||||
LLMaterialEditor::uploadMaterialFromModel(filename, model, i, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLSD& notification, const LLSD& response)
|
||||
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLSD& notification, const LLSD& response, const LLUUID& dest)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option != 0)
|
||||
@@ -718,7 +720,7 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLS
|
||||
return;
|
||||
}
|
||||
|
||||
do_bulk_upload(filenames, allow_2k);
|
||||
do_bulk_upload(filenames, allow_2k, dest);
|
||||
}
|
||||
|
||||
bool get_bulk_upload_expected_cost(
|
||||
|
||||
@@ -73,7 +73,7 @@ bool get_bulk_upload_expected_cost(
|
||||
S32& bvh_count,
|
||||
S32& textures_2k_count);
|
||||
|
||||
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k);
|
||||
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLUUID &dest_folder);
|
||||
|
||||
void upload_single_file(
|
||||
const std::vector<std::string>& filenames,
|
||||
|
||||
@@ -7488,7 +7488,7 @@ void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender
|
||||
void LLStaticViewerObject::updateDrawable(bool force_damped)
|
||||
{
|
||||
// Force an immediate rebuild on any update
|
||||
if (mDrawable.notNull())
|
||||
if (mDrawable.notNull() && mDrawable->getVObj())
|
||||
{
|
||||
mDrawable->updateXform(true);
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
|
||||
|
||||
@@ -587,6 +587,7 @@ void LLViewerShaderMgr::setShaders()
|
||||
unloadShaders();
|
||||
|
||||
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
|
||||
LLPipeline::RenderAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth");
|
||||
|
||||
if (gViewerWindow)
|
||||
{
|
||||
@@ -2390,7 +2391,9 @@ bool LLViewerShaderMgr::loadShadersDeferred()
|
||||
gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
|
||||
gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
|
||||
|
||||
gDeferredAvatarProgram.clearPermutations();
|
||||
add_common_permutations(&gDeferredAvatarProgram);
|
||||
gDeferredAvatarProgram.addPermutation("AVATAR_CLOTH", LLPipeline::RenderAvatarCloth ? "1" : "0");
|
||||
|
||||
success = gDeferredAvatarProgram.createShader();
|
||||
llassert(success);
|
||||
@@ -3606,7 +3609,7 @@ bool LLViewerShaderMgr::loadShadersInterface()
|
||||
|
||||
std::string LLViewerShaderMgr::getShaderDirPrefix(void)
|
||||
{
|
||||
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
|
||||
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders", "class");
|
||||
}
|
||||
|
||||
void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
|
||||
|
||||
@@ -1124,7 +1124,6 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
|
||||
|
||||
imagep->postCreateTexture();
|
||||
imagep->mCreatePending = false;
|
||||
mCreateTextureList.pop();
|
||||
|
||||
if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel() &&
|
||||
(imagep->getDesiredDiscardLevel() <= MAX_DISCARD_LEVEL))
|
||||
@@ -1136,6 +1135,8 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
|
||||
imagep->scaleDown();
|
||||
}
|
||||
|
||||
mCreateTextureList.pop();
|
||||
|
||||
if (create_timer.getElapsedTimeF32() > max_time)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -3739,7 +3739,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
|
||||
void LLVOAvatar::idleUpdateWindEffect()
|
||||
{
|
||||
// update wind effect
|
||||
if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
|
||||
if (LLPipeline::RenderAvatarCloth)
|
||||
{
|
||||
F32 hover_strength = 0.f;
|
||||
F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast;
|
||||
|
||||
@@ -781,7 +781,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
|
||||
void LLVOGrass::updateDrawable(bool force_damped)
|
||||
{
|
||||
// Force an immediate rebuild on any update
|
||||
if (mDrawable.notNull())
|
||||
if (mDrawable.notNull() && mDrawable->getVObj())
|
||||
{
|
||||
mDrawable->updateXform(true);
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
|
||||
|
||||
@@ -237,6 +237,7 @@ S32 LLPipeline::RenderBufferVisualization;
|
||||
bool LLPipeline::RenderMirrors;
|
||||
S32 LLPipeline::RenderHeroProbeUpdateRate;
|
||||
S32 LLPipeline::RenderHeroProbeConservativeUpdateMultiplier;
|
||||
bool LLPipeline::RenderAvatarCloth;
|
||||
LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
|
||||
|
||||
// const U32 LLPipeline::MAX_PREVIEW_WIDTH = 512;
|
||||
@@ -658,6 +659,7 @@ void LLPipeline::init()
|
||||
connectRefreshCachedSettingsSafe("RenderMirrors");
|
||||
connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate");
|
||||
connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier");
|
||||
connectRefreshCachedSettingsSafe("RenderAvatarCloth");
|
||||
connectRefreshCachedSettingsSafe("FSRenderVignette"); // <FS:CR> Import Vignette from Exodus
|
||||
// <FS:Ansariel> Make change to RenderAttachedLights & RenderAttachedParticles instant
|
||||
connectRefreshCachedSettingsSafe("RenderAttachedLights");
|
||||
@@ -1274,6 +1276,8 @@ void LLPipeline::refreshCachedSettings()
|
||||
RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
|
||||
RenderHeroProbeUpdateRate = gSavedSettings.getS32("RenderHeroProbeUpdateRate");
|
||||
RenderHeroProbeConservativeUpdateMultiplier = gSavedSettings.getS32("RenderHeroProbeConservativeUpdateMultiplier");
|
||||
RenderAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth");
|
||||
|
||||
sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
|
||||
// <FS:Beq> [FIRE-35070] Instead of using the above we'll add a new static level variable to save some lookups. Making the above "work" with ProbeLevel will break everything.
|
||||
sReflectionProbeLevel = gSavedSettings.getS32("RenderReflectionProbeLevel");
|
||||
@@ -3100,7 +3104,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, bool damped_motion)
|
||||
|
||||
void LLPipeline::markShift(LLDrawable *drawablep)
|
||||
{
|
||||
if (!drawablep || drawablep->isDead())
|
||||
if (!drawablep || drawablep->isDead() || !drawablep->getVObj())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -3134,7 +3138,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
|
||||
iter != mShiftList.end(); iter++)
|
||||
{
|
||||
LLDrawable *drawablep = *iter;
|
||||
if (drawablep->isDead())
|
||||
if (drawablep->isDead() || !drawablep->getVObj())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1167,6 +1167,7 @@ public:
|
||||
static bool RenderMirrors;
|
||||
static S32 RenderHeroProbeUpdateRate;
|
||||
static S32 RenderHeroProbeConservativeUpdateMultiplier;
|
||||
static bool RenderAvatarCloth;
|
||||
};
|
||||
|
||||
void render_bbox(const LLVector3 &min, const LLVector3 &max);
|
||||
|
||||
@@ -560,6 +560,7 @@
|
||||
<menu_item_check label="Texturen in Vollauflösung (gefährlich)" name="Full Res Textures"/>
|
||||
<menu_item_check label="Angehängte Lichter rendern" name="Render Attached Lights"/>
|
||||
<menu_item_check label="Angehängte Partikel rendern" name="Render Attached Particles"/>
|
||||
<menu_item_check label="Animierte Avatar-System-Kleidung rendern" name="Render Avatar Cloth"/>
|
||||
<menu_item_check label="Sammeln von Vertex Buffern für Schrift aktivieren" name="Collect Font Vertex Buffers"/>
|
||||
<menu_item_check label="Shader-Cache aktivieren" name="Enable Shader Cache"/>
|
||||
<menu_item_call label="Shader-Cache bereinigen" name="Shader Cache Clear"/>
|
||||
|
||||
@@ -4733,8 +4733,7 @@
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Object-Object Occlusion"
|
||||
name="Object-Object Occlusion"
|
||||
shortcut="control|shift|O">
|
||||
name="Object-Object Occlusion">
|
||||
<menu_item_check.on_check
|
||||
function="CheckControl"
|
||||
parameter="UseOcclusion" />
|
||||
@@ -4856,6 +4855,16 @@
|
||||
function="Advanced.HandleAttachedLightParticles"
|
||||
parameter="RenderAttachedParticles" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Render Animated Avatar System Cloth"
|
||||
name="Render Avatar Cloth">
|
||||
<menu_item_check.on_check
|
||||
function="CheckControl"
|
||||
parameter="RenderAvatarCloth" />
|
||||
<menu_item_check.on_click
|
||||
function="ToggleControl"
|
||||
parameter="RenderAvatarCloth" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Reduce Draw Distance when VRAM is full"
|
||||
name="Reduce Draw Distance when VRAM is full">
|
||||
|
||||
@@ -60,23 +60,23 @@
|
||||
<scroll_list.columns
|
||||
label="Parcel"
|
||||
name="name"
|
||||
relative_width="0.2" />
|
||||
relative_width="0.25" />
|
||||
<scroll_list.columns
|
||||
label="Region"
|
||||
name="location"
|
||||
relative_width="0.2" />
|
||||
relative_width="0.25" />
|
||||
<scroll_list.columns
|
||||
label="Type"
|
||||
name="type"
|
||||
relative_width="0.2" />
|
||||
relative_width="0.25" />
|
||||
<scroll_list.columns
|
||||
label="Area"
|
||||
name="area"
|
||||
relative_width="0.2" />
|
||||
relative_width="0.25" />
|
||||
<scroll_list.columns
|
||||
label="Hidden"
|
||||
name="hidden"
|
||||
relative_width="0.2" />
|
||||
width="-1" />
|
||||
</scroll_list>
|
||||
<button
|
||||
right="-4"
|
||||
|
||||
@@ -348,9 +348,9 @@ class ViewerManifest(LLManifest,FSViewerManifest):
|
||||
channel_type=self.channel_type()
|
||||
#<FS:TS> LL uses "Viewer" in the name of their release package. We use "Release".
|
||||
#if channel_type == 'release':
|
||||
# app_suffix='Viewer'
|
||||
# return CHANNEL_VENDOR_BASE
|
||||
#else:
|
||||
# app_suffix=self.channel_variant()
|
||||
# return CHANNEL_VENDOR_BASE + ' ' + self.channel_variant()
|
||||
app_suffix=self.channel_variant()
|
||||
|
||||
#<FS:ND> tag "OS" after CHANNEL_VENDOR_BASE and before any suffix
|
||||
@@ -1357,13 +1357,12 @@ class Darwin_x86_64_Manifest(ViewerManifest):
|
||||
bugsplat_db = self.args.get('bugsplat')
|
||||
print(f"debug: bugsplat_db={bugsplat_db}")
|
||||
if bugsplat_db:
|
||||
# Inject BugsplatServerURL into Info.plist if provided.
|
||||
# Inject Bugsplat's db into Info.plist if provided.
|
||||
Info_plist = self.dst_path_of("Info.plist")
|
||||
with open(Info_plist, 'rb') as f:
|
||||
Info = plistlib.load(f)
|
||||
# https://www.bugsplat.com/docs/platforms/os-x#configuration
|
||||
Info["BugsplatServerURL"] = \
|
||||
"https://{}.bugsplat.com/".format(bugsplat_db)
|
||||
Info["BugSplatDatabase"] = bugsplat_db
|
||||
self.put_in_file(
|
||||
plistlib.dumps(Info),
|
||||
os.path.basename(Info_plist),
|
||||
@@ -1382,6 +1381,8 @@ class Darwin_x86_64_Manifest(ViewerManifest):
|
||||
|
||||
if self.args.get('bugsplat'):
|
||||
self.path2basename(relpkgdir, "BugsplatMac.framework")
|
||||
self.path2basename(relpkgdir, "CrashReporter.framework")
|
||||
self.path2basename(relpkgdir, "HockeySDK.framework")
|
||||
|
||||
# OpenAL dylibs
|
||||
if self.args['openal'] == 'ON':
|
||||
@@ -1419,6 +1420,24 @@ class Darwin_x86_64_Manifest(ViewerManifest):
|
||||
# stamped into the framework.
|
||||
# Let exception, if any, propagate -- if this doesn't
|
||||
# work, we need the build to noisily fail!
|
||||
oldpath = subprocess.check_output(
|
||||
['objdump', '--macho', '--dylib-id', '--non-verbose',
|
||||
os.path.join(relpkgdir, "HockeySDK.framework", "HockeySDK")],
|
||||
text=True
|
||||
).splitlines()[-1] # take the last line of output
|
||||
self.run_command(
|
||||
['install_name_tool', '-change', oldpath,
|
||||
'@executable_path/../Frameworks/HockeySDK.framework/HockeySDK',
|
||||
executable])
|
||||
oldpath = subprocess.check_output(
|
||||
['objdump', '--macho', '--dylib-id', '--non-verbose',
|
||||
os.path.join(relpkgdir, "CrashReporter.framework", "CrashReporter")],
|
||||
text=True
|
||||
).splitlines()[-1] # take the last line of output
|
||||
self.run_command(
|
||||
['install_name_tool', '-change', oldpath,
|
||||
'@executable_path/../Frameworks/CrashReporter.framework/CrashReporter',
|
||||
executable])
|
||||
oldpath = subprocess.check_output(
|
||||
['objdump', '--macho', '--dylib-id', '--non-verbose',
|
||||
os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")],
|
||||
|
||||
Reference in New Issue
Block a user