More information from the platform on mac

This commit is contained in:
Sam Gateau 2019-07-02 14:48:25 +02:00
parent 043aee4f78
commit 2c412808e7
3 changed files with 211 additions and 53 deletions

View file

@ -19,6 +19,9 @@
#include <cpuid.h>
#include <sys/sysctl.h>
#include <sstream>
#include <regex>
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
#include <QSysInfo>
@ -36,73 +39,226 @@ void MACOSInstance::enumerateCpus() {
_cpus.push_back(cpu);
}
#include <OpenGL/OpenGL.h>
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<std::string>());
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<CGLRendererDesc> 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<std::string>());
// 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<json> 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<CGDirectDisplayID> 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
}

View file

@ -98,6 +98,7 @@ PropFolderPanel {
"label": itemLabel,
"rootObject":itemRootObject,
"indentDepth": itemDepth,
"isUnfold": true,
})
} break;
case 'printLabel': {

View file

@ -51,6 +51,7 @@ Rectangle {
}
Prop.PropFolderPanel {
label: "Platform"
isUnfold: true
panelFrameData: Component {
Platform {
}