summaryrefslogtreecommitdiff
path: root/indra/llwindow
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2020-06-15 15:29:04 -0400
committerOz Linden <oz@lindenlab.com>2020-06-15 15:29:04 -0400
commit86009f885efc796850d3e5b612c896a9d737fb86 (patch)
tree404923800dbc6d09ea72b10de0c7f4bb103d1e62 /indra/llwindow
parent17598f936bb6b099f21fc32aa80b68258cdfd0b9 (diff)
parent1702a65665879d0c68df4c6b4fdb60f815ab7abb (diff)
SL-10297: merge up to master at 6.4.3
Diffstat (limited to 'indra/llwindow')
-rw-r--r--indra/llwindow/lldxhardware.cpp94
-rw-r--r--indra/llwindow/lldxhardware.h4
-rw-r--r--indra/llwindow/llmousehandler.h1
-rw-r--r--indra/llwindow/llopenglview-objc.mm2
-rw-r--r--indra/llwindow/llwindowcallbacks.cpp4
-rw-r--r--indra/llwindow/llwindowcallbacks.h1
-rw-r--r--indra/llwindow/llwindowmacosx-objc.h2
-rw-r--r--indra/llwindow/llwindowmacosx.cpp8
-rw-r--r--indra/llwindow/llwindowwin32.cpp50
9 files changed, 145 insertions, 21 deletions
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index d4790f9f29..12a6baa3e6 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -61,7 +61,7 @@ typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSv
OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
-HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
+HRESULT GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam)
{
HRESULT hr;
bool bGotMemory = false;
@@ -149,21 +149,26 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
if ( !pVideoControllers[iController] )
continue;
- pPropName = SysAllocString( L"PNPDeviceID" );
- hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
+ // if strInputDeviceID is set find this specific device and return memory or specific device
+ // if strInputDeviceID is not set return the best device
+ if (strInputDeviceID)
+ {
+ pPropName = SysAllocString( L"PNPDeviceID" );
+ hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
#ifdef PRINTF_DEBUGGING
- if( FAILED( hr ) )
- wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );
+ if( FAILED( hr ) )
+ wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );
#endif
- if( SUCCEEDED( hr ) )
- {
- if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
- bFound = true;
+ if( SUCCEEDED( hr ) && strInputDeviceID)
+ {
+ if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
+ bFound = true;
+ }
+ VariantClear( &var );
+ if( pPropName ) SysFreeString( pPropName );
}
- VariantClear( &var );
- if( pPropName ) SysFreeString( pPropName );
- if( bFound )
+ if( bFound || !strInputDeviceID )
{
pPropName = SysAllocString( L"AdapterRAM" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
@@ -175,13 +180,18 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
if( SUCCEEDED( hr ) )
{
bGotMemory = true;
- *pdwAdapterRam = var.ulVal;
+ *pdwAdapterRam = llmax(var.ulVal, *pdwAdapterRam);
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
- break;
}
+
SAFE_RELEASE( pVideoControllers[iController] );
+
+ if (bFound)
+ {
+ break;
+ }
}
}
}
@@ -207,6 +217,17 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
return E_FAIL;
}
+//static
+S32 LLDXHardware::getMBVideoMemoryViaWMI()
+{
+ DWORD vram = 0;
+ if (SUCCEEDED(GetVideoMemoryViaWMI(NULL, &vram)))
+ {
+ return vram / (1024 * 1024);;
+ }
+ return 0;
+}
+
//Getting the version of graphics controller driver via WMI
std::string LLDXHardware::getDriverVersionWMI()
{
@@ -613,6 +634,9 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
IDxDiagContainer *device_containerp = NULL;
IDxDiagContainer *file_containerp = NULL;
IDxDiagContainer *driver_containerp = NULL;
+ DWORD dw_device_count;
+
+ mVRAM = 0;
// CoCreate a IDxDiagProvider*
LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;
@@ -663,10 +687,21 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
if(FAILED(hr) || !devices_containerp)
{
+ // do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp
+ devices_containerp = NULL;
goto LCleanup;
}
+ // make sure there is something inside
+ hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count);
+ if (FAILED(hr) || dw_device_count == 0)
+ {
+ goto LCleanup;
+ }
+
// Get device 0
+ // By default 0 device is the primary one, howhever in case of various hybrid graphics
+ // like itegrated AMD and PCI AMD GPUs system might switch.
LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL;
hr = devices_containerp->GetChildContainer(L"0", &device_containerp);
if(FAILED(hr) || !device_containerp)
@@ -679,12 +714,27 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
WCHAR deviceID[512];
get_wstring(device_containerp, L"szDeviceID", deviceID, 512);
-
+ // Example: searches id like 1F06 in pnp string (aka VEN_10DE&DEV_1F06)
+ // doesn't seem to work on some systems since format is unrecognizable
+ // but in such case keyDeviceID works
if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))
{
mVRAM = vram/(1024*1024);
}
else
+ {
+ get_wstring(device_containerp, L"szKeyDeviceID", deviceID, 512);
+ LL_WARNS() << "szDeviceID" << deviceID << LL_ENDL;
+ // '+9' to avoid ENUM\\PCI\\ prefix
+ // Returns string like Enum\\PCI\\VEN_10DE&DEV_1F06&SUBSYS...
+ // and since GetVideoMemoryViaWMI searches by PNPDeviceID it is sufficient
+ if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram)))
+ {
+ mVRAM = vram / (1024 * 1024);
+ }
+ }
+
+ if (mVRAM == 0)
{ // Get the English VRAM string
std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish");
@@ -872,6 +922,7 @@ LLSD LLDXHardware::getDisplayInfo()
IDxDiagContainer *device_containerp = NULL;
IDxDiagContainer *file_containerp = NULL;
IDxDiagContainer *driver_containerp = NULL;
+ DWORD dw_device_count;
// CoCreate a IDxDiagProvider*
LL_INFOS() << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;
@@ -922,9 +973,18 @@ LLSD LLDXHardware::getDisplayInfo()
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
if(FAILED(hr) || !devices_containerp)
{
+ // do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp
+ devices_containerp = NULL;
goto LCleanup;
}
+ // make sure there is something inside
+ hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count);
+ if (FAILED(hr) || dw_device_count == 0)
+ {
+ goto LCleanup;
+ }
+
// Get device 0
LL_INFOS() << "devices_containerp->GetChildContainer" << LL_ENDL;
hr = devices_containerp->GetChildContainer(L"0", &device_containerp);
@@ -976,6 +1036,10 @@ LLSD LLDXHardware::getDisplayInfo()
}
LCleanup:
+ if (ret.emptyMap())
+ {
+ LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL;
+ }
SAFE_RELEASE(file_containerp);
SAFE_RELEASE(driver_containerp);
SAFE_RELEASE(device_containerp);
diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h
index cf33db8b37..1cb687e3b6 100644
--- a/indra/llwindow/lldxhardware.h
+++ b/indra/llwindow/lldxhardware.h
@@ -94,6 +94,10 @@ public:
LLSD getDisplayInfo();
+ // Will get memory of best GPU in MB, return memory on sucsess, 0 on failure
+ // Note: WMI is not accurate in some cases
+ static S32 getMBVideoMemoryViaWMI();
+
// Find a particular device that matches the following specs.
// Empty strings indicate that you don't care.
// You can separate multiple devices with '|' chars to indicate you want
diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h
index 8e6fbdb4e3..1dcd0348d8 100644
--- a/indra/llwindow/llmousehandler.h
+++ b/indra/llwindow/llmousehandler.h
@@ -66,6 +66,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0;
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0;
+ virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) = 0;
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask) = 0;
virtual const std::string& getName() const = 0;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 1b0b9213a5..5b9dce02c4 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -467,7 +467,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) scrollWheel:(NSEvent *)theEvent
{
- callScrollMoved(-[theEvent deltaY]);
+ callScrollMoved(-[theEvent deltaX], -[theEvent deltaY]);
}
- (void) mouseExited:(NSEvent *)theEvent
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index c01f574375..be61e1e16c 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -130,6 +130,10 @@ void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
{
}
+void LLWindowCallbacks::handleScrollHWheel(LLWindow *window, S32 clicks)
+{
+}
+
void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height)
{
}
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 9304446f8f..3b18648138 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -56,6 +56,7 @@ public:
virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleScrollWheel(LLWindow *window, S32 clicks);
+ virtual void handleScrollHWheel(LLWindow *window, S32 clicks);
virtual void handleResize(LLWindow *window, S32 width, S32 height);
virtual void handleFocus(LLWindow *window);
virtual void handleFocusLost(LLWindow *window);
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 0f77ebe7a4..44fd4127ce 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -142,7 +142,7 @@ void callDoubleClick(float *pos, unsigned int mask);
void callResize(unsigned int width, unsigned int height);
void callMouseMoved(float *pos, unsigned int mask);
void callMouseDragged(float *pos, unsigned int mask);
-void callScrollMoved(float delta);
+void callScrollMoved(float deltaX, float deltaY);
void callMouseExit();
void callWindowFocus();
void callWindowUnfocus();
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index d9b95d311a..2604a23c85 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -356,9 +356,13 @@ void callMouseDragged(float *pos, MASK mask)
gWindowImplementation->getCallbacks()->handleMouseDragged(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
}
-void callScrollMoved(float delta)
+void callScrollMoved(float deltaX, float deltaY)
{
- gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta);
+ if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
+ {
+ gWindowImplementation->getCallbacks()->handleScrollHWheel(gWindowImplementation, deltaX);
+ gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, deltaY);
+ }
}
void callMouseExit()
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 8fefb119bc..0b3936f8a5 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -741,17 +741,27 @@ void LLWindowWin32::restore()
SetFocus(mWindowHandle);
}
+// See SL-12170
+// According to callstack "c0000005 Access violation" happened inside __try block,
+// deep in DestroyWindow and crashed viewer, which shouldn't be possible.
+// I tried manually causing this exception and it was caught without issues, so
+// I'm turning off optimizations for this part to be sure code executes as intended
+// (it is a straw, but I have no idea why else __try can get overruled)
+#pragma optimize("", off)
bool destroy_window_handler(HWND &hWnd)
{
+ bool res;
__try
{
- return DestroyWindow(hWnd);
+ res = DestroyWindow(hWnd);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
- return false;
+ res = false;
}
+ return res;
}
+#pragma optimize("", on)
// close() destroys all OS-specific code associated with a window.
// Usually called from LLWindowManager::destroyWindow()
@@ -2662,6 +2672,42 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return 0;
}
*/
+ case WM_MOUSEHWHEEL:
+ {
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEHWHEEL");
+ static short h_delta = 0;
+
+ RECT client_rect;
+
+ // eat scroll events that occur outside our window, since we use mouse position to direct scroll
+ // instead of keyboard focus
+ // NOTE: mouse_coord is in *window* coordinates for scroll events
+ POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)};
+
+ if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
+ && GetClientRect(window_imp->mWindowHandle, &client_rect))
+ {
+ // we have a valid mouse point and client rect
+ if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
+ || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
+ {
+ // mouse is outside of client rect, so don't do anything
+ return 0;
+ }
+ }
+
+ S16 incoming_h_delta = HIWORD(w_param);
+ h_delta += incoming_h_delta;
+
+ // If the user rapidly spins the wheel, we can get messages with
+ // large deltas, like 480 or so. Thus we need to scroll more quickly.
+ if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta)
+ {
+ window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA);
+ h_delta = 0;
+ }
+ return 0;
+ }
// Handle mouse movement within the window
case WM_MOUSEMOVE:
{