diff options
Diffstat (limited to 'indra/llwindow')
-rw-r--r-- | indra/llwindow/CMakeLists.txt | 8 | ||||
-rw-r--r-- | indra/llwindow/lldragdropwin32.h | 4 | ||||
-rw-r--r-- | indra/llwindow/lldxhardware.cpp | 652 | ||||
-rw-r--r-- | indra/llwindow/lldxhardware.h | 68 | ||||
-rw-r--r-- | indra/llwindow/llkeyboardwin32.cpp | 2 | ||||
-rw-r--r-- | indra/llwindow/llopenglview-objc.mm | 96 | ||||
-rw-r--r-- | indra/llwindow/llwindow.cpp | 28 | ||||
-rw-r--r-- | indra/llwindow/llwindowcallbacks.cpp | 9 | ||||
-rw-r--r-- | indra/llwindow/llwindowcallbacks.h | 2 | ||||
-rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 146 | ||||
-rw-r--r-- | indra/llwindow/llwindowmacosx.h | 3 | ||||
-rw-r--r-- | indra/llwindow/llwindowsdl.cpp | 1357 | ||||
-rw-r--r-- | indra/llwindow/llwindowsdl.h | 47 | ||||
-rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 101 | ||||
-rw-r--r-- | indra/llwindow/llwindowwin32.h | 2 |
15 files changed, 620 insertions, 1905 deletions
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 6b70d66d7a..6debd54665 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -17,6 +17,7 @@ include(LLImage) include(LLWindow) include(UI) include(ViewerMiscLibs) +include(GLM) set(llwindow_SOURCE_FILES llcursortypes.cpp @@ -53,7 +54,7 @@ set(llwindow_LINK_LIBRARIES llmath llfilesystem llxml - ll::glh_linear + ll::glm ll::glext ll::uilibraries ll::SDL @@ -63,7 +64,7 @@ include_directories(${CMAKE_SOURCE_DIR}/llrender) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level -if (USESYSTEMLIBS AND NOT DARWIN) +if (NOT (DARWIN OR WINDOWS)) list(APPEND viewer_SOURCE_FILES llkeyboardsdl.cpp llwindowsdl.cpp @@ -85,7 +86,7 @@ if (USESYSTEMLIBS AND NOT DARWIN) fontconfig # For FCInit and other FC* functions. ) endif (BUILD_HEADLESS) -endif (USESYSTEMLIBS AND NOT DARWIN) +endif () if (DARWIN) list(APPEND llwindow_SOURCE_FILES @@ -182,7 +183,6 @@ endif (SDL_FOUND) target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) if (DARWIN) - include(CMakeFindFrameworks) find_library(CARBON_LIBRARY Carbon) target_link_libraries(llwindow ${CARBON_LIBRARY}) endif (DARWIN) diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h index 1b30dced27..16d016677b 100644 --- a/indra/llwindow/lldragdropwin32.h +++ b/indra/llwindow/lldragdropwin32.h @@ -31,7 +31,7 @@ #ifndef LL_LLDRAGDROP32_H #define LL_LLDRAGDROP32_H -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include <ole2.h> class LLDragDropWin32 @@ -54,7 +54,7 @@ class LLDragDropWin32 #ifndef LL_LLDRAGDROP32_H #define LL_LLDRAGDROP32_H -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include <ole2.h> // impostor class that does nothing diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 4bc069c5a4..387982dfc2 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -47,7 +47,6 @@ #include "llstl.h" #include "lltimer.h" -void (*gWriteDebug)(const char* msg) = NULL; LLDXHardware gDXHardware; //----------------------------------------------------------------------------- @@ -61,170 +60,6 @@ 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 hr; - bool bGotMemory = false; - IWbemLocator* pIWbemLocator = nullptr; - IWbemServices* pIWbemServices = nullptr; - BSTR pNamespace = nullptr; - - *pdwAdapterRam = 0; - CoInitializeEx(0, COINIT_APARTMENTTHREADED); - - hr = CoCreateInstance( CLSID_WbemLocator, - nullptr, - CLSCTX_INPROC_SERVER, - IID_IWbemLocator, - ( LPVOID* )&pIWbemLocator ); -#ifdef PRINTF_DEBUGGING - if( FAILED( hr ) ) wprintf( L"WMI: CoCreateInstance failed: 0x%0.8x\n", hr ); -#endif - - if( SUCCEEDED( hr ) && pIWbemLocator ) - { - // Using the locator, connect to WMI in the given namespace. - pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" ); - - hr = pIWbemLocator->ConnectServer( pNamespace, nullptr, nullptr, 0L, - 0L, nullptr, nullptr, &pIWbemServices ); -#ifdef PRINTF_DEBUGGING - if( FAILED( hr ) ) wprintf( L"WMI: pIWbemLocator->ConnectServer failed: 0x%0.8x\n", hr ); -#endif - if( SUCCEEDED( hr ) && pIWbemServices != 0 ) - { - HINSTANCE hinstOle32 = nullptr; - - hinstOle32 = LoadLibraryW( L"ole32.dll" ); - if( hinstOle32 ) - { - PfnCoSetProxyBlanket pfnCoSetProxyBlanket = nullptr; - - pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" ); - if( pfnCoSetProxyBlanket != 0 ) - { - // Switch security level to IMPERSONATE. - pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 ); - } - - FreeLibrary( hinstOle32 ); - } - - IEnumWbemClassObject* pEnumVideoControllers = nullptr; - BSTR pClassName = nullptr; - - pClassName = SysAllocString( L"Win32_VideoController" ); - - hr = pIWbemServices->CreateInstanceEnum( pClassName, 0, - nullptr, &pEnumVideoControllers ); -#ifdef PRINTF_DEBUGGING - if( FAILED( hr ) ) wprintf( L"WMI: pIWbemServices->CreateInstanceEnum failed: 0x%0.8x\n", hr ); -#endif - - if( SUCCEEDED( hr ) && pEnumVideoControllers ) - { - IWbemClassObject* pVideoControllers[10] = {0}; - DWORD uReturned = 0; - BSTR pPropName = nullptr; - - // Get the first one in the list - pEnumVideoControllers->Reset(); - hr = pEnumVideoControllers->Next( 5000, // timeout in 5 seconds - 10, // return the first 10 - pVideoControllers, - &uReturned ); -#ifdef PRINTF_DEBUGGING - if( FAILED( hr ) ) wprintf( L"WMI: pEnumVideoControllers->Next failed: 0x%0.8x\n", hr ); - if( uReturned == 0 ) wprintf( L"WMI: pEnumVideoControllers uReturned == 0\n" ); -#endif - - VARIANT var; - if( SUCCEEDED( hr ) ) - { - bool bFound = false; - for( UINT iController = 0; iController < uReturned; iController++ ) - { - if ( !pVideoControllers[iController] ) - continue; - - // 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 ); -#endif - if( SUCCEEDED( hr ) && strInputDeviceID) - { - if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 ) - bFound = true; - } - VariantClear( &var ); - if( pPropName ) SysFreeString( pPropName ); - } - - if( bFound || !strInputDeviceID ) - { - pPropName = SysAllocString( L"AdapterRAM" ); - hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); -#ifdef PRINTF_DEBUGGING - if( FAILED( hr ) ) - wprintf( L"WMI: pVideoControllers[iController]->Get AdapterRAM failed: 0x%0.8x\n", - hr ); -#endif - if( SUCCEEDED( hr ) ) - { - bGotMemory = true; - *pdwAdapterRam = llmax(var.ulVal, *pdwAdapterRam); - } - VariantClear( &var ); - if( pPropName ) SysFreeString( pPropName ); - } - - SAFE_RELEASE( pVideoControllers[iController] ); - - if (bFound) - { - break; - } - } - } - } - - if( pClassName ) - SysFreeString( pClassName ); - SAFE_RELEASE( pEnumVideoControllers ); - } - - if( pNamespace ) - SysFreeString( pNamespace ); - SAFE_RELEASE( pIWbemServices ); - } - - SAFE_RELEASE( pIWbemLocator ); - - CoUninitialize(); - - if( bGotMemory ) - return S_OK; - else - return E_FAIL; -} - -//static -U32 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(EGPUVendor vendor) @@ -480,495 +315,14 @@ std::string get_string(IDxDiagContainer *containerp, const WCHAR *wszPropName) return utf16str_to_utf8str(wszPropValue); } - -LLVersion::LLVersion() -{ - mValid = false; - S32 i; - for (i = 0; i < 4; i++) - { - mFields[i] = 0; - } -} - -bool LLVersion::set(const std::string &version_string) -{ - S32 i; - for (i = 0; i < 4; i++) - { - mFields[i] = 0; - } - // Split the version string. - std::string str(version_string); - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep(".", "", boost::keep_empty_tokens); - tokenizer tokens(str, sep); - - tokenizer::iterator iter = tokens.begin(); - S32 count = 0; - for (;(iter != tokens.end()) && (count < 4);++iter) - { - mFields[count] = atoi(iter->c_str()); - count++; - } - if (count < 4) - { - //LL_WARNS() << "Potentially bogus version string!" << version_string << LL_ENDL; - for (i = 0; i < 4; i++) - { - mFields[i] = 0; - } - mValid = false; - } - else - { - mValid = true; - } - return mValid; -} - -S32 LLVersion::getField(const S32 field_num) -{ - if (!mValid) - { - return -1; - } - else - { - return mFields[field_num]; - } -} - -std::string LLDXDriverFile::dump() -{ - if (gWriteDebug) - { - gWriteDebug("Filename:"); - gWriteDebug(mName.c_str()); - gWriteDebug("\n"); - gWriteDebug("Ver:"); - gWriteDebug(mVersionString.c_str()); - gWriteDebug("\n"); - gWriteDebug("Date:"); - gWriteDebug(mDateString.c_str()); - gWriteDebug("\n"); - } - LL_INFOS() << mFilepath << LL_ENDL; - LL_INFOS() << mName << LL_ENDL; - LL_INFOS() << mVersionString << LL_ENDL; - LL_INFOS() << mDateString << LL_ENDL; - - return ""; -} - -LLDXDevice::~LLDXDevice() -{ - for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer()); - mDriverFiles.clear(); -} - -std::string LLDXDevice::dump() -{ - if (gWriteDebug) - { - gWriteDebug("StartDevice\n"); - gWriteDebug("DeviceName:"); - gWriteDebug(mName.c_str()); - gWriteDebug("\n"); - gWriteDebug("PCIString:"); - gWriteDebug(mPCIString.c_str()); - gWriteDebug("\n"); - } - LL_INFOS() << LL_ENDL; - LL_INFOS() << "DeviceName:" << mName << LL_ENDL; - LL_INFOS() << "PCIString:" << mPCIString << LL_ENDL; - LL_INFOS() << "Drivers" << LL_ENDL; - LL_INFOS() << "-------" << LL_ENDL; - for (driver_file_map_t::iterator iter = mDriverFiles.begin(), - end = mDriverFiles.end(); - iter != end; iter++) - { - LLDXDriverFile *filep = iter->second; - filep->dump(); - } - if (gWriteDebug) - { - gWriteDebug("EndDevice\n"); - } - - return ""; -} - -LLDXDriverFile *LLDXDevice::findDriver(const std::string &driver) -{ - for (driver_file_map_t::iterator iter = mDriverFiles.begin(), - end = mDriverFiles.end(); - iter != end; iter++) - { - LLDXDriverFile *filep = iter->second; - if (!utf8str_compare_insensitive(filep->mName,driver)) - { - return filep; - } - } - - return NULL; -} - LLDXHardware::LLDXHardware() { - mVRAM = 0; - gWriteDebug = NULL; } void LLDXHardware::cleanup() { - // for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer()); - // mDevices.clear(); -} - -/* -std::string LLDXHardware::dumpDevices() -{ - if (gWriteDebug) - { - gWriteDebug("\n"); - gWriteDebug("StartAllDevices\n"); - } - for (device_map_t::iterator iter = mDevices.begin(), - end = mDevices.end(); - iter != end; iter++) - { - LLDXDevice *devicep = iter->second; - devicep->dump(); - } - if (gWriteDebug) - { - gWriteDebug("EndAllDevices\n\n"); - } - return ""; } -LLDXDevice *LLDXHardware::findDevice(const std::string &vendor, const std::string &devices) -{ - // Iterate through different devices tokenized in devices string - std::string str(devices); - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("|", "", boost::keep_empty_tokens); - tokenizer tokens(str, sep); - - tokenizer::iterator iter = tokens.begin(); - for (;iter != tokens.end();++iter) - { - std::string dev_str = *iter; - for (device_map_t::iterator iter = mDevices.begin(), - end = mDevices.end(); - iter != end; iter++) - { - LLDXDevice *devicep = iter->second; - if ((devicep->mVendorID == vendor) - && (devicep->mDeviceID == dev_str)) - { - return devicep; - } - } - } - - return NULL; -} -*/ - -bool LLDXHardware::getInfo(bool vram_only) -{ - LLTimer hw_timer; - bool ok = false; - HRESULT hr; - - // CLSID_DxDiagProvider does not work with Multithreaded? - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - - IDxDiagProvider *dx_diag_providerp = NULL; - IDxDiagContainer *dx_diag_rootp = NULL; - IDxDiagContainer *devices_containerp = NULL; - // IDxDiagContainer *system_device_containerp= NULL; - 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; - hr = CoCreateInstance(CLSID_DxDiagProvider, - NULL, - CLSCTX_INPROC_SERVER, - IID_IDxDiagProvider, - (LPVOID*) &dx_diag_providerp); - - if (FAILED(hr)) - { - LL_WARNS("AppInit") << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; - gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); - goto LCleanup; - } - if (SUCCEEDED(hr)) // if FAILED(hr) then dx9 is not installed - { - // Fill out a DXDIAG_INIT_PARAMS struct and pass it to IDxDiagContainer::Initialize - // Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are - // digital signed as logo'd by WHQL which may connect via internet to update - // WHQL certificates. - DXDIAG_INIT_PARAMS dx_diag_init_params; - ZeroMemory(&dx_diag_init_params, sizeof(DXDIAG_INIT_PARAMS)); - - dx_diag_init_params.dwSize = sizeof(DXDIAG_INIT_PARAMS); - dx_diag_init_params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; - dx_diag_init_params.bAllowWHQLChecks = TRUE; - dx_diag_init_params.pReserved = NULL; - - LL_DEBUGS("AppInit") << "dx_diag_providerp->Initialize" << LL_ENDL; - hr = dx_diag_providerp->Initialize(&dx_diag_init_params); - if(FAILED(hr)) - { - goto LCleanup; - } - - LL_DEBUGS("AppInit") << "dx_diag_providerp->GetRootContainer" << LL_ENDL; - hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp ); - if(FAILED(hr) || !dx_diag_rootp) - { - goto LCleanup; - } - - HRESULT hr; - - // Get display driver information - LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer" << LL_ENDL; - 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) - { - goto LCleanup; - } - - DWORD vram = 0; - - 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"); - - // We don't need the device any more - SAFE_RELEASE(device_containerp); - - // Dump the string as an int into the structure - char *stopstring; - mVRAM = strtol(ram_str.c_str(), &stopstring, 10); - LL_INFOS("AppInit") << "VRAM Detected: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL; - } - - if (vram_only) - { - ok = true; - goto LCleanup; - } - - - /* for now, we ONLY do vram_only the rest of this - is commented out, to ensure no-one is tempted - to use it - - // Now let's get device and driver information - // Get the IDxDiagContainer object called "DxDiag_SystemDevices". - // This call may take some time while dxdiag gathers the info. - DWORD num_devices = 0; - WCHAR wszContainer[256]; - LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer DxDiag_SystemDevices" << LL_ENDL; - hr = dx_diag_rootp->GetChildContainer(L"DxDiag_SystemDevices", &system_device_containerp); - if (FAILED(hr)) - { - goto LCleanup; - } - - hr = system_device_containerp->GetNumberOfChildContainers(&num_devices); - if (FAILED(hr)) - { - goto LCleanup; - } - - LL_DEBUGS("AppInit") << "DX9 iterating over devices" << LL_ENDL; - S32 device_num = 0; - for (device_num = 0; device_num < (S32)num_devices; device_num++) - { - hr = system_device_containerp->EnumChildContainerNames(device_num, wszContainer, 256); - if (FAILED(hr)) - { - goto LCleanup; - } - - hr = system_device_containerp->GetChildContainer(wszContainer, &device_containerp); - if (FAILED(hr) || device_containerp == NULL) - { - goto LCleanup; - } - - std::string device_name = get_string(device_containerp, L"szDescription"); - - std::string device_id = get_string(device_containerp, L"szDeviceID"); - - LLDXDevice *dxdevicep = new LLDXDevice; - dxdevicep->mName = device_name; - dxdevicep->mPCIString = device_id; - mDevices[dxdevicep->mPCIString] = dxdevicep; - - // Split the PCI string based on vendor, device, subsys, rev. - std::string str(device_id); - typedef boost::tokenizer<boost::char_separator<char> > tokenizer; - boost::char_separator<char> sep("&\\", "", boost::keep_empty_tokens); - tokenizer tokens(str, sep); - - tokenizer::iterator iter = tokens.begin(); - S32 count = 0; - bool valid = true; - for (;(iter != tokens.end()) && (count < 3);++iter) - { - switch (count) - { - case 0: - if (strcmp(iter->c_str(), "PCI")) - { - valid = false; - } - break; - case 1: - dxdevicep->mVendorID = iter->c_str(); - break; - case 2: - dxdevicep->mDeviceID = iter->c_str(); - break; - default: - // Ignore it - break; - } - count++; - } - - - - - // Now, iterate through the related drivers - hr = device_containerp->GetChildContainer(L"Drivers", &driver_containerp); - if (FAILED(hr) || !driver_containerp) - { - goto LCleanup; - } - - DWORD num_files = 0; - hr = driver_containerp->GetNumberOfChildContainers(&num_files); - if (FAILED(hr)) - { - goto LCleanup; - } - - S32 file_num = 0; - for (file_num = 0; file_num < (S32)num_files; file_num++ ) - { - - hr = driver_containerp->EnumChildContainerNames(file_num, wszContainer, 256); - if (FAILED(hr)) - { - goto LCleanup; - } - - hr = driver_containerp->GetChildContainer(wszContainer, &file_containerp); - if (FAILED(hr) || file_containerp == NULL) - { - goto LCleanup; - } - - std::string driver_path = get_string(file_containerp, L"szPath"); - std::string driver_name = get_string(file_containerp, L"szName"); - std::string driver_version = get_string(file_containerp, L"szVersion"); - std::string driver_date = get_string(file_containerp, L"szDatestampEnglish"); - - LLDXDriverFile *dxdriverfilep = new LLDXDriverFile; - dxdriverfilep->mName = driver_name; - dxdriverfilep->mFilepath= driver_path; - dxdriverfilep->mVersionString = driver_version; - dxdriverfilep->mVersion.set(driver_version); - dxdriverfilep->mDateString = driver_date; - - dxdevicep->mDriverFiles[driver_name] = dxdriverfilep; - - SAFE_RELEASE(file_containerp); - } - SAFE_RELEASE(device_containerp); - } - */ - } - - // dumpDevices(); - ok = true; - -LCleanup: - if (!ok) - { - LL_WARNS("AppInit") << "DX9 probe failed" << LL_ENDL; - gWriteDebug("DX9 probe failed\n"); - } - - SAFE_RELEASE(file_containerp); - SAFE_RELEASE(driver_containerp); - SAFE_RELEASE(device_containerp); - SAFE_RELEASE(devices_containerp); - SAFE_RELEASE(dx_diag_rootp); - SAFE_RELEASE(dx_diag_providerp); - - CoUninitialize(); - - return ok; - } - LLSD LLDXHardware::getDisplayInfo() { LLTimer hw_timer; @@ -995,7 +349,6 @@ LLSD LLDXHardware::getDisplayInfo() if (FAILED(hr)) { LL_WARNS() << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL; - gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n"); goto LCleanup; } if (SUCCEEDED(hr)) // if FAILED(hr) then dx9 is not installed @@ -1111,9 +464,4 @@ LCleanup: return ret; } -void LLDXHardware::setWriteDebugFunc(void (*func)(const char*)) -{ - gWriteDebug = func; -} - #endif diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h index 2b879e021c..8d8a08a4eb 100644 --- a/indra/llwindow/lldxhardware.h +++ b/indra/llwindow/lldxhardware.h @@ -30,64 +30,16 @@ #include <map> #include "stdtypes.h" -#include "llstring.h" #include "llsd.h" -class LLVersion -{ -public: - LLVersion(); - bool set(const std::string &version_string); - S32 getField(const S32 field_num); -protected: - std::string mVersionString; - S32 mFields[4]; - bool mValid; -}; - -class LLDXDriverFile -{ -public: - std::string dump(); - -public: - std::string mFilepath; - std::string mName; - std::string mVersionString; - LLVersion mVersion; - std::string mDateString; -}; - -class LLDXDevice -{ -public: - ~LLDXDevice(); - std::string dump(); - - LLDXDriverFile *findDriver(const std::string &driver); -public: - std::string mName; - std::string mPCIString; - std::string mVendorID; - std::string mDeviceID; - - typedef std::map<std::string, LLDXDriverFile *> driver_file_map_t; - driver_file_map_t mDriverFiles; -}; - class LLDXHardware { public: LLDXHardware(); - void setWriteDebugFunc(void (*func)(const char*)); void cleanup(); - // Returns true on success. - // vram_only true does a "light" probe. - bool getInfo(bool vram_only); - // WMI can return multiple GPU drivers // specify which one to output typedef enum { @@ -98,29 +50,9 @@ public: } EGPUVendor; std::string getDriverVersionWMI(EGPUVendor vendor); - S32 getVRAM() const { return mVRAM; } - 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 U32 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 - // ANY of them to match and return. - // LLDXDevice *findDevice(const std::string &vendor, const std::string &devices); - - // std::string dumpDevices(); -public: - typedef std::map<std::string, LLDXDevice *> device_map_t; - // device_map_t mDevices; -protected: - S32 mVRAM; }; -extern void (*gWriteDebug)(const char* msg); extern LLDXHardware gDXHardware; #endif // LL_LLDXHARDWARE_H diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index ec0055fe60..8d6b8d9b93 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -28,7 +28,7 @@ #include "linden_common.h" -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include "llkeyboardwin32.h" #include "llwindowcallbacks.h" diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 0bd4e506a2..6177eb4873 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -64,16 +64,16 @@ attributedStringInfo getSegments(NSAttributedString *str) segment_standouts seg_standouts; NSRange effectiveRange; NSRange limitRange = NSMakeRange(0, [str length]); - + while (limitRange.length > 0) { NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange]; limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange)); - + if (effectiveRange.length <= 0) { effectiveRange.length = 1; } - + if ([attr integerValue] == 2) { seg_lengths.push_back(effectiveRange.length); @@ -96,12 +96,12 @@ attributedStringInfo getSegments(NSAttributedString *str) + (NSScreen *)currentScreenForMouseLocation { NSPoint mouseLocation = [NSEvent mouseLocation]; - + NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator]; NSScreen *screen; while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO)) ; - + return screen; } @@ -110,7 +110,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x)); float normalizedY = aPoint.y - self.frame.origin.y; - + return NSMakePoint(normalizedX, normalizedY); } @@ -153,7 +153,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { vram_megabytes = 256; } - + return (unsigned long)vram_megabytes; // return value is in megabytes. } @@ -162,15 +162,15 @@ attributedStringInfo getSegments(NSAttributedString *str) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:NSWindowDidResizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:[self window]]; @@ -246,7 +246,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { [self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]]; [self initWithFrame:frame]; - + // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6. // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat. // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons). @@ -255,8 +255,8 @@ attributedStringInfo getSegments(NSAttributedString *str) NSOpenGLPFADoubleBuffer, NSOpenGLPFAClosestPolicy, NSOpenGLPFAAccelerated, - NSOpenGLPFASampleBuffers, static_cast<NSOpenGLPixelFormatAttribute>(samples > 0 ? 1 : 0), - NSOpenGLPFASamples, static_cast<NSOpenGLPixelFormatAttribute>(samples), + NSOpenGLPFASampleBuffers, 0, + NSOpenGLPFASamples, 0, NSOpenGLPFAStencilSize, 8, NSOpenGLPFADepthSize, 24, NSOpenGLPFAAlphaSize, 8, @@ -264,34 +264,34 @@ attributedStringInfo getSegments(NSAttributedString *str) NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, 0 }; - + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease]; - + if (pixelFormat == nil) { NSLog(@"Failed to create pixel format!", nil); return nil; } - + NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - + if (glContext == nil) { NSLog(@"Failed to create OpenGL context!", nil); return nil; } - + [self setPixelFormat:pixelFormat]; //for retina support [self setWantsBestResolutionOpenGLSurface:gHiDPISupport]; [self setOpenGLContext:glContext]; - + [glContext setView:self]; - + [glContext makeCurrentContext]; - + if (vsync) { GLint value = 1; @@ -303,9 +303,9 @@ attributedStringInfo getSegments(NSAttributedString *str) GLint swapInterval=0; [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; } - + mOldResize = false; - + return self; } @@ -317,16 +317,16 @@ attributedStringInfo getSegments(NSAttributedString *str) - (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format { NSOpenGLContext *ctx = [self openGLContext]; - + [ctx clearDrawable]; [ctx initWithFormat:format shareContext:nil]; - + if (ctx == nil) { NSLog(@"Failed to create OpenGL context!", nil); return false; } - + [self setOpenGLContext:ctx]; [ctx setView:self]; [ctx makeCurrentContext]; @@ -413,9 +413,9 @@ attributedStringInfo getSegments(NSAttributedString *str) float(dev_delta.x), float(dev_delta.y) }; - + callDeltaUpdate(mouseDeltas, 0); - + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; @@ -437,9 +437,9 @@ attributedStringInfo getSegments(NSAttributedString *str) float(dev_delta.x), float(dev_delta.y) }; - + callDeltaUpdate(mouseDeltas, 0); - + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; @@ -469,7 +469,7 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) otherMouseDragged:(NSEvent *)theEvent { - [self mouseDragged:theEvent]; + [self mouseDragged:theEvent]; } - (void) scrollWheel:(NSEvent *)theEvent @@ -493,7 +493,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent); eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; - + uint keycode = [theEvent keyCode]; // We must not depend on flagsChange event to detect modifier flags changed, // must depend on the modifire flags in the event parameter. @@ -527,13 +527,13 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void)flagsChanged:(NSEvent *)theEvent { NativeKeyEventData eventData = extractKeyDataFromModifierEvent(theEvent); - + mModifiers = [theEvent modifierFlags]; callModifier([theEvent modifierFlags]); - + NSInteger mask = 0; switch([theEvent keyCode]) - { + { case 56: mask = NSShiftKeyMask; break; @@ -544,9 +544,9 @@ attributedStringInfo getSegments(NSAttributedString *str) mask = NSControlKeyMask; break; default: - return; + return; } - + if (mModifiers & mask) { eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; @@ -565,7 +565,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { eventData.mKeyEvent = NativeKeyEventData::KEYUP; callKeyUp(&eventData, [theEvent keyCode], 0); - } + } } - (BOOL) acceptsFirstResponder @@ -577,11 +577,11 @@ attributedStringInfo getSegments(NSAttributedString *str) { NSPasteboard *pboard; NSDragOperation sourceDragMask; - + sourceDragMask = [sender draggingSourceOperationMask]; - + pboard = [sender draggingPasteboard]; - + if ([[pboard types] containsObject:NSURLPboardType]) { if (sourceDragMask & NSDragOperationLink) { @@ -596,7 +596,7 @@ attributedStringInfo getSegments(NSAttributedString *str) - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender { callHandleDragUpdated(mLastDraggedUrl); - + return NSDragOperationLink; } @@ -650,12 +650,12 @@ attributedStringInfo getSegments(NSAttributedString *str) unsigned(selectedRange.location), unsigned(selectedRange.length) }; - + unsigned int replacement[2] = { unsigned(replacementRange.location), unsigned(replacementRange.length) }; - + int string_length = [aString length]; unichar text[string_length]; attributedStringInfo segments; @@ -754,7 +754,7 @@ attributedStringInfo getSegments(NSAttributedString *str) return; } } - + @try { if (!mHasMarkedText) @@ -767,7 +767,7 @@ attributedStringInfo getSegments(NSAttributedString *str) resetPreedit(); // We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text. // But just in case... - + for (NSInteger i = 0; i < [aString length]; i++) { handleUnicodeCharacter([aString characterAtIndex:i]); @@ -913,10 +913,10 @@ attributedStringInfo getSegments(NSAttributedString *str) NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint]; NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint]; flippedScreenPoint.y += [currentScreen frame].origin.y; - + return flippedScreenPoint; } - + return NSZeroPoint; } diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 302d038a79..bff559591f 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -74,12 +74,12 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type) LL_WARNS() << "OSMessageBox: " << text << LL_ENDL; #if LL_MESA_HEADLESS // !!! *FIX: (?) return OSBTN_OK; +#elif LL_SDL + result = OSMessageBoxSDL(text, caption, type); #elif LL_WINDOWS result = OSMessageBoxWin32(text, caption, type); -#elif LL_DARWIN && !LL_SDL +#elif LL_DARWIN result = OSMessageBoxMacOSX(text, caption, type); -#elif LL_SDL - result = OSMessageBoxSDL(text, caption, type); #else #error("OSMessageBox not implemented for this platform!") #endif @@ -259,12 +259,12 @@ bool LLWindow::copyTextToPrimary(const LLWString &src) // static std::vector<std::string> LLWindow::getDynamicFallbackFontList() { -#if LL_WINDOWS +#if LL_SDL + return LLWindowSDL::getDynamicFallbackFontList(); +#elif LL_WINDOWS return LLWindowWin32::getDynamicFallbackFontList(); -#elif LL_DARWIN && !LL_SDL +#elif LL_DARWIN return LLWindowMacOSX::getDynamicFallbackFontList(); -#elif LL_SDL - return LLWindowSDL::getDynamicFallbackFontList(); #else return std::vector<std::string>(); #endif @@ -273,12 +273,12 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList() // static std::vector<std::string> LLWindow::getDisplaysResolutionList() { -#if LL_WINDOWS +#if LL_SDL + return std::vector<std::string>(); +#elif LL_WINDOWS return LLWindowWin32::getDisplaysResolutionList(); -#elif LL_DARWIN && !LL_SDL +#elif LL_DARWIN return LLWindowMacOSX::getDisplaysResolutionList(); -#else - return std::vector<std::string>(); #endif } @@ -346,7 +346,7 @@ LLSplashScreen *LLSplashScreen::create() return 0; #elif LL_WINDOWS return new LLSplashScreenWin32; -#elif LL_DARWIN && !LL_SDL +#elif LL_DARWIN return new LLSplashScreenMacOSX; #else #error("LLSplashScreen not implemented on this platform!") @@ -359,7 +359,7 @@ void LLSplashScreen::show() { if (!gSplashScreenp) { -#if LL_WINDOWS && !LL_MESA_HEADLESS +#if LL_WINDOWS && !LL_MESA_HEADLESS && !LL_SDL gSplashScreenp = new LLSplashScreenWin32; #elif LL_DARWIN && !LL_SDL gSplashScreenp = new LLSplashScreenMacOSX; @@ -421,7 +421,7 @@ LLWindow* LLWindowManager::createWindow( fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); #elif LL_SDL new_window = new LLWindowSDL(callbacks, - title, x, y, width, height, flags, + title, name, x, y, width, height, flags, fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS new_window = new LLWindowWin32(callbacks, diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index 624ecd5030..195f68e08b 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -52,10 +52,6 @@ bool LLWindowCallbacks::handleUnicodeChar(llwchar uni_char, MASK mask) return false; } -bool LLWindowCallbacks::handleUnicodeString(char *uni_str, bool editing) -{ - return FALSE; -} bool LLWindowCallbacks::handleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask) { @@ -198,6 +194,11 @@ bool LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, return false; } +bool LLWindowCallbacks::handleDisplayChanged() +{ + return false; +} + bool LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow *window) { return false; diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 74660e1705..d812f93524 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -37,7 +37,6 @@ public: virtual bool handleTranslatedKeyUp(KEY key, MASK mask); virtual void handleScanKey(KEY key, bool key_down, bool key_up, bool key_level); virtual bool handleUnicodeChar(llwchar uni_char, MASK mask); - virtual bool handleUnicodeString(char *uni_str, bool editing); virtual bool handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); virtual bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); @@ -70,6 +69,7 @@ public: virtual bool handleTimerEvent(LLWindow *window); virtual bool handleDeviceChange(LLWindow *window); virtual bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); + virtual bool handleDisplayChanged(); virtual bool handleWindowDidChangeScreen(LLWindow *window); enum DragNDropAction { diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 3cfc9d7c84..c97e014e46 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -69,6 +69,41 @@ namespace bool LLWindowMacOSX::sUseMultGL = false; +//static +void LLWindowMacOSX::setUseMultGL(bool use_mult_gl) +{ + bool was_enabled = sUseMultGL; + + sUseMultGL = use_mult_gl; + + if (gGLManager.mInited) + { + CGLContextObj ctx = CGLGetCurrentContext(); + //enable multi-threaded OpenGL (whether or not sUseMultGL actually changed) + if (sUseMultGL) + { + CGLError cgl_err; + + cgl_err = CGLEnable( ctx, kCGLCEMPEngine); + + if (cgl_err != kCGLNoError ) + { + LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; + sUseMultGL = false; + } + else + { + LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; + } + } + else if (was_enabled) + { + CGLDisable( ctx, kCGLCEMPEngine); + LL_INFOS("GLInit") << "Multi-threaded OpenGL disabled." << LL_ENDL; + } + } +} + // Cross-platform bits: bool check_for_card(const char* RENDERER, const char* bad_card) @@ -245,6 +280,10 @@ void callResetKeys() bool callUnicodeCallback(wchar_t character, unsigned int mask) { + if (!gWindowImplementation) + { + return false; + } NativeKeyEventData eventData; memset(&eventData, 0, sizeof(NativeKeyEventData)); @@ -266,7 +305,7 @@ bool callUnicodeCallback(wchar_t character, unsigned int mask) void callFocus() { - if (gWindowImplementation) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); } @@ -274,7 +313,7 @@ void callFocus() void callFocusLost() { - if (gWindowImplementation) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); } @@ -282,6 +321,10 @@ void callFocusLost() void callRightMouseDown(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -295,6 +338,10 @@ void callRightMouseDown(float *pos, MASK mask) void callRightMouseUp(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -308,6 +355,10 @@ void callRightMouseUp(float *pos, MASK mask) void callLeftMouseDown(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -321,6 +372,10 @@ void callLeftMouseDown(float *pos, MASK mask) void callLeftMouseUp(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -335,6 +390,10 @@ void callLeftMouseUp(float *pos, MASK mask) void callDoubleClick(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -348,7 +407,7 @@ void callDoubleClick(float *pos, MASK mask) void callResize(unsigned int width, unsigned int height) { - if (gWindowImplementation != NULL) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height); } @@ -356,6 +415,10 @@ void callResize(unsigned int width, unsigned int height) void callMouseMoved(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -369,6 +432,10 @@ void callMouseMoved(float *pos, MASK mask) void callMouseDragged(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -390,6 +457,10 @@ void callScrollMoved(float deltaX, float deltaY) void callMouseExit() { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation); } @@ -441,11 +512,19 @@ void callWindowDidChangeScreen() void callDeltaUpdate(float *delta, MASK mask) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->updateMouseDeltas(delta); } void callOtherMouseDown(float *pos, MASK mask, int button) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -466,6 +545,10 @@ void callOtherMouseDown(float *pos, MASK mask, int button) void callOtherMouseUp(float *pos, MASK mask, int button) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -490,27 +573,43 @@ void callModifier(MASK mask) void callHandleDragEntered(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING); } void callHandleDragExited(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING); } void callHandleDragUpdated(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK); } void callHandleDragDropped(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED); } void callQuitHandler() { - if (gWindowImplementation) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) { @@ -521,7 +620,7 @@ void callQuitHandler() void getPreeditSelectionRange(int *position, int *length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->getSelectionRange(position, length); } @@ -529,7 +628,7 @@ void getPreeditSelectionRange(int *position, int *length) void getPreeditMarkedRange(int *position, int *length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->getPreeditRange(position, length); } @@ -537,7 +636,7 @@ void getPreeditMarkedRange(int *position, int *length) void setPreeditMarkedRange(int position, int length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->markAsPreedit(position, length); } @@ -546,7 +645,7 @@ void setPreeditMarkedRange(int position, int length) bool handleUnicodeCharacter(wchar_t c) { bool success = false; - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); } @@ -556,7 +655,7 @@ bool handleUnicodeCharacter(wchar_t c) void resetPreedit() { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->resetPreedit(); } @@ -566,7 +665,7 @@ void resetPreedit() // This largely mirrors the old implementation, only sans the carbon parameters. void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); preeditor->resetPreedit(); @@ -589,7 +688,7 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne void getPreeditLocation(float *location, unsigned int length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); LLCoordGL coord; @@ -705,23 +804,8 @@ bool LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Disable vertical sync for swap toggleVSync(enable_vsync); - //enable multi-threaded OpenGL - if (sUseMultGL) - { - CGLError cgl_err; - CGLContextObj ctx = CGLGetCurrentContext(); - - cgl_err = CGLEnable( ctx, kCGLCEMPEngine); + setUseMultGL(sUseMultGL); - if (cgl_err != kCGLNoError ) - { - LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; - } - else - { - LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; - } - } makeFirstResponder(mWindow, mGLView); return true; @@ -1041,7 +1125,7 @@ F32 LLWindowMacOSX::getGamma() &greenGamma, &blueMin, &blueMax, - &blueGamma) == noErr) + &blueGamma) == kCGErrorSuccess) { // So many choices... // Let's just return the green channel gamma for now. @@ -1092,7 +1176,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma) &greenGamma, &blueMin, &blueMax, - &blueGamma) != noErr) + &blueGamma) != kCGErrorSuccess) { return false; } @@ -1107,7 +1191,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma) gamma, blueMin, blueMax, - gamma) != noErr) + gamma) != kCGErrorSuccess) { return false; } @@ -1159,7 +1243,7 @@ bool LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) newPosition.y = screen_pos.mY; CGSetLocalEventsSuppressionInterval(0.0); - if(CGWarpMouseCursorPosition(newPosition) == noErr) + if(CGWarpMouseCursorPosition(newPosition) == kCGErrorSuccess) { result = true; } diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index f5b6441746..7de1a40d93 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -147,6 +147,9 @@ public: void toggleVSync(bool enable_vsync) override; + // enable or disable multithreaded GL + static void setUseMultGL(bool use_mult_gl); + protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 8c90f917b8..69332e36b6 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -61,9 +61,6 @@ extern bool gDebugWindowProc; const S32 MAX_NUM_RESOLUTIONS = 200; -// static variable for ATI mouse cursor crash work-around: -static bool ATIbug = false; - #if LL_DARWIN #include <OpenGL/OpenGL.h> @@ -152,257 +149,14 @@ Display* LLWindowSDL::get_SDL_Display(void) } #endif // LL_X11 -#if LL_X11 - -// Clipboard handing via native X11, base on the implementation in Cool VL by Henri Beauchamp - -namespace -{ - std::array<Atom, 3> gSupportedAtoms; - - Atom XA_CLIPBOARD; - Atom XA_TARGETS; - Atom PVT_PASTE_BUFFER; - long const MAX_PASTE_BUFFER_SIZE = 16383; - - void filterSelectionRequest( XEvent aEvent ) - { - auto *display = LLWindowSDL::getSDLDisplay(); - auto &request = aEvent.xselectionrequest; - - XSelectionEvent reply { SelectionNotify, aEvent.xany.serial, aEvent.xany.send_event, display, - request.requestor, request.selection, request.target, - request.property,request.time }; - - if (request.target == XA_TARGETS) - { - XChangeProperty(display, request.requestor, request.property, - XA_ATOM, 32, PropModeReplace, - (unsigned char *) &gSupportedAtoms.front(), gSupportedAtoms.size()); - } - else if (std::find(gSupportedAtoms.begin(), gSupportedAtoms.end(), request.target) != - gSupportedAtoms.end()) - { - std::string utf8; - if (request.selection == XA_PRIMARY) - utf8 = wstring_to_utf8str(gWindowImplementation->getPrimaryText()); - else - utf8 = wstring_to_utf8str(gWindowImplementation->getSecondaryText()); - - XChangeProperty(display, request.requestor, request.property, - request.target, 8, PropModeReplace, - (unsigned char *) utf8.c_str(), utf8.length()); - } - else if (request.selection == XA_CLIPBOARD) - { - // Did not have what they wanted, so no property set - reply.property = None; - } - else - return; - - XSendEvent(request.display, request.requestor, False, NoEventMask, (XEvent *) &reply); - XSync(display, False); - } - - void filterSelectionClearRequest( XEvent aEvent ) - { - auto &request = aEvent.xselectionrequest; - if (request.selection == XA_PRIMARY) - gWindowImplementation->clearPrimaryText(); - else if (request.selection == XA_CLIPBOARD) - gWindowImplementation->clearSecondaryText(); - } - - int x11_clipboard_filter(void*, SDL_Event *evt) - { - Display *display = LLWindowSDL::getSDLDisplay(); - if (!display) - return 1; - - if (evt->type != SDL_SYSWMEVENT) - return 1; - - auto xevent = evt->syswm.msg->msg.x11.event; - - if (xevent.type == SelectionRequest) - filterSelectionRequest( xevent ); - else if (xevent.type == SelectionClear) - filterSelectionClearRequest( xevent ); - return 1; - } - - bool grab_property(Display* display, Window window, Atom selection, Atom target) - { - if( !display ) - return false; - - maybe_lock_display(); - - XDeleteProperty(display, window, PVT_PASTE_BUFFER); - XFlush(display); - - XConvertSelection(display, selection, target, PVT_PASTE_BUFFER, window, CurrentTime); - - // Unlock the connection so that the SDL event loop may function - maybe_unlock_display(); - - const auto start{ SDL_GetTicks() }; - const auto end{ start + 1000 }; - - XEvent xevent {}; - bool response = false; - - do - { - SDL_Event event {}; - - // Wait for an event - SDL_WaitEvent(&event); - - // If the event is a window manager event - if (event.type == SDL_SYSWMEVENT) - { - xevent = event.syswm.msg->msg.x11.event; - - if (xevent.type == SelectionNotify && xevent.xselection.requestor == window) - response = true; - } - } while (!response && SDL_GetTicks() < end ); - - return response && xevent.xselection.property != None; - } -} - -void LLWindowSDL::initialiseX11Clipboard() -{ - if (!mSDL_Display) - return; - - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - SDL_SetEventFilter(x11_clipboard_filter, nullptr); - - maybe_lock_display(); - - XA_CLIPBOARD = XInternAtom(mSDL_Display, "CLIPBOARD", False); - - gSupportedAtoms[0] = XInternAtom(mSDL_Display, "UTF8_STRING", False); - gSupportedAtoms[1] = XInternAtom(mSDL_Display, "COMPOUND_TEXT", False); - gSupportedAtoms[2] = XA_STRING; - - // TARGETS atom - XA_TARGETS = XInternAtom(mSDL_Display, "TARGETS", False); - - // SL_PASTE_BUFFER atom - PVT_PASTE_BUFFER = XInternAtom(mSDL_Display, "FS_PASTE_BUFFER", False); - - maybe_unlock_display(); -} - -bool LLWindowSDL::getSelectionText( Atom aSelection, Atom aType, LLWString &text ) -{ - if( !mSDL_Display ) - return false; - - if( !grab_property(mSDL_Display, mSDL_XWindowID, aSelection,aType ) ) - return false; - - maybe_lock_display(); - - Atom type; - int format{}; - unsigned long len{},remaining {}; - unsigned char* data = nullptr; - int res = XGetWindowProperty(mSDL_Display, mSDL_XWindowID, - PVT_PASTE_BUFFER, 0, MAX_PASTE_BUFFER_SIZE, False, - AnyPropertyType, &type, &format, &len, - &remaining, &data); - if (data && len) - { - text = LLWString( - utf8str_to_wstring(reinterpret_cast< char const *>( data ) ) - ); - XFree(data); - } - - maybe_unlock_display(); - return res == Success; -} - -bool LLWindowSDL::getSelectionText(Atom selection, LLWString& text) -{ - if (!mSDL_Display) - return false; - - maybe_lock_display(); - - Window owner = XGetSelectionOwner(mSDL_Display, selection); - if (owner == None) - { - if (selection == XA_PRIMARY) - { - owner = DefaultRootWindow(mSDL_Display); - selection = XA_CUT_BUFFER0; - } - else - { - maybe_unlock_display(); - return false; - } - } - - maybe_unlock_display(); - - for( Atom atom : gSupportedAtoms ) - { - if(getSelectionText(selection, atom, text ) ) - return true; - } - - return false; -} - -bool LLWindowSDL::setSelectionText(Atom selection, const LLWString& text) -{ - maybe_lock_display(); - - if (selection == XA_PRIMARY) - { - std::string utf8 = wstring_to_utf8str(text); - XStoreBytes(mSDL_Display, utf8.c_str(), utf8.length() + 1); - mPrimaryClipboard = text; - } - else - mSecondaryClipboard = text; - - XSetSelectionOwner(mSDL_Display, selection, mSDL_XWindowID, CurrentTime); - - auto owner = XGetSelectionOwner(mSDL_Display, selection); - - maybe_unlock_display(); - - return owner == mSDL_XWindowID; -} - -Display* LLWindowSDL::getSDLDisplay() -{ - if (gWindowImplementation) - return gWindowImplementation->mSDL_Display; - return nullptr; -} - -#endif - - LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, - const std::string& title, S32 x, S32 y, S32 width, + const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, bool fullscreen, bool clearBg, - bool disable_vsync, bool use_gl, + bool enable_vsync, bool use_gl, bool ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags), Lock_Display(NULL), - //Unlock_Display(NULL), mGamma(1.0f) Unlock_Display(NULL), mGamma(1.0f) { // Initialize the keyboard @@ -427,19 +181,19 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, #if LL_X11 mSDL_XWindowID = None; - mSDL_Display = NULL; + mSDL_Display = nullptr; #endif // LL_X11 // Assume 4:3 aspect ratio until we know better mOriginalAspectRatio = 1024.0 / 768.0; if (title.empty()) - mWindowTitle = "SDL Window"; // *FIX: (?) + mWindowTitle = "Second Life"; else mWindowTitle = title; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, enable_vsync)) { gGLManager.initGL(); @@ -453,10 +207,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, // Stash an object pointer for OSMessageBox() gWindowImplementation = this; -#if LL_X11 mFlashing = false; - initialiseX11Clipboard(); -#endif // LL_X11 mKeyVirtualKey = 0; mKeyModifiers = KMOD_NONE; @@ -478,145 +229,6 @@ static SDL_Surface *Load_BMP_Resource(const char *basename) return SDL_LoadBMP(path_buffer); } -#if LL_X11 -// This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM -// on this machine. It works by searching /var/log/var/log/Xorg.?.log or -// /var/log/XFree86.?.log for a ': (VideoRAM ?|Memory): (%d+) kB' regex, where -// '?' is the X11 display number derived from $DISPLAY -static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str) -{ - const int line_buf_size = 1000; - char line_buf[line_buf_size]; - while (fgets(line_buf, line_buf_size, fp)) - { - //LL_DEBUGS() << "XLOG: " << line_buf << LL_ENDL; - - // Why the ad-hoc parser instead of using a regex? Our - // favourite regex implementation - libboost_regex - is - // quite a heavy and troublesome dependency for the client, so - // it seems a shame to introduce it for such a simple task. - // *FIXME: libboost_regex is a dependency now anyway, so we may - // as well use it instead of this hand-rolled nonsense. - const char *part1_template = prefix_str; - const char part2_template[] = " kB"; - char *part1 = strstr(line_buf, part1_template); - if (part1) // found start of matching line - { - part1 = &part1[strlen(part1_template)]; // -> after - char *part2 = strstr(part1, part2_template); - if (part2) // found end of matching line - { - // now everything between part1 and part2 is - // supposed to be numeric, describing the - // number of kB of Video RAM supported - int rtn = 0; - for (; part1 < part2; ++part1) - { - if (*part1 < '0' || *part1 > '9') - { - // unexpected char, abort parse - rtn = 0; - break; - } - rtn *= 10; - rtn += (*part1) - '0'; - } - if (rtn > 0) - { - // got the kB number. return it now. - return rtn; - } - } - } - } - return 0; // 'could not detect' -} - -static int x11_detect_VRAM_kb() -{ - std::string x_log_location("/var/log/"); - std::string fname; - int rtn = 0; // 'could not detect' - int display_num = 0; - FILE *fp; - char *display_env = getenv("DISPLAY"); // e.g. :0 or :0.0 or :1.0 etc - // parse DISPLAY number so we can go grab the right log file - if (display_env[0] == ':' && - display_env[1] >= '0' && display_env[1] <= '9') - { - display_num = display_env[1] - '0'; - } - - // *TODO: we could be smarter and see which of Xorg/XFree86 has the - // freshest time-stamp. - - // Try Xorg log first - fname = x_log_location; - fname += "Xorg."; - fname += ('0' + display_num); - fname += ".log"; - fp = fopen(fname.c_str(), "r"); - if (fp) - { - LL_INFOS() << "Looking in " << fname - << " for VRAM info..." << LL_ENDL; - rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); - fclose(fp); - if (0 == rtn) - { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Video RAM: "); - fclose(fp); - if (0 == rtn) - { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); - fclose(fp); - } - } - } - } - } - else - { - LL_INFOS() << "Could not open " << fname - << " - skipped." << LL_ENDL; - // Try old XFree86 log otherwise - fname = x_log_location; - fname += "XFree86."; - fname += ('0' + display_num); - fname += ".log"; - fp = fopen(fname.c_str(), "r"); - if (fp) - { - LL_INFOS() << "Looking in " << fname - << " for VRAM info..." << LL_ENDL; - rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); - fclose(fp); - if (0 == rtn) - { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); - fclose(fp); - } - } - } - else - { - LL_INFOS() << "Could not open " << fname - << " - skipped." << LL_ENDL; - } - } - return rtn; -} -#endif // LL_X11 - void LLWindowSDL::setTitle(const std::string title) { SDL_SetWindowTitle( mWindow, title.c_str() ); @@ -675,7 +287,7 @@ void LLWindowSDL::tryFindFullscreenSize( int &width, int &height ) } } -bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync) +bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync) { //bool glneedsinit = false; @@ -734,6 +346,10 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b width = 1024; if (height == 0) width = 768; + if (x == 0) + x = SDL_WINDOWPOS_UNDEFINED; + if (y == 0) + y = SDL_WINDOWPOS_UNDEFINED; mFullscreen = fullscreen; @@ -749,23 +365,16 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b mSDLFlags = sdlflags; + // Setup default backing colors GLint redBits{8}, greenBits{8}, blueBits{8}, alphaBits{8}; + GLint depthBits{24}, stencilBits{8}; - GLint depthBits{(bits <= 16) ? 16 : 24}, stencilBits{8}; - - if (getenv("LL_GL_NO_STENCIL")) - stencilBits = 0; - - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, redBits); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, greenBits); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, blueBits); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits ); - - // We need stencil support for a few (minor) things. - if (stencilBits) - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits); - // *FIX: try to toggle vsync here? + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); #if LL_DARWIN @@ -777,30 +386,40 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (mFSAASamples > 0) + U32 context_flags = 0; + if (gDebugGL) { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); + context_flags |= SDL_GL_CONTEXT_DEBUG_FLAG; } - + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, context_flags); SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); - mWindow = SDL_CreateWindow( mWindowTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, mSDLFlags ); - if( mWindow ) + // Create the window + mWindow = SDL_CreateWindow(mWindowTitle.c_str(), x, y, width, height, mSDLFlags); + if (mWindow == nullptr) { - mContext = SDL_GL_CreateContext( mWindow ); + LL_WARNS() << "Window creation failure. SDL: " << SDL_GetError() << LL_ENDL; + setupFailure("Window creation error", "Error", OSMB_OK); + return false; + } - if( mContext == 0 ) - { - LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; - setupFailure("GL Context creation error creation error", "Error", OSMB_OK); - return false; - } - // SDL_GL_SetSwapInterval(1); + // Create the context + mContext = SDL_GL_CreateContext(mWindow); + if(!mContext) + { + LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; + setupFailure("GL Context creation error", "Error", OSMB_OK); + return false; } + if (SDL_GL_MakeCurrent(mWindow, mContext) != 0) + { + LL_WARNS() << "Failed to make context current. SDL: " << SDL_GetError() << LL_ENDL; + setupFailure("GL Context failed to set current failure", "Error", OSMB_OK); + return false; + } - if( mFullscreen ) + if(mFullscreen) { if (mWindow) { @@ -844,70 +463,6 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b } } - // Set the application icon. - SDL_Surface *bmpsurface; - bmpsurface = Load_BMP_Resource("ll_icon.BMP"); - if (bmpsurface) - { - SDL_SetWindowIcon(mWindow, bmpsurface); - SDL_FreeSurface(bmpsurface); - bmpsurface = NULL; - } - - // Detect video memory size. -# if LL_X11 - gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; - if (gGLManager.mVRAM != 0) - { - LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; - } else - { - PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger; - queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) - glXGetProcAddressARB((const GLubyte *)"glXQueryCurrentRendererIntegerMESA"); - unsigned int vram_megabytes = 0; - queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_megabytes); - if (!vram_megabytes) { - glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, (int *)&vram_megabytes); - vram_megabytes /= 1024; - } - if (!vram_megabytes) { - glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, (int *)&vram_megabytes); - vram_megabytes /= 1024; - } - gGLManager.mVRAM = vram_megabytes; - } -#elif LL_DARWIN - CGLRendererInfoObj info = 0; - GLint vram_megabytes = 0; - int num_renderers = 0; - auto err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), - &info, &num_renderers); - if (!err) { - CGLDescribeRenderer(info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); - CGLDestroyRendererInfo(info); - } else - vram_megabytes = 256; - gGLManager.mVRAM = vram_megabytes; -# endif // LL_X11 -/* - { - // fallback to letting SDL detect VRAM. - // note: I've not seen SDL's detection ever actually find - // VRAM != 0, but if SDL *does* detect it then that's a bonus. - gGLManager.mVRAM = 0; - if (gGLManager.mVRAM != 0) - { - LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; - } - } -*/ - // If VRAM is not detected, that is handled later - - // *TODO: Now would be an appropriate time to check for some - // explicitly unsupported cards. - //const char* RENDERER = (const char*) glGetString(GL_RENDERER); - SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits); @@ -943,6 +498,20 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b #endif } + LL_PROFILER_GPU_CONTEXT; + + // Enable vertical sync + toggleVSync(enable_vsync); + + // Set the application icon. + SDL_Surface* bmpsurface = Load_BMP_Resource("ll_icon.BMP"); + if (bmpsurface) + { + SDL_SetWindowIcon(mWindow, bmpsurface); + SDL_FreeSurface(bmpsurface); + bmpsurface = NULL; + } + #if LL_X11 /* Grab the window manager specific information */ SDL_SysWMinfo info; @@ -968,7 +537,38 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b } #endif // LL_X11 - +# if LL_X11 + PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger; + queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXQueryCurrentRendererIntegerMESA"); + unsigned int vram_megabytes = 0; + queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_megabytes); + if (!vram_megabytes) + { + glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, (int *)&vram_megabytes); + vram_megabytes /= 1024; + } + if (!vram_megabytes) + { + glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, (int *)&vram_megabytes); + vram_megabytes /= 1024; + } + gGLManager.mVRAM = vram_megabytes; +#elif LL_DARWIN + CGLRendererInfoObj info = 0; + GLint vram_megabytes = 0; + int num_renderers = 0; + auto err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers); + if (!err) + { + CGLDescribeRenderer(info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); + CGLDestroyRendererInfo(info); + } + else + { + vram_megabytes = 256; + } + gGLManager.mVRAM = vram_megabytes; +# endif SDL_StartTextInput(); //make sure multisampling is disabled by default #if GL_VERSION_1_3 @@ -979,9 +579,48 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b return true; } +void* LLWindowSDL::createSharedContext() +{ + SDL_GLContext pContext = SDL_GL_CreateContext(mWindow); + if (pContext) + { + LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; + return (void*)pContext; + } + + LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; + return nullptr; +} + +void LLWindowSDL::makeContextCurrent(void* contextPtr) +{ + SDL_GL_MakeCurrent(mWindow, contextPtr); + LL_PROFILER_GPU_CONTEXT; +} + +void LLWindowSDL::destroySharedContext(void* contextPtr) +{ + SDL_GL_DeleteContext(contextPtr); +} + +void LLWindowSDL::toggleVSync(bool enable_vsync) +{ + if (!enable_vsync) + { + LL_INFOS("Window") << "Disabling vertical sync" << LL_ENDL; + SDL_GL_SetSwapInterval(0); + SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"0",SDL_HINT_OVERRIDE); + } + else + { + LL_INFOS("Window") << "Enabling vertical sync" << LL_ENDL; + SDL_GL_SetSwapInterval(1); + SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"1",SDL_HINT_OVERRIDE); + } +} // changing fullscreen resolution, or switching between windowed and fullscreen mode. -bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp) +bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, const LLCoordScreen * const posp) { const bool needsRebuild = true; // Just nuke the context and start over. bool result = true; @@ -991,7 +630,7 @@ bool LLWindowSDL::switchContext(bool fullscreen, const LLCoordScreen &size, bool if(needsRebuild) { destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); + result = createContext(0, 0, size.mX, size.mY, 32, fullscreen, enable_vsync); if (result) { gGLManager.initGL(); @@ -1011,7 +650,13 @@ void LLWindowSDL::destroyContext() { LL_INFOS() << "destroyContext begins" << LL_ENDL; + // Stop unicode input SDL_StopTextInput(); + + // Clean up remaining GL state before blowing away window + LL_INFOS() << "shutdownGL begins" << LL_ENDL; + gGLManager.shutdownGL(); + #if LL_X11 mSDL_Display = NULL; mSDL_XWindowID = None; @@ -1019,18 +664,38 @@ void LLWindowSDL::destroyContext() Unlock_Display = NULL; #endif // LL_X11 - // Clean up remaining GL state before blowing away window - LL_INFOS() << "shutdownGL begins" << LL_ENDL; - gGLManager.shutdownGL(); + LL_INFOS() << "Destroying SDL cursors" << LL_ENDL; + quitCursors(); + + if (mContext) + { + LL_INFOS() << "Destroying SDL GL Context" << LL_ENDL; + SDL_GL_DeleteContext(mContext); + mContext = nullptr; + } + else + { + LL_INFOS() << "SDL GL Context already destroyed" << LL_ENDL; + } + + if (mWindow) + { + LL_INFOS() << "Destroying SDL Window" << LL_ENDL; + SDL_DestroyWindow(mWindow); + mWindow = nullptr; + } + else + { + LL_INFOS() << "SDL Window already destroyed" << LL_ENDL; + } + LL_INFOS() << "destroyContext end" << LL_ENDL; + LL_INFOS() << "SDL_QuitSS/VID begins" << LL_ENDL; SDL_QuitSubSystem(SDL_INIT_VIDEO); // *FIX: this might be risky... - - mWindow = NULL; } LLWindowSDL::~LLWindowSDL() { - quitCursors(); destroyContext(); if(mSupportedResolutions != NULL) @@ -1044,7 +709,6 @@ LLWindowSDL::~LLWindowSDL() void LLWindowSDL::show() { - // *FIX: What to do with SDL? if (mWindow) { SDL_ShowWindow(mWindow); @@ -1053,7 +717,6 @@ void LLWindowSDL::show() void LLWindowSDL::hide() { - // *FIX: What to do with SDL? if (mWindow) { SDL_HideWindow(mWindow); @@ -1063,7 +726,6 @@ void LLWindowSDL::hide() //virtual void LLWindowSDL::minimize() { - // *FIX: What to do with SDL? if (mWindow) { SDL_MinimizeWindow(mWindow); @@ -1073,14 +735,12 @@ void LLWindowSDL::minimize() //virtual void LLWindowSDL::restore() { - // *FIX: What to do with SDL? if (mWindow) { SDL_RestoreWindow(mWindow); } } - // close() destroys all OS-specific code associated with a window. // Usually called from LLWindowManager::destroyWindow() void LLWindowSDL::close() @@ -1106,56 +766,54 @@ bool LLWindowSDL::isValid() bool LLWindowSDL::getVisible() { bool result = false; - - // *FIX: This isn't really right... - // Then what is? if (mWindow) { - if( SDL_GetWindowFlags(mWindow) & SDL_WINDOW_SHOWN ) result = true; + Uint32 flags = SDL_GetWindowFlags(mWindow); + if (flags & SDL_WINDOW_SHOWN) + { + result = true; + } } - - return(result); + return result; } bool LLWindowSDL::getMinimized() { bool result = false; - - if (mWindow/*&& (1 == mIsMinimized)*/) + if (mWindow) { - if( SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MINIMIZED ) result = true; + Uint32 flags = SDL_GetWindowFlags(mWindow); + if (flags & SDL_WINDOW_MINIMIZED) + { + result = true; + } } - - mIsMinimized = result; - return(result); + return result; } bool LLWindowSDL::getMaximized() { bool result = false; - if (mWindow) { - // TODO - if( SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED ) result = true; - else result = false; + Uint32 flags = SDL_GetWindowFlags(mWindow); + if (flags & SDL_WINDOW_MAXIMIZED) + { + result = true; + } } - return(result); + return result; } bool LLWindowSDL::maximize() { - // TODO - bool result = false; - if (mWindow) { SDL_MaximizeWindow(mWindow); - result = true; + return true; } - - return result; + return false; } bool LLWindowSDL::getFullscreen() @@ -1165,10 +823,12 @@ bool LLWindowSDL::getFullscreen() bool LLWindowSDL::getPosition(LLCoordScreen *position) { - // *FIX: can anything be done with this? - position->mX = 0; - position->mY = 0; - return true; + if (mWindow) + { + SDL_GetWindowPosition(mWindow, &position->mX, &position->mY); + return true; + } + return false; } bool LLWindowSDL::getSize(LLCoordScreen *size) @@ -1203,17 +863,13 @@ bool LLWindowSDL::getSize(LLCoordWindow *size) bool LLWindowSDL::setPosition(const LLCoordScreen position) { - bool result = false; - - if(mWindow) + if (mWindow) { - // *FIX: (?) - //MacMoveWindow(mWindow, position.mX, position.mY, false); SDL_SetWindowPosition(mWindow, position.mX, position.mY); - result = true; + return true; } - return result; + return false; } template< typename T > bool setSizeImpl( const T& newSize, SDL_Window *pWin ) @@ -1254,8 +910,9 @@ void LLWindowSDL::swapBuffers() { if (mWindow) { - SDL_GL_SwapWindow( mWindow ); + SDL_GL_SwapWindow(mWindow); } + LL_PROFILER_GPU_COLLECT; } U32 LLWindowSDL::getFSAASamples() @@ -1270,28 +927,33 @@ void LLWindowSDL::setFSAASamples(const U32 samples) F32 LLWindowSDL::getGamma() { - return 1/mGamma; + return 1.f / mGamma; } bool LLWindowSDL::restoreGamma() { - //CGDisplayRestoreColorSyncSettings(); - // SDL_SetGamma(1.0f, 1.0f, 1.0f); - Uint16 ramp; - SDL_CalculateGammaRamp(1.0f, &ramp); - SDL_SetWindowGammaRamp(mWindow, &ramp, &ramp, &ramp); + if (mWindow) + { + Uint16 ramp[256]; + SDL_CalculateGammaRamp(1.f, ramp); + SDL_SetWindowGammaRamp(mWindow, ramp, ramp, ramp); + } return true; } bool LLWindowSDL::setGamma(const F32 gamma) { - mGamma = gamma; - if (mGamma == 0) mGamma = 0.1f; - mGamma = 1/mGamma; - // SDL_SetGamma(mGamma, mGamma, mGamma); - Uint16 ramp; - SDL_CalculateGammaRamp(mGamma, &ramp); - SDL_SetWindowGammaRamp(mWindow, &ramp, &ramp, &ramp); + if (mWindow) + { + Uint16 ramp[256]; + + mGamma = gamma; + if (mGamma == 0) mGamma = 0.1f; + mGamma = 1.f / mGamma; + + SDL_CalculateGammaRamp(mGamma, ramp); + SDL_SetWindowGammaRamp(mWindow, ramp, ramp, ramp); + } return true; } @@ -1300,10 +962,8 @@ bool LLWindowSDL::isCursorHidden() return mCursorHidden; } - - // Constrains the mouse to the window. -void LLWindowSDL::setMouseClipping( bool b ) +void LLWindowSDL::setMouseClipping(bool b) { //SDL_WM_GrabInput(b ? SDL_GRAB_ON : SDL_GRAB_OFF); } @@ -1313,18 +973,10 @@ void LLWindowSDL::setMinSize(U32 min_width, U32 min_height, bool enforce_immedia { LLWindow::setMinSize(min_width, min_height, enforce_immediately); -#if LL_X11 - // Set the minimum size limits for X11 window - // so the window manager doesn't allow resizing below those limits. - XSizeHints* hints = XAllocSizeHints(); - hints->flags |= PMinSize; - hints->min_width = mMinWindowWidth; - hints->min_height = mMinWindowHeight; - - XSetWMNormalHints(mSDL_Display, mSDL_XWindowID, hints); - - XFree(hints); -#endif + if (mWindow && min_width > 0 && min_height > 0) + { + SDL_SetWindowMinimumSize(mWindow, mMinWindowWidth, mMinWindowHeight); + } } bool LLWindowSDL::setCursorPosition(const LLCoordWindow position) @@ -1359,7 +1011,6 @@ bool LLWindowSDL::getCursorPosition(LLCoordWindow *position) //Point cursor_point; LLCoordScreen screen_pos; - //GetMouse(&cursor_point); int x, y; SDL_GetMouseState(&x, &y); @@ -1479,116 +1130,70 @@ void LLWindowSDL::afterDialog() } } - -#if LL_X11 -// set/reset the XWMHints flag for 'urgency' that usually makes the icon flash -void LLWindowSDL::x11_set_urgent(bool urgent) -{ - if (mSDL_Display && !mFullscreen) - { - XWMHints *wm_hints; - - LL_INFOS() << "X11 hint for urgency, " << urgent << LL_ENDL; - - maybe_lock_display(); - wm_hints = XGetWMHints(mSDL_Display, mSDL_XWindowID); - if (!wm_hints) - wm_hints = XAllocWMHints(); - - if (urgent) - wm_hints->flags |= XUrgencyHint; - else - wm_hints->flags &= ~XUrgencyHint; - - XSetWMHints(mSDL_Display, mSDL_XWindowID, wm_hints); - XFree(wm_hints); - XSync(mSDL_Display, False); - maybe_unlock_display(); - } -} -#endif // LL_X11 - void LLWindowSDL::flashIcon(F32 seconds) { - if (getMinimized()) - { -#if !LL_X11 - LL_INFOS() << "Stub LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; -#else - LL_INFOS() << "X11 LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; + LL_INFOS() << "LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; - F32 remaining_time = mFlashTimer.getRemainingTimeF32(); - if (remaining_time < seconds) - remaining_time = seconds; - mFlashTimer.reset(); - mFlashTimer.setTimerExpirySec(remaining_time); + F32 remaining_time = mFlashTimer.getRemainingTimeF32(); + if (remaining_time < seconds) + remaining_time = seconds; + mFlashTimer.reset(); + mFlashTimer.setTimerExpirySec(remaining_time); - x11_set_urgent(true); - mFlashing = true; -#endif // LL_X11 - } + SDL_FlashWindow(mWindow, SDL_FLASH_UNTIL_FOCUSED); + mFlashing = true; } bool LLWindowSDL::isClipboardTextAvailable() { -#if LL_X11 - return mSDL_Display && XGetSelectionOwner(mSDL_Display, XA_CLIPBOARD) != None; -#else - return SDL_HasClipboardText(); -#endif + return SDL_HasClipboardText() == SDL_TRUE; } bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst) { -#if LL_X11 - return getSelectionText(XA_CLIPBOARD, dst); -#else - auto data = SDL_GetClipboardText(); - if (data) + if (isClipboardTextAvailable()) { - dst = LLWString(utf8str_to_wstring(data)); - SDL_free(data); - return true; + char* data = SDL_GetClipboardText(); + if (data) + { + dst = LLWString(utf8str_to_wstring(data)); + SDL_free(data); + return true; + } } return false; -#endif } -bool LLWindowSDL::copyTextToClipboard(const LLWString &s) +bool LLWindowSDL::copyTextToClipboard(const LLWString& text) { -#if LL_X11 - return setSelectionText(XA_CLIPBOARD, s); -#else - return !SDL_SetClipboardText(wstring_to_utf8str(s).c_str()); -#endif + const std::string utf8 = wstring_to_utf8str(text); + return SDL_SetClipboardText(utf8.c_str()) == 0; // success == 0 } bool LLWindowSDL::isPrimaryTextAvailable() { -#if LL_X11 - LLWString text; - return getSelectionText(XA_PRIMARY, text) && !text.empty(); -#else - return false; // unsupported -#endif + return SDL_HasPrimarySelectionText() == SDL_TRUE; } bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst) { -#if LL_X11 - return getSelectionText(XA_PRIMARY, dst); -#else - return false; // unsupported -#endif + if (isPrimaryTextAvailable()) + { + char* data = SDL_GetPrimarySelectionText(); + if (data) + { + dst = LLWString(utf8str_to_wstring(data)); + SDL_free(data); + return true; + } + } + return false; } -bool LLWindowSDL::copyTextToPrimary(const LLWString &s) +bool LLWindowSDL::copyTextToPrimary(const LLWString& text) { -#if LL_X11 - return setSelectionText(XA_PRIMARY, s); -#else - return false; // unsupported -#endif + const std::string utf8 = wstring_to_utf8str(text); + return SDL_SetPrimarySelectionText(utf8.c_str()) == 0; // success == 0 } LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions) @@ -1693,9 +1298,6 @@ bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordScreen *to) return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); } - - - void LLWindowSDL::setupFailure(const std::string& text, const std::string& caption, U32 type) { destroyContext(); @@ -1730,47 +1332,24 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture) bool newGrab = wantGrab; -#if LL_X11 if (!mFullscreen) /* only bother if we're windowed anyway */ { - if (mSDL_Display) + int result; + if (wantGrab == true) { - /* we dirtily mix raw X11 with SDL so that our pointer - isn't (as often) constrained to the limits of the - window while grabbed, which feels nicer and - hopefully eliminates some reported 'sticky pointer' - problems. We use raw X11 instead of - SDL_WM_GrabInput() because the latter constrains - the pointer to the window and also steals all - *keyboard* input from the window manager, which was - frustrating users. */ - int result; - if (wantGrab == true) - { - maybe_lock_display(); - result = XGrabPointer(mSDL_Display, mSDL_XWindowID, - True, 0, GrabModeAsync, - GrabModeAsync, - None, None, CurrentTime); - maybe_unlock_display(); - if (GrabSuccess == result) - newGrab = true; - else - newGrab = false; - } + result = SDL_CaptureMouse(SDL_TRUE); + if (0 == result) + newGrab = true; else - { newGrab = false; - - maybe_lock_display(); - XUngrabPointer(mSDL_Display, CurrentTime); - // Make sure the ungrab happens RIGHT NOW. - XSync(mSDL_Display, False); - maybe_unlock_display(); - } + } + else + { + newGrab = false; + result = SDL_CaptureMouse(SDL_FALSE); } } -#endif // LL_X11 + // return boolean success for whether we ended up in the desired state return capture == newGrab; } @@ -1900,7 +1479,7 @@ void check_vm_bloat() last_rss_size = this_rss_size; last_vm_size = this_vm_size; - finally: +finally: if (NULL != ptr) { free(ptr); @@ -1936,11 +1515,6 @@ void LLWindowSDL::processMiscNativeEvents() void LLWindowSDL::gatherInput() { - const Uint32 CLICK_THRESHOLD = 300; // milliseconds - static int leftClick = 0; - static int rightClick = 0; - static Uint32 lastLeftDown = 0; - static Uint32 lastRightDown = 0; SDL_Event event; // Handle all outstanding SDL events @@ -1949,13 +1523,21 @@ void LLWindowSDL::gatherInput() switch (event.type) { case SDL_MOUSEWHEEL: + { if( event.wheel.y != 0 ) + { mCallbacks->handleScrollWheel(this, -event.wheel.y); + } + if (event.wheel.x != 0) + { + mCallbacks->handleScrollHWheel(this, -event.wheel.x); + } break; + } case SDL_MOUSEMOTION: { - LLCoordWindow winCoord(event.button.x, event.button.y); + LLCoordWindow winCoord(event.motion.x, event.motion.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); @@ -2034,7 +1616,6 @@ void LLWindowSDL::gatherInput() case SDL_MOUSEBUTTONDOWN: { - bool isDoubleClick = false; LLCoordWindow winCoord(event.button.x, event.button.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); @@ -2044,58 +1625,25 @@ void LLWindowSDL::gatherInput() MASK mask = gKeyboard->currentMask(true); - if (event.button.button == SDL_BUTTON_LEFT) // SDL doesn't manage double clicking... - { - Uint32 now = SDL_GetTicks(); - if ((now - lastLeftDown) > CLICK_THRESHOLD) - leftClick = 1; - else - { - if (++leftClick >= 2) - { - leftClick = 0; - isDoubleClick = true; - } - } - lastLeftDown = now; - } - else if (event.button.button == SDL_BUTTON_RIGHT) - { - Uint32 now = SDL_GetTicks(); - if ((now - lastRightDown) > CLICK_THRESHOLD) - rightClick = 1; - else - { - if (++rightClick >= 2) - { - rightClick = 0; - isDoubleClick = true; - } - } - lastRightDown = now; - } - if (event.button.button == SDL_BUTTON_LEFT) // left { - if (isDoubleClick) + if (event.button.clicks >= 2) mCallbacks->handleDoubleClick(this, openGlCoord, mask); else mCallbacks->handleMouseDown(this, openGlCoord, mask); } - else if (event.button.button == SDL_BUTTON_RIGHT) // right { mCallbacks->handleRightMouseDown(this, openGlCoord, mask); } - else if (event.button.button == SDL_BUTTON_MIDDLE) // middle { mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask); } - else if (event.button.button == 4) // mousewheel up...thanks to X11 for making SDL consider these "buttons". - mCallbacks->handleScrollWheel(this, -1); - else if (event.button.button == 5) // mousewheel down...thanks to X11 for making SDL consider these "buttons". - mCallbacks->handleScrollWheel(this, 1); + else + { + mCallbacks->handleOtherMouseDown(this, openGlCoord, mask, event.button.button); + } break; } @@ -2112,99 +1660,64 @@ void LLWindowSDL::gatherInput() MASK mask = gKeyboard->currentMask(true); if (event.button.button == SDL_BUTTON_LEFT) // left - mCallbacks->handleMouseUp(this, openGlCoord, mask); - else if (event.button.button == SDL_BUTTON_RIGHT) // right - mCallbacks->handleRightMouseUp(this, openGlCoord, mask); - else if (event.button.button == SDL_BUTTON_MIDDLE) // middle - mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); - // don't handle mousewheel here... - - break; - } - - case SDL_WINDOWEVENT: // *FIX: handle this? - { - if( event.window.event == SDL_WINDOWEVENT_RESIZED - /* || event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED*/ ) // <FS:ND> SDL_WINDOWEVENT_SIZE_CHANGED is followed by SDL_WINDOWEVENT_RESIZED, so handling one shall be enough { - LL_INFOS() << "Handling a resize event: " << event.window.data1 << "x" << event.window.data2 << LL_ENDL; - - S32 width = llmax(event.window.data1, (S32)mMinWindowWidth); - S32 height = llmax(event.window.data2, (S32)mMinWindowHeight); - - // *FIX: I'm not sure this is necessary! - // <FS:ND> I think is is not - // SDL_SetWindowSize(mWindow, width, height); - // - - mCallbacks->handleResize(this, width * getSystemUISize(), height * getSystemUISize()); - } - else if(event.window.event == SDL_WINDOWEVENT_ENTER) - { - LL_INFOS() << "SDL_WINDOWEVENT_ENTER" << LL_ENDL; - if(!mHaveInputFocus) mCallbacks->handleFocus(this); - mHaveInputFocus = true; + mCallbacks->handleMouseUp(this, openGlCoord, mask); } - else if(event.window.event == SDL_WINDOWEVENT_LEAVE) + else if (event.button.button == SDL_BUTTON_RIGHT) // right { - LL_INFOS() << "SDL_WINDOWEVENT_LEAVE" << LL_ENDL; - if(mHaveInputFocus) mCallbacks->handleFocusLost(this); - mHaveInputFocus = false; + mCallbacks->handleRightMouseUp(this, openGlCoord, mask); } - else if( event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED ) // <FS:ND> What about SDL_WINDOWEVENT_ENTER (mouse focus) + else if (event.button.button == SDL_BUTTON_MIDDLE) // middle { - // We have to do our own state massaging because SDL - // can send us two unfocus events in a row for example, - // which confuses the focus code [SL-24071]. - mHaveInputFocus = true; - - mCallbacks->handleFocus(this); + mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); } - else if( event.window.event == SDL_WINDOWEVENT_FOCUS_LOST ) // <FS:ND> What about SDL_WINDOWEVENT_LEAVE (mouse focus) + else { - // We have to do our own state massaging because SDL - // can send us two unfocus events in a row for example, - // which confuses the focus code [SL-24071]. - mHaveInputFocus = false; - - mCallbacks->handleFocusLost(this); + mCallbacks->handleOtherMouseUp(this, openGlCoord, mask, event.button.button); } - /* - Bug : the app remains inactive when maximized .. + break; + } - else if(event.window.event == SDL_WINDOWEVENT_MINIMIZED) - { - LL_INFOS() << "SDL_WINDOWEVENT_MINIMIZED" << LL_ENDL; - if(!mIsMinimized) mCallbacks->handleActivate(this,false); - mIsMinimized = true; - } - else if(event.window.event == SDL_WINDOWEVENT_MAXIMIZED) - { - LL_INFOS() << "SDL_WINDOWEVENT_MAXIMIZED" << LL_ENDL; - if(mIsMinimized) mCallbacks->handleActivate(this,true); - mIsMinimized = false; - } - */ - else if (event.window.event == SDL_WINDOWEVENT_EXPOSED) + case SDL_WINDOWEVENT: + { + switch(event.window.event) { - int w, h; - SDL_GL_GetDrawableSize(mWindow, &w, &h); + //case SDL_WINDOWEVENT_SIZE_CHANGED: <FS:ND> SDL_WINDOWEVENT_SIZE_CHANGED is followed by SDL_WINDOWEVENT_RESIZED, so handling one shall be enough + case SDL_WINDOWEVENT_RESIZED: + { + LL_INFOS() << "Handling a resize event: " << event.window.data1 << "x" << event.window.data2 << LL_ENDL; + S32 width = llmax(event.window.data1, (S32)mMinWindowWidth); + S32 height = llmax(event.window.data2, (S32)mMinWindowHeight); - mCallbacks->handlePaint(this, 0, 0, w, h); - } - else if( event.window.event == SDL_WINDOWEVENT_MINIMIZED || - event.window.event == SDL_WINDOWEVENT_MAXIMIZED || - event.window.event == SDL_WINDOWEVENT_RESTORED || - event.window.event == SDL_WINDOWEVENT_EXPOSED || - event.window.event == SDL_WINDOWEVENT_SHOWN ) - { - mIsMinimized = (event.window.event == SDL_WINDOWEVENT_MINIMIZED); + mCallbacks->handleResize(this, width * getSystemUISize(), height * getSystemUISize()); + break; + } + case SDL_WINDOWEVENT_LEAVE: + mCallbacks->handleMouseLeave(this); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + mCallbacks->handleFocus(this); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + mCallbacks->handleFocusLost(this); + break; + case SDL_WINDOWEVENT_EXPOSED: + case SDL_WINDOWEVENT_SHOWN: + case SDL_WINDOWEVENT_HIDDEN: + case SDL_WINDOWEVENT_MINIMIZED: + case SDL_WINDOWEVENT_MAXIMIZED: + case SDL_WINDOWEVENT_RESTORED: + { + Uint32 flags = SDL_GetWindowFlags(mWindow); + bool minimized = (flags & SDL_WINDOW_MINIMIZED); + bool hidden = (flags & SDL_WINDOW_HIDDEN); - mCallbacks->handleActivate(this, !mIsMinimized); - LL_INFOS() << "SDL deiconification state switched to " << mIsMinimized << LL_ENDL; + mCallbacks->handleActivate(this, !minimized || !hidden); + LL_INFOS() << "SDL deiconification state switched to " << minimized << LL_ENDL; + break; + } } - break; } case SDL_QUIT: @@ -2223,20 +1736,18 @@ void LLWindowSDL::gatherInput() updateCursor(); -#if LL_X11 // This is a good time to stop flashing the icon if our mFlashTimer has // expired. if (mFlashing && mFlashTimer.hasExpired()) { - x11_set_urgent(false); + SDL_FlashWindow(mWindow, SDL_FLASH_CANCEL); mFlashing = false; } -#endif // LL_X11 } static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty) { - SDL_Cursor *sdlcursor = NULL; + SDL_Cursor *sdlcursor = nullptr; SDL_Surface *bmpsurface; // Load cursor pixel data from BMP file @@ -2310,12 +1821,6 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty void LLWindowSDL::updateCursor() { - if (ATIbug) { - // cursor-updating is very flaky when this bug is - // present; do nothing. - return; - } - if (mCurrentCursor != mNextCursor) { if (mNextCursor < UI_CURSOR_COUNT) @@ -2327,10 +1832,13 @@ void LLWindowSDL::updateCursor() sdlcursor = mSDLCursors[UI_CURSOR_ARROW]; if (sdlcursor) SDL_SetCursor(sdlcursor); - } else { + + mCurrentCursor = mNextCursor; + } + else + { LL_WARNS() << "Tried to set invalid cursor number " << mNextCursor << LL_ENDL; } - mCurrentCursor = mNextCursor; } } @@ -2340,24 +1848,24 @@ void LLWindowSDL::initCursors() // Blank the cursor pointer array for those we may miss. for (i=0; i<UI_CURSOR_COUNT; ++i) { - mSDLCursors[i] = NULL; + mSDLCursors[i] = nullptr; } // Pre-make an SDL cursor for each of the known cursor types. // We hardcode the hotspots - to avoid that we'd have to write // a .cur file loader. // NOTE: SDL doesn't load RLE-compressed BMP files. - mSDLCursors[UI_CURSOR_ARROW] = makeSDLCursorFromBMP("llarrow.BMP",0,0); - mSDLCursors[UI_CURSOR_WAIT] = makeSDLCursorFromBMP("wait.BMP",12,15); - mSDLCursors[UI_CURSOR_HAND] = makeSDLCursorFromBMP("hand.BMP",7,10); - mSDLCursors[UI_CURSOR_IBEAM] = makeSDLCursorFromBMP("ibeam.BMP",15,16); - mSDLCursors[UI_CURSOR_CROSS] = makeSDLCursorFromBMP("cross.BMP",16,14); - mSDLCursors[UI_CURSOR_SIZENWSE] = makeSDLCursorFromBMP("sizenwse.BMP",14,17); - mSDLCursors[UI_CURSOR_SIZENESW] = makeSDLCursorFromBMP("sizenesw.BMP",17,17); - mSDLCursors[UI_CURSOR_SIZEWE] = makeSDLCursorFromBMP("sizewe.BMP",16,14); - mSDLCursors[UI_CURSOR_SIZENS] = makeSDLCursorFromBMP("sizens.BMP",17,16); - mSDLCursors[UI_CURSOR_SIZEALL] = makeSDLCursorFromBMP("sizeall.BMP", 17, 17); - mSDLCursors[UI_CURSOR_NO] = makeSDLCursorFromBMP("llno.BMP",8,8); - mSDLCursors[UI_CURSOR_WORKING] = makeSDLCursorFromBMP("working.BMP",12,15); + mSDLCursors[UI_CURSOR_ARROW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + mSDLCursors[UI_CURSOR_WAIT] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT); + mSDLCursors[UI_CURSOR_HAND] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + mSDLCursors[UI_CURSOR_IBEAM] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + mSDLCursors[UI_CURSOR_CROSS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR); + mSDLCursors[UI_CURSOR_SIZENWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + mSDLCursors[UI_CURSOR_SIZENESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + mSDLCursors[UI_CURSOR_SIZEWE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + mSDLCursors[UI_CURSOR_SIZENS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + mSDLCursors[UI_CURSOR_SIZEALL] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + mSDLCursors[UI_CURSOR_NO] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); + mSDLCursors[UI_CURSOR_WORKING] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAITARROW); mSDLCursors[UI_CURSOR_TOOLGRAB] = makeSDLCursorFromBMP("lltoolgrab.BMP",2,13); mSDLCursors[UI_CURSOR_TOOLLAND] = makeSDLCursorFromBMP("lltoolland.BMP",1,6); mSDLCursors[UI_CURSOR_TOOLFOCUS] = makeSDLCursorFromBMP("lltoolfocus.BMP",8,5); @@ -2390,11 +1898,6 @@ void LLWindowSDL::initCursors() mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END] = makeSDLCursorFromBMP("lltoolpathfindingpathend.BMP", 16, 16); mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathendadd.BMP", 16, 16); mSDLCursors[UI_CURSOR_TOOLNO] = makeSDLCursorFromBMP("llno.BMP",8,8); - - if (getenv("LL_ATI_MOUSE_CURSOR_BUG") != NULL) { - LL_INFOS() << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << LL_ENDL; - ATIbug = true; - } } void LLWindowSDL::quitCursors() @@ -2444,7 +1947,7 @@ void LLWindowSDL::hideCursor() // LL_INFOS() << "hideCursor: hiding" << LL_ENDL; mCursorHidden = true; mHideCursorPermanent = true; - SDL_ShowCursor(0); + SDL_ShowCursor(SDL_DISABLE); } else { @@ -2459,7 +1962,7 @@ void LLWindowSDL::showCursor() // LL_INFOS() << "showCursor: showing" << LL_ENDL; mCursorHidden = false; mHideCursorPermanent = false; - SDL_ShowCursor(1); + SDL_ShowCursor(SDL_ENABLE); } else { @@ -2598,62 +2101,6 @@ LLSD LLWindowSDL::getNativeKeyData() } #endif // LL_DARWIN -#if LL_LINUX || LL_SOLARIS || __FreeBSD__ -// extracted from spawnWebBrowser for clarity and to eliminate -// compiler confusion regarding close(int fd) vs. LLWindow::close() -void exec_cmd(const std::string& cmd, const std::string& arg) -{ - char* const argv[] = {(char*)cmd.c_str(), (char*)arg.c_str(), NULL}; - fflush(NULL); - pid_t pid = fork(); - if (pid == 0) - { // child - // disconnect from stdin/stdout/stderr, or child will - // keep our output pipe undesirably alive if it outlives us. - // close(0); - // close(1); - // close(2); - // <FS:TS> Reopen stdin, stdout, and stderr to /dev/null. - // It's good practice to always have those file - // descriptors open to something, lest the exec'd - // program actually try to use them. - FILE *result; - result = freopen("/dev/null","r",stdin); - if (result == NULL) - { - LL_WARNS() << "Error reopening stdin for web browser: " - << strerror(errno) << LL_ENDL; - } - result = freopen("/dev/null","w",stdout); - if (result == NULL) - { - LL_WARNS() << "Error reopening stdout for web browser: " - << strerror(errno) << LL_ENDL; - } - result = freopen("/dev/null","w",stderr); - if (result == NULL) - { - LL_WARNS() << "Error reopening stderr for web browser: " - << strerror(errno) << LL_ENDL; - } - // end ourself by running the command - execv(cmd.c_str(), argv); /* Flawfinder: ignore */ - // if execv returns at all, there was a problem. - LL_WARNS() << "execv failure when trying to start " << cmd << LL_ENDL; - _exit(1); // _exit because we don't want atexit() clean-up! - } else { - if (pid > 0) - { - // parent - wait for child to die - int childExitStatus; - waitpid(pid, &childExitStatus, 0); - } else { - LL_WARNS() << "fork failure." << LL_ENDL; - } - } -} -#endif - // Open a URL with the user's default web browser. // Must begin with protocol identifier. void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) @@ -2677,75 +2124,14 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL; -#if LL_LINUX || __FreeBSD__ -# if LL_X11 - if (mSDL_Display) + if (SDL_OpenURL(escaped_url.c_str()) != 0) { - maybe_lock_display(); - // Just in case - before forking. - XSync(mSDL_Display, False); - maybe_unlock_display(); + LL_WARNS() << "spawn_web_browser failed with error: " << SDL_GetError() << LL_ENDL; } -# endif // LL_X11 - - std::string cmd, arg; -#ifdef LL_USESYSTEMLIBS - cmd = gDirUtilp->getExecutableDir(); -#else - cmd = gDirUtilp->getAppRODataDir(); - cmd += gDirUtilp->getDirDelimiter(); - cmd += "etc"; -#endif - cmd += gDirUtilp->getDirDelimiter(); - cmd += "launch_url.sh"; - arg = escaped_url; - exec_cmd(cmd, arg); - -#elif LL_DARWIN - - S32 result = 0; - CFURLRef urlRef = NULL; - - LL_INFOS() << "Opening URL " << escaped_url << LL_ENDL; - - CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url.c_str(), kCFStringEncodingUTF8); - if (stringRef) - { - // This will succeed if the string is a full URL, including the http:// - // Note that URLs specified this way need to be properly percent-escaped. - urlRef = CFURLCreateWithString(NULL, stringRef, NULL); - - // Don't use CRURLCreateWithFileSystemPath -- only want valid URLs - - CFRelease(stringRef); - } - - if (urlRef) - { - result = LSOpenCFURLRef(urlRef, NULL); - - if (result != noErr) - { - LL_INFOS() << "Error " << result << " on open." << LL_ENDL; - } - - CFRelease(urlRef); - } - else - { - LL_INFOS() << "Error: couldn't create URL." << LL_ENDL; - } - -#endif // LL_LINUX LL_INFOS() << "spawn_web_browser returning." << LL_ENDL; } -void LLWindowSDL::openFile(const std::string& file_name) -{ - spawnWebBrowser("file://"+file_name,true); -} - void *LLWindowSDL::getPlatformWindow() { return NULL; @@ -2756,15 +2142,10 @@ void LLWindowSDL::bringToFront() // This is currently used when we are 'launched' to a specific // map position externally. LL_INFOS() << "bringToFront" << LL_ENDL; -#if LL_X11 - if (mSDL_Display && !mFullscreen) + if (mWindow && !mFullscreen) { - maybe_lock_display(); - XRaiseWindow(mSDL_Display, mSDL_XWindowID); - XSync(mSDL_Display, False); - maybe_unlock_display(); + SDL_RaiseWindow(mWindow); } -#endif // LL_X11 } //static @@ -2868,54 +2249,6 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() return rtns; } - -void* LLWindowSDL::createSharedContext() -{ - auto *pContext = SDL_GL_CreateContext(mWindow); - if ( pContext) - { - SDL_GL_SetSwapInterval(0); - SDL_GL_MakeCurrent(mWindow, mContext); - - LLCoordScreen size; - if (getSize(&size)) - setSize(size); - - LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; - - return (void*)pContext; - } - - LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; - - return nullptr; -} - -void LLWindowSDL::makeContextCurrent(void* contextPtr) -{ - LL_PROFILER_GPU_CONTEXT; - SDL_GL_MakeCurrent( mWindow, contextPtr ); -} - -void LLWindowSDL::destroySharedContext(void* contextPtr) -{ - SDL_GL_DeleteContext( contextPtr ); -} - -void LLWindowSDL::toggleVSync(bool enable_vsync) -{ - if( !enable_vsync) - { - SDL_GL_SetSwapInterval(0); - SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"0",SDL_HINT_OVERRIDE); - } - else - { - SDL_GL_SetSwapInterval(1); - SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"1",SDL_HINT_OVERRIDE); - } -} - void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position) { LLCoordWindow win_pos; diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 3ed2811572..076d7234bc 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -32,7 +32,7 @@ #include "llwindow.h" #include "lltimer.h" -#if !defined(__i386__) && !defined(__x86_64__) +#if !defined(__i386__) && !defined(__x86_64__) && !_M_X64 #define SDL_DISABLE_IMMINTRIN_H #endif #include "SDL2/SDL.h" @@ -84,7 +84,7 @@ public: bool setSizeImpl(LLCoordWindow size) override; - bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, + bool switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, const LLCoordScreen *const posp = NULL) override; bool setCursorPosition(LLCoordWindow position) override; @@ -177,13 +177,11 @@ public: void *getPlatformWindow() override; void bringToFront() override; - + void setLanguageTextInput(const LLCoordGL& pos) override; void spawnWebBrowser(const std::string &escaped_url, bool async) override; - void openFile(const std::string &file_name); - void setTitle(const std::string title) override; static std::vector<std::string> getDynamicFallbackFontList(); @@ -221,8 +219,8 @@ public: protected: LLWindowSDL(LLWindowCallbacks *callbacks, - const std::string &title, int x, int y, int width, int height, U32 flags, - bool fullscreen, bool clearBg, bool disable_vsync, bool use_gl, + const std::string &title, const std::string& name, int x, int y, int width, int height, U32 flags, + bool fullscreen, bool clearBg, bool enable_vsync, bool use_gl, bool ignore_pixel_depth, U32 fsaa_samples); ~LLWindowSDL(); @@ -251,14 +249,12 @@ protected: // // create or re-create the GL context/window. Called from the constructor and switchContext(). - bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync); + bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync); void destroyContext(); void setupFailure(const std::string &text, const std::string &caption, U32 type); - void fixWindowSize(void); - U32 SDLCheckGrabbyKeys(U32 keysym, bool gain); bool SDLReallyCaptureInput(bool capture); @@ -285,50 +281,19 @@ protected: int mHaveInputFocus; /* 0=no, 1=yes, else unknown */ int mIsMinimized; /* 0=no, 1=yes, else unknown */ - int mIsActive; /* 0=no, 1=yes, else unknown */ friend class LLWindowManager; private: -#if LL_X11 - - void x11_set_urgent(bool urgent); - bool mFlashing; LLTimer mFlashTimer; -#endif //LL_X11 - U32 mKeyVirtualKey; U32 mKeyModifiers; std::string mInputType; -public: -#if LL_X11 - - static Display *getSDLDisplay(); - - LLWString const &getPrimaryText() const { return mPrimaryClipboard; } - - LLWString const &getSecondaryText() const { return mSecondaryClipboard; } - - void clearPrimaryText() { mPrimaryClipboard.clear(); } - - void clearSecondaryText() { mSecondaryClipboard.clear(); } private: - void initialiseX11Clipboard(); - - bool getSelectionText(Atom selection, LLWString &text); - - bool getSelectionText(Atom selection, Atom type, LLWString &text); - - bool setSelectionText(Atom selection, const LLWString &text); -#endif - void tryFindFullscreenSize(int &aWidth, int &aHeight); - - LLWString mPrimaryClipboard; - LLWString mSecondaryClipboard; }; class LLSplashScreenSDL : public LLSplashScreen diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 9dc2644650..64f20e65ca 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -44,6 +44,7 @@ #include "llstring.h" #include "lldir.h" #include "llsdutil.h" +#include "llsys.h" #include "llglslshader.h" #include "llthreadsafequeue.h" #include "stringize.h" @@ -80,10 +81,6 @@ const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; const F32 ICON_FLASH_TIME = 0.5f; -#ifndef WM_DPICHANGED -#define WM_DPICHANGED 0x02E0 -#endif - #ifndef USER_DEFAULT_SCREEN_DPI #define USER_DEFAULT_SCREEN_DPI 96 // Win7 #endif @@ -163,7 +160,18 @@ HGLRC SafeCreateContext(HDC &hdc) GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) { - return LL::seh::catcher([hdc, ppfd]{ return ChoosePixelFormat(hdc, ppfd); }); + __try + { + return ChoosePixelFormat(hdc, ppfd); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + // convert to C++ styled exception + // C exception don't allow classes, so it's a regular char array + char integer_string[32]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } } //static @@ -568,6 +576,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, // Make an instance of our window then define the window class mhInstance = GetModuleHandle(NULL); +#if !_M_ARM64 // Init Direct Input - needed for joystick / Spacemouse LPDIRECTINPUT8 di8_interface; @@ -582,6 +591,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, { gDirectInput8 = di8_interface; } +#endif mSwapMethod = SWAP_METHOD_UNDEFINED; @@ -1306,8 +1316,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo catch (...) { LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); - OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1318,8 +1327,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1357,8 +1365,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo if (!SetPixelFormat(mhDC, pixel_format, &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1366,16 +1373,14 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo if (!(mhRC = SafeCreateContext(mhDC))) { - OSMessageBox(mCallbacks->translateString("MBGLContextErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } if (!wglMakeCurrent(mhDC, mhRC)) { - OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1581,15 +1586,14 @@ const S32 max_format = (S32)num_formats - 1; if (!mhDC) { - OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBDevContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } if (!SetPixelFormat(mhDC, pixel_format, &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1619,16 +1623,18 @@ const S32 max_format = (S32)num_formats - 1; } else { - LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr")); - // mWindowHandle is 0, going to crash either way - LL_ERRS("Window") << "No wgl_ARB_pixel_format extension!" << LL_ENDL; + LL_WARNS("Window") << "No wgl_ARB_pixel_format extension!" << LL_ENDL; + // cannot proceed without wgl_ARB_pixel_format extension, shutdown same as any other gGLManager.initGL() failure + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); + close(); + return false; } // Verify what pixel format we actually received. if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1650,14 +1656,14 @@ const S32 max_format = (S32)num_formats - 1; if (!wglMakeCurrent(mhDC, mhRC)) { - OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } if (!gGLManager.initGL()) { - OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1862,7 +1868,7 @@ void* LLWindowWin32::createSharedContext() if (!rc && !(rc = wglCreateContext(mhDC))) { close(); - OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); } return rc; @@ -2961,6 +2967,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ return 0; } + case WM_DISPLAYCHANGE: + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleDisplayChanged()); + } + case WM_SETFOCUS: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETFOCUS"); @@ -3699,6 +3710,10 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t // // "This is why I'm doing it this way, instead of what you would think would be more obvious..." // (C) Nat Goodspeed + if (!IsWindow(sWindowHandleForMessageBox)) + { + sWindowHandleForMessageBox = NULL; + } int retval_win = MessageBoxW(sWindowHandleForMessageBox, // HWND ll_convert_string_to_wide(text).c_str(), ll_convert_string_to_wide(caption).c_str(), @@ -4027,7 +4042,15 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont) break; } - logfont->lfHeight = mPreeditor->getPreeditFontSize(); + if (mPreeditor) + { + logfont->lfHeight = mPreeditor->getPreeditFontSize(); + } + else + { + // todo: extract from some font * LLUI::getScaleFactor() intead + logfont->lfHeight = 10; + } logfont->lfWeight = FW_NORMAL; } @@ -4664,6 +4687,32 @@ void LLWindowWin32::LLWindowWin32Thread::checkDXMem() // Alternatively use GetDesc from below to get adapter's memory UINT64 budget_mb = info.Budget / (1024 * 1024); + if (gGLManager.mIsIntel) + { + U32Megabytes phys_mb = gSysMemory.getPhysicalMemoryKB(); + LL_WARNS() << "Physical memory: " << phys_mb << " MB" << LL_ENDL; + + if (phys_mb > 0) + { + if (gGLManager.mIsIntel) + { + // Intel uses 'shared' vram, cap it to 25% of total memory + // Todo: consider a way of detecting integrated Intel and AMD + budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.25)); + } + else + { + // More budget is generally better, but the way viewer + // utilizes even dedicated VRAM leaves a footprint in RAM + budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.75)); + } + } + else + { + // if no data available, cap to 2Gb + budget_mb = llmin(budget_mb, (UINT64)2048); + } + } if (gGLManager.mVRAM < (S32)budget_mb) { gGLManager.mVRAM = (S32)budget_mb; diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 287402faa0..36e89e4586 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -28,7 +28,7 @@ #define LL_LLWINDOWWIN32_H // Limit Windows API to small and manageable set. -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include "llwindow.h" #include "llwindowcallbacks.h" |