diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index f814458cdb6fb895ccfc58287f53dc58789848cb..7947587800197971df4d71a06fb26899ab1409f1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -313,6 +313,11 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool void run() override; + void glReady() + { + mGLReady = true; + } + // initialzie DXGI adapter (for querying available VRAM) void initDX(); @@ -371,6 +376,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool HWND mWindowHandle = NULL; HDC mhDC = 0; + // *HACK: Attempt to prevent startup crashes by deferring memory accounting + // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18 + bool mGLReady = false; // best guess at available video memory in MB std::atomic<U32> mAvailableVRAM; @@ -1829,6 +1837,13 @@ const S32 max_format = (S32)num_formats - 1; // ok to post quit messages now mPostQuit = TRUE; + // *HACK: Attempt to prevent startup crashes by deferring memory accounting + // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18 + mWindowThread->post([=]() + { + mWindowThread->glReady(); + }); + if (auto_show) { show(); @@ -4749,6 +4764,8 @@ void debugEnumerateGraphicsAdapters() void LLWindowWin32::LLWindowWin32Thread::initDX() { + if (!mGLReady) { return; } + if (mDXGIAdapter == NULL) { debugEnumerateGraphicsAdapters(); @@ -4783,6 +4800,8 @@ void LLWindowWin32::LLWindowWin32Thread::initDX() void LLWindowWin32::LLWindowWin32Thread::initD3D() { + if (!mGLReady) { return; } + if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0) { mD3D = Direct3DCreate9(D3D_SDK_VERSION); @@ -4809,6 +4828,8 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D() void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() { LL_PROFILE_ZONE_SCOPED; + if (!mGLReady) { return; } + if (mDXGIAdapter != nullptr) { // NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware @@ -4882,8 +4903,6 @@ void LLWindowWin32::LLWindowWin32Thread::run() sWindowThreadId = std::this_thread::get_id(); LogChange logger("Window"); - initDX(); - //as good a place as any to up the MM timer resolution (see ms_sleep) //attempt to set timer resolution to 1ms TIMECAPS tc; @@ -4896,9 +4915,12 @@ void LLWindowWin32::LLWindowWin32Thread::run() { LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32; + // lazily call initD3D inside this loop to catch when mGLReady has been set to true + initDX(); + if (mWindowHandle != 0) { - // lazily call initD3D inside this loop to catch when mWindowHandle has been set + // lazily call initD3D inside this loop to catch when mWindowHandle has been set, and mGLReady has been set to true // *TODO: Shutdown if this fails when mWindowHandle exists initD3D(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 5a086e588dce320194eeb2bdb8d4cd5f407983c7..a6341d9c9a5895ae8b5a1209f889e816ceadc343 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5127,7 +5127,7 @@ void LLControlAVBridge::updateSpatialExtents() // disappear when root goes off-screen" // // Expand extents to include Control Avatar placed outside of the bounds - if (controlAvatar && (rootWasDirty || controlAvatar->mPlaying)) + if (controlAvatar && controlAvatar->mDrawable && (rootWasDirty || controlAvatar->mPlaying)) { root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform()); }