From 2c412808e71696039e62b63aedde3bd06dc3480f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jul 2019 14:48:25 +0200 Subject: [PATCH] More information from the platform on mac --- .../src/platform/backend/MACOSPlatform.cpp | 262 ++++++++++++++---- .../utilities/lib/prop/PropGroup.qml | 1 + .../utilities/render/performanceSetup.qml | 1 + 3 files changed, 211 insertions(+), 53 deletions(-) diff --git a/libraries/platform/src/platform/backend/MACOSPlatform.cpp b/libraries/platform/src/platform/backend/MACOSPlatform.cpp index cacbd06816..c510059093 100644 --- a/libraries/platform/src/platform/backend/MACOSPlatform.cpp +++ b/libraries/platform/src/platform/backend/MACOSPlatform.cpp @@ -19,6 +19,9 @@ #include #include +#include +#include + #include #include #include @@ -36,73 +39,226 @@ void MACOSInstance::enumerateCpus() { _cpus.push_back(cpu); } +#include + void MACOSInstance::enumerateGpus() { #ifdef Q_OS_MAC - - GPUIdent* ident = GPUIdent::getInstance(); - json gpu = {}; - - gpu[keys::gpu::model] = ident->getName().toUtf8().constData(); - gpu[keys::gpu::vendor] = findGPUVendorInDescription(gpu[keys::gpu::model].get()); - gpu[keys::gpu::videoMemory] = ident->getMemory(); - gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData(); - - _gpus.push_back(gpu); + // Collect Renderer info as exposed by the CGL layers + GLuint cglDisplayMask = -1; // Iterate over all of them. + CGLRendererInfoObj rendererInfo; + GLint rendererInfoCount; + CGLError error = CGLQueryRendererInfo(cglDisplayMask, &rendererInfo, &rendererInfoCount); + if (rendererInfoCount <= 0 || 0 != error) { + return; + } + struct CGLRendererDesc { + int rendererID{0}; + int deviceVRAM{0}; + int majorGLVersion{0}; + int registryIDLow{0}; + int registryIDHigh{0}; + int displayMask{0}; + }; + std::vector renderers(rendererInfoCount); + + // Iterate over all of the renderers and use the figure for the one with the most VRAM, + // on the assumption that this is the one that will actually be used. + for (GLint i = 0; i < rendererInfoCount; i++) { + auto& desc = renderers[i]; + + CGLDescribeRenderer(rendererInfo, i, kCGLRPRendererID, &desc.rendererID); + CGLDescribeRenderer(rendererInfo, i, kCGLRPVideoMemoryMegabytes, &desc.deviceVRAM); + CGLDescribeRenderer(rendererInfo, i, kCGLRPMajorGLVersion, &desc.majorGLVersion); + CGLDescribeRenderer(rendererInfo, i, kCGLRPRegistryIDLow, &desc.registryIDLow); + CGLDescribeRenderer(rendererInfo, i, kCGLRPRegistryIDHigh, &desc.registryIDHigh); + CGLDescribeRenderer(rendererInfo, i, kCGLRPDisplayMask, &desc.displayMask); + + kCGLRPDisplayMask + json gpu = {}; + gpu["A"] =desc.rendererID; + gpu["B"] =desc.deviceVRAM; + gpu["C"] =desc.majorGLVersion; + + gpu["D"] =desc.registryIDLow; + gpu["E"] =desc.registryIDHigh; + gpu["F"] =desc.displayMask; + + _gpus.push_back(gpu); + } + + CGLDestroyRendererInfo(rendererInfo); + + //get gpu / display information from the system profiler + + FILE* stream = popen("system_profiler SPDisplaysDataType | grep -e Chipset -e VRAM -e Vendor -e \"Device ID\" -e Displays -e \"Display Type\" -e Resolution -e \"Main Display\"", "r"); + std::ostringstream hostStream; + while (!feof(stream) && !ferror(stream)) { + char buf[128]; + int bytesRead = fread(buf, 1, 128, stream); + hostStream.write(buf, bytesRead); + } + std::string gpuArrayDesc = hostStream.str(); + + // Find the Chipset model first + const std::regex chipsetModelToken("(Chipset Model: )(.*)"); + std::smatch found; + + while (std::regex_search(gpuArrayDesc, found, chipsetModelToken)) { + json gpu = {}; + gpu[keys::gpu::model] = found.str(2); + + // Find the end of the gpu block + gpuArrayDesc = found.suffix(); + std::string gpuDesc = gpuArrayDesc; + const std::regex endGpuToken("Chipset Model: "); + if (std::regex_search(gpuArrayDesc, found, endGpuToken)) { + gpuDesc = found.prefix(); + } + + // Find the vendor + gpu[keys::gpu::vendor] = findGPUVendorInDescription(gpu[keys::gpu::model].get()); + + // Find the memory amount in MB + const std::regex memoryToken("(VRAM .*: )(.*)"); + if (std::regex_search(gpuDesc, found, memoryToken)) { + auto memAmountUnit = found.str(2); + std::smatch amount; + const std::regex memAmountGBToken("(\\d*) GB"); + const std::regex memAmountMBToken("(\\d*) MB"); + const int GB_TO_MB { 1024 }; + if (std::regex_search(memAmountUnit, amount, memAmountGBToken)) { + gpu[keys::gpu::videoMemory] = std::stoi(amount.str(1)) * GB_TO_MB; + } else if (std::regex_search(memAmountUnit, amount, memAmountMBToken)) { + gpu[keys::gpu::videoMemory] = std::stoi(amount.str(1)); + } else { + gpu[keys::gpu::videoMemory] = found.str(2); + } + } + + // Find the Device ID + const std::regex deviceIDToken("(Device ID: )(.*)"); + if (std::regex_search(gpuDesc, found, deviceIDToken)) { + gpu["deviceID"] = std::stoi(found.str(2)); + } + + // Enumerate the Displays + const std::regex displaysToken("(Displays: )"); + if (std::regex_search(gpuDesc, found, displaysToken)) { + std::string displayArrayDesc = found.suffix(); + std::vector displays; + + int displayIndex = 0; + const std::regex displayTypeToken("(Display Type: )(.*)"); + while (std::regex_search(displayArrayDesc, found, displayTypeToken)) { + json display = {}; + display["display"] = found.str(2); + + // Find the end of the display block + displayArrayDesc = found.suffix(); + std::string displayDesc = displayArrayDesc; + const std::regex endDisplayToken("Display Type: "); + if (std::regex_search(displayArrayDesc, found, endDisplayToken)) { + displayDesc = found.prefix(); + } + + // Find the resolution + const std::regex resolutionToken("(Resolution: )(.*)"); + if (std::regex_search(displayDesc, found, deviceIDToken)) { + display["resolution"] = found.str(2); + } + + // Find is main display + const std::regex mainMonitorToken("(Main Display: )(.*)"); + if (std::regex_search(displayDesc, found, mainMonitorToken)) { + display["isMaster"] = found.str(2); + } else { + display["isMaster"] = "false"; + } + + display["index"] = displayIndex; + displayIndex++; + + displays.push_back(display); + } + if (!displays.empty()) { + gpu["displays"] = displays; + } + } + + _gpus.push_back(gpu); + } #endif } void MACOSInstance::enumerateDisplays() { #ifdef Q_OS_MAC - auto displayID = CGMainDisplayID(); - auto displaySize = CGDisplayScreenSize(displayID); + uint32_t numDisplays = 0; + CGError error = CGGetOnlineDisplayList(0, nullptr, &numDisplays); + if (numDisplays <= 0 || error != kCGErrorSuccess) { + return; + } + + std::vector onlineDisplayIDs(numDisplays, 0); + error = CGGetOnlineDisplayList(onlineDisplayIDs.size(), onlineDisplayIDs.data(), &numDisplays); + if (error != kCGErrorSuccess) { + return; + } + + for (auto displayID : onlineDisplayIDs) { + auto displaySize = CGDisplayScreenSize(displayID); - const auto MM_TO_IN = 0.0393701; - auto displaySizeWidthInches = displaySize.width * MM_TO_IN; - auto displaySizeHeightInches = displaySize.height * MM_TO_IN; - auto displaySizeDiagonalInches = sqrt(displaySizeWidthInches * displaySizeWidthInches + displaySizeHeightInches * displaySizeHeightInches); - - auto displayBounds = CGDisplayBounds(displayID); - auto displayMaster =CGDisplayIsMain(displayID); - - auto displayUnit =CGDisplayUnitNumber(displayID); - auto displayModel =CGDisplayModelNumber(displayID); - auto displayVendor = CGDisplayVendorNumber(displayID); - auto displaySerial = CGDisplaySerialNumber(displayID); + auto glmask = CGDisplayIDToOpenGLDisplayMask(displayID); + + const auto MM_TO_IN = 0.0393701; + auto displaySizeWidthInches = displaySize.width * MM_TO_IN; + auto displaySizeHeightInches = displaySize.height * MM_TO_IN; + auto displaySizeDiagonalInches = sqrt(displaySizeWidthInches * displaySizeWidthInches + displaySizeHeightInches * displaySizeHeightInches); + + auto displayBounds = CGDisplayBounds(displayID); + auto displayMaster =CGDisplayIsMain(displayID); + + auto displayUnit =CGDisplayUnitNumber(displayID); + auto displayModel =CGDisplayModelNumber(displayID); + auto displayVendor = CGDisplayVendorNumber(displayID); + auto displaySerial = CGDisplaySerialNumber(displayID); - auto displayMode = CGDisplayCopyDisplayMode(displayID); - auto displayModeWidth = CGDisplayModeGetPixelWidth(displayMode); - auto displayModeHeight = CGDisplayModeGetPixelHeight(displayMode); - auto displayRefreshrate = CGDisplayModeGetRefreshRate(displayMode); + auto displayMode = CGDisplayCopyDisplayMode(displayID); + auto displayModeWidth = CGDisplayModeGetPixelWidth(displayMode); + auto displayModeHeight = CGDisplayModeGetPixelHeight(displayMode); + auto displayRefreshrate = CGDisplayModeGetRefreshRate(displayMode); - CGDisplayModeRelease(displayMode); - - json display = {}; - - display["physicalWidth"] = displaySizeWidthInches; - display["physicalHeight"] = displaySizeHeightInches; - display["physicalDiagonal"] = displaySizeDiagonalInches; - - display["ppi"] = sqrt(displayModeHeight * displayModeHeight + displayModeWidth * displayModeWidth) / displaySizeDiagonalInches; - - display["coordLeft"] = displayBounds.origin.x; - display["coordRight"] = displayBounds.origin.x + displayBounds.size.width; - display["coordTop"] = displayBounds.origin.y; - display["coordBottom"] = displayBounds.origin.y + displayBounds.size.height; - - display["isMaster"] = displayMaster; + CGDisplayModeRelease(displayMode); + + json display = {}; + + display["physicalWidth"] = displaySizeWidthInches; + display["physicalHeight"] = displaySizeHeightInches; + display["physicalDiagonal"] = displaySizeDiagonalInches; + + display["ppi"] = sqrt(displayModeHeight * displayModeHeight + displayModeWidth * displayModeWidth) / displaySizeDiagonalInches; + + display["coordLeft"] = displayBounds.origin.x; + display["coordRight"] = displayBounds.origin.x + displayBounds.size.width; + display["coordTop"] = displayBounds.origin.y; + display["coordBottom"] = displayBounds.origin.y + displayBounds.size.height; + + display["isMaster"] = displayMaster; - display["unit"] = displayUnit; - display["vendor"] = displayVendor; - display["model"] = displayModel; - display["serial"] = displaySerial; - - display["refreshrate"] =displayRefreshrate; - display["modeWidth"] = displayModeWidth; - display["modeHeight"] = displayModeHeight; + display["unit"] = displayUnit; + display["vendor"] = displayVendor; + display["model"] = displayModel; + display["serial"] = displaySerial; + + display["refreshrate"] =displayRefreshrate; + display["modeWidth"] = displayModeWidth; + display["modeHeight"] = displayModeHeight; + + display["glmask"] = glmask; - _displays.push_back(display); + _displays.push_back(display); + } #endif } diff --git a/scripts/developer/utilities/lib/prop/PropGroup.qml b/scripts/developer/utilities/lib/prop/PropGroup.qml index 848ff8b288..b1c65d04fd 100644 --- a/scripts/developer/utilities/lib/prop/PropGroup.qml +++ b/scripts/developer/utilities/lib/prop/PropGroup.qml @@ -98,6 +98,7 @@ PropFolderPanel { "label": itemLabel, "rootObject":itemRootObject, "indentDepth": itemDepth, + "isUnfold": true, }) } break; case 'printLabel': { diff --git a/scripts/developer/utilities/render/performanceSetup.qml b/scripts/developer/utilities/render/performanceSetup.qml index 4654736f72..be9b6a3271 100644 --- a/scripts/developer/utilities/render/performanceSetup.qml +++ b/scripts/developer/utilities/render/performanceSetup.qml @@ -51,6 +51,7 @@ Rectangle { } Prop.PropFolderPanel { label: "Platform" + isUnfold: true panelFrameData: Component { Platform { }