Merge pull request #15512 from amerhifi/feature/platform

case lily-29:  Feature/platform. Creating a single point api to get system info
This commit is contained in:
Brad Hefta-Gaub 2019-05-15 14:04:43 -07:00 committed by GitHub
commit 4e8d3470d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 669 additions and 4 deletions

View file

@ -209,7 +209,7 @@ link_hifi_libraries(
model-networking model-baker entities avatars trackers
audio audio-client animation script-engine physics
render-utils entities-renderer avatars-renderer ui qml auto-updater midi
controllers plugins image trackers
controllers plugins image trackers platform
ui-plugins display-plugins input-plugins
# Platform specific GL libraries
${PLATFORM_GL_BACKEND}
@ -228,6 +228,7 @@ target_bullet()
target_opengl()
add_crashpad()
target_breakpad()
target_json()
# perform standard include and linking for found externals
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})

View file

@ -1,4 +1,4 @@
//
//
// Application.h
// interface/src
//
@ -48,7 +48,6 @@
#include <ThreadSafeValueCache.h>
#include <shared/ConicalViewFrustum.h>
#include <shared/FileLogger.h>
#include <RunningMarker.h>
#include "avatar/MyAvatar.h"

View file

@ -0,0 +1,5 @@
set(TARGET_NAME platform)
setup_hifi_library()
link_hifi_libraries(shared)
target_json()

View file

@ -0,0 +1,40 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "AndroidPlatform.h"
#include "platformJsonKeys.h"
#include <GPUIdent.h>
#include <string>
using namespace platform;
void AndroidInstance::enumerateCpu() {
json cpu;
cpu["cpuBrand"] = "";
cpu["cpuModel"] = "";
cpu["cpuClockSpeed"] = "";
cpu["cpuNumCores"] = "";
_cpu.push_back(cpu);
}
void AndroidInstance::enumerateGpu() {
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu["gpuName"] = ident->getName().toUtf8().constData();
gpu["gpuMemory"] = ident->getMemory();
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_display = ident->getOutput();
}
void AndroidInstance::enumerateMemory() {
json ram = {};
_memory.push_back(ram);
}

View file

@ -0,0 +1,25 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_AndroidPlatform_h
#define hifi_AndroidPlatform_h
#include "platformInstance.h"
namespace platform {
class AndroidInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateMemory() override;
void enumerateGpu() override;
};
} // namespace platform
#endif //hifi_androidplatform_h

View file

@ -0,0 +1,42 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "LinuxPlatform.h"
#include "platformJsonKeys.h"
#include <GPUIdent.h>
#include <string>
using namespace platform;
void LinuxInstance::enumerateCpu() {
json cpu = {};
cpu["cpuBrand"] = "";
cpu["cpuModel"] = "";
cpu["cpuClockSpeed"] = "";
cpu["cpuNumCores"] = "";
_cpu.push_back(cpu);
}
void LinuxInstance::enumerateGpu() {
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu["gpuName"] = ident->getName().toUtf8().constData();
gpu["gpuMemory"] = ident->getMemory();
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_display = ident->getOutput();
}
void LinuxInstance::enumerateMemory() {
json ram = {};
_memory.push_back(ram);
}

View file

@ -0,0 +1,25 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_LinuxPlatform_h
#define hifi_LinuxPlatform_h
#include "platformInstance.h"
namespace platform {
class LinuxInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateMemory() override;
void enumerateGpu() override;
};
} // namespace platform
#endif //hifi_linuxPlaform_h

View file

@ -0,0 +1,86 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "MACOSPlatform.h"
#include "platformJsonKeys.h"
#include <thread>
#include <GPUIdent.h>
#include <string>
#ifdef Q_OS_MAC
#include <unistd.h>
#include <cpuid.h>
#endif
using namespace platform;
static void getCpuId( uint32_t* p, uint32_t ax )
{
#ifdef Q_OS_MAC
__asm __volatile
( "movl %%ebx, %%esi\n\t"
"cpuid\n\t"
"xchgl %%ebx, %%esi"
: "=a" (p[0]), "=S" (p[1]),
"=c" (p[2]), "=d" (p[3])
: "0" (ax)
);
#endif
}
void MACOSInstance::enumerateCpu() {
json cpu = {};
uint32_t cpuInfo[4]={0,0,0,0};
char CPUBrandString[16];
char CPUModelString[16];
char CPUClockString[16];
uint32_t nExIds;
getCpuId(cpuInfo, 0x80000000);
nExIds = cpuInfo[0];
for (uint32_t i = 0x80000000; i <= nExIds; ++i) {
getCpuId(cpuInfo, i);
// Interpret CPU brand string
if (i == 0x80000002) {
memcpy(CPUBrandString, cpuInfo, sizeof(cpuInfo));
} else if (i == 0x80000003) {
memcpy(CPUModelString, cpuInfo, sizeof(cpuInfo));
} else if (i == 0x80000004) {
memcpy(CPUClockString, cpuInfo, sizeof(cpuInfo));
}
}
cpu["cpuBrand"] = CPUBrandString;
cpu["cpuModel"] = CPUModelString;
cpu["cpuClockSpeed"] = CPUClockString;
cpu["cpuNumCores"] = std::thread::hardware_concurrency();
_cpu.push_back(cpu);
}
void MACOSInstance::enumerateGpu() {
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu["gpuName"] = ident->getName().toUtf8().constData();
gpu["gpuMemory"] = ident->getMemory();
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_display = ident->getOutput();
}
void MACOSInstance::enumerateMemory() {
json ram = {};
#ifdef Q_OS_MAC
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
ram["totalMemory"] = pages * page_size;;
#endif
_memory.push_back(ram);
}

View file

@ -0,0 +1,25 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_MACOSPlatform_h
#define hifi_MACOSPlatform_h
#include "platformInstance.h"
namespace platform {
class MACOSInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateMemory() override;
void enumerateGpu() override;
};
} // namespace platform
#endif //hifi_winplatform_h

View file

@ -0,0 +1,82 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "WINPlatform.h"
#include "platformJsonKeys.h"
#ifdef Q_OS_WINDOWS
#include <intrin.h>
#include <Windows.h>
#endif
#include <thread>
#include <GPUIdent.h>
#include <string>
using namespace platform;
void WINInstance::enumerateCpu() {
json cpu = {};
#ifdef Q_OS_WINDOWS
int CPUInfo[4] = { -1 };
unsigned nExIds;
unsigned int i = 0;
char CPUBrandString[16];
char CPUModelString[16];
char CPUClockString[16];
// Get the information associated with each extended ID.
__cpuid(CPUInfo, 0x80000000);
nExIds = CPUInfo[0];
for (i = 0x80000000; i <= nExIds; ++i) {
__cpuid(CPUInfo, i);
// Interpret CPU brand string
if (i == 0x80000002) {
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
} else if (i == 0x80000003) {
memcpy(CPUModelString, CPUInfo, sizeof(CPUInfo));
} else if (i == 0x80000004) {
memcpy(CPUClockString, CPUInfo, sizeof(CPUInfo));
}
}
cpu["cpuBrand"] = CPUBrandString;
cpu["cpuModel"] = CPUModelString;
cpu["cpuClockSpeed"] = CPUClockString;
cpu["cpuNumCores"] = std::thread::hardware_concurrency();
#endif
_cpu.push_back(cpu);
}
void WINInstance::enumerateGpu() {
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu["gpuName"] = ident->getName().toUtf8().constData();
gpu["gpuMemory"] = ident->getMemory();
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_display = ident->getOutput();
}
void WINInstance::enumerateMemory() {
json ram = {};
#ifdef Q_OS_WINDOWS
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex);
int totalRam = statex.ullTotalPhys / 1024 / 1024;
ram[jsonKeys::totalMemory] = totalRam;
#endif
_memory.push_back(ram);
}

View file

@ -0,0 +1,25 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_WinPlatform_h
#define hifi_WinPlatform_h
#include "platformInstance.h"
namespace platform {
class WINInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateMemory() override;
void enumerateGpu() override;
};
} // namespace platform
#endif //hifi_winplatform_h

View file

@ -0,0 +1,79 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "platform.h"
#include <qglobal.h>
#if defined(Q_OS_WIN)
#include "WINPlatform.h"
#elif defined(Q_OS_MAC)
#include "MACOSPlatform.h"
#elif defined(Q_OS_ANDROID)
#include "AndroidPlatform.h"
#elif defined(Q_OS_LINUX)
#include "LinuxPlatform.h"
#endif
using namespace platform;
Instance *_instance;
void platform::create() {
#if defined(Q_OS_WIN)
_instance =new WINInstance();
#elif defined(Q_OS_MAC)
_instance = new MACOSInstance();
#elif defined(Q_OS_ANDROID)
_instance= new AndroidInstance();
#elif defined(Q_OS_LINUX)
_instance= new LinuxInstance();
#endif
}
void platform::destroy() {
if(_instance)
delete _instance;
}
bool platform::enumeratePlatform() {
return _instance->enumeratePlatform();
}
int platform::getNumCPU() {
return _instance->getNumCPU();
}
json platform::getCPU(int index) {
return _instance->getCPU(index);
}
int platform::getNumGPU() {
return _instance->getNumGPU();
}
json platform::getGPU(int index) {
return _instance->getGPU(index);
}
int platform::getNumDisplay() {
return _instance->getNumDisplay();
}
json platform::getDisplay(int index) {
return _instance->getDisplay(index);
}
int platform::getNumMemory() {
return _instance->getNumMemory();
}
json platform::getMemory(int index) {
return _instance->getMemory(index);
}

View file

@ -0,0 +1,37 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_Platform_h
#define hifi_Platform_h
#include "platformInstance.h"
#include <vector>
#include <nlohmann/json.hpp>
namespace platform {
using json = nlohmann::json;
void create();
void destroy();
bool enumeratePlatform();
int getNumCPU();
json getCPU(int index);
int getNumGPU();
json getGPU(int index);
int getNumDisplay();
json getDisplay(int index);
int getNumMemory();
json getMemory(int index);
} // namespace platform
#endif // hifi_platform_h

View file

@ -0,0 +1,86 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "platform.h"
#include <QtGlobal>
#ifdef Q_OS_WIN
#include "WINPlatform.h"
#endif
#ifdef Q_OS_MACOS
#include "MACOSPlatform.h"
#endif
#ifdef Q_OS_LINUX
#endif
using namespace platform;
bool Instance::enumeratePlatform() {
enumerateCpu();
enumerateGpu();
enumerateMemory();
return true;
}
json Instance::getCPU(int index) {
assert(index <(int) _cpu.size());
if (index >= (int)_cpu.size())
return json();
return _cpu.at(index);
}
//These are ripe for template.. will work on that next
json Instance::getMemory(int index) {
assert(index <(int) _memory.size());
if(index >= (int)_memory.size())
return json();
return _memory.at(index);
}
json Instance::getGPU(int index) {
assert(index <(int) _gpu.size());
if (index >=(int) _gpu.size())
return json();
return _gpu.at(index);
}
json Instance::getDisplay(int index) {
assert(index <(int) _display.size());
if (index >=(int) _display.size())
return json();
return _display.at(index);
}
Instance::~Instance() {
if (_cpu.size() > 0) {
_cpu.clear();
}
if (_memory.size() > 0) {
_memory.clear();
}
if (_gpu.size() > 0) {
_gpu.clear();
}
if (_display.size() > 0) {
_display.clear();
}
}

View file

@ -0,0 +1,49 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_PlatformInstance_h
#define hifi_PlatformInstance_h
#include <vector>
#include <nlohmann/json.hpp>
namespace platform {
using json = nlohmann::json;
class Instance {
public:
bool virtual enumeratePlatform();
int getNumCPU() { return (int)_cpu.size(); }
json getCPU(int index);
int getNumGPU() { return (int)_gpu.size(); }
json getGPU(int index);
int getNumMemory() { return (int)_memory.size(); }
json getMemory(int index);
int getNumDisplay() { return (int)_display.size(); }
json getDisplay(int index);
void virtual enumerateCpu()=0;
void virtual enumerateMemory()=0;
void virtual enumerateGpu()=0;
virtual ~Instance();
protected:
std::vector<json> _cpu;
std::vector<json> _memory;
std::vector<json> _gpu;
std::vector<json> _display;
};
} // namespace platform
#endif // hifi_platformInstance_h

View file

@ -0,0 +1,34 @@
//
// Created by Amer Cerkic 05/02/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#ifndef hifi_PlatformJsonKeys_h
#define hifi_PlatformJsonKeys_h
namespace platform {
namespace jsonKeys{
#if 0
static const char* cpuBrand { "cpuBrand"};
static const char* cpuModel {"cpuModel"};
static const char* cpuClockSpeed {"clockSpeed"};
static const char* cpuNumCores { "numCores"};
static const char* gpuName {"GpuName"};
static const char* gpuMemory {"gpuMemory"};
static const char* gpuDriver {"gpuDriver"};
static const char* totalMemory {"totalMem"};
static const char* displayDescription { "description"};
static const char* displayName {"deviceName"};
static const char* displayCoordsLeft {"coordinatesleft"};
static const char* displayCoordsRight { "coordinatesright"};
static const char* displayCoordsTop { "coordinatestop"};
static const char* displayCoordsBottom { "coordinatesbottom"};
#endif
}
} // namespace platform
#endif

View file

@ -15,3 +15,5 @@ endif()
target_zlib()
target_nsight()
target_json()

View file

@ -12,6 +12,7 @@
#ifdef Q_OS_WIN
#include <string>
#include <nlohmann/json.hpp>
//#include <atlbase.h>
//#include <Wbemidl.h>
@ -250,6 +251,22 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer)
*/
if (!validAdapterList.empty()) {
for (auto outy = adapterToOutputs.begin(); outy != adapterToOutputs.end(); ++outy) {
AdapterEntry entry = *outy;
for (auto test = entry.second.begin(); test != entry.second.end(); ++test) {
nlohmann::json output = {};
output["description"] = entry.first.first.Description;
output["deviceName"]= test->DeviceName;
output["coordinatesleft"] = test->DesktopCoordinates.left;
output["coordinatesright"] = test->DesktopCoordinates.right;
output["coordinatestop"] = test->DesktopCoordinates.top;
output["coordinatesbottom"] = test->DesktopCoordinates.bottom;
_output.push_back(output);
}
}
auto& adapterEntry = adapterToOutputs[validAdapterList.front()];
std::wstring wDescription(adapterEntry.first.first.Description);

View file

@ -15,19 +15,25 @@
#define hifi_GPUIdent_h
#include <cstdint>
#include <QString>
#include <memory>
#include <nlohmann/json.hpp>
#include <vector>
class GPUIdent
{
public:
uint64_t getMemory() { return _dedicatedMemoryMB; }
QString getName() { return _name; }
QString getDriver() { return _driver; }
bool isValid() { return _isValid; }
const std::vector<nlohmann::json>& getOutput() { return _output; }
// E.g., GPUIdent::getInstance()->getMemory();
static GPUIdent* getInstance(const QString& vendor = "", const QString& renderer = "") { return _instance.ensureQuery(vendor, renderer); }
private:
std::vector<nlohmann::json> _output;
uint64_t _dedicatedMemoryMB { 0 };
QString _name { "" };
QString _driver { "" };