Skip to content

Commit

Permalink
Merge pull request #1584 from unknownbrackets/reporting
Browse files Browse the repository at this point in the history
Send GPU, CPU, and platform info into the reporting server
  • Loading branch information
hrydgard committed Apr 29, 2013
2 parents c3e7440 + b0ce9e9 commit 8561531
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 12 deletions.
123 changes: 111 additions & 12 deletions Core/Reporting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@

#include "Core/Reporting.h"

#include "Common/CPUDetect.h"
#include "Common/StdThread.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "GPU/GPUInterface.h"
#include "GPU/GPUState.h"

#include "net/http_client.h"
#include "net/resolve.h"
Expand All @@ -40,6 +43,60 @@ namespace Reporting
// Temporarily stores a reference to the hostname.
static std::string lastHostname;

struct UrlEncoder
{
UrlEncoder() : paramCount(0)
{
data.reserve(256);
};

void Add(const std::string &key, const std::string &value)
{
if (++paramCount > 1)
data += '&';
AppendEscaped(key);
data += '=';
AppendEscaped(value);
}

// Percent encoding, aka application/x-www-form-urlencoded.
void AppendEscaped(const std::string &value)
{
for (size_t lastEnd = 0; lastEnd < value.length(); )
{
size_t pos = value.find_first_not_of(unreservedChars, lastEnd);
if (pos == value.npos)
{
data += value.substr(lastEnd);
break;
}

if (pos != lastEnd)
data += value.substr(lastEnd, pos - lastEnd);
lastEnd = pos;

// Encode the reserved character.
char c = value[pos];
data += '%';
data += hexChars[(c >> 4) & 15];
data += hexChars[(c >> 0) & 15];
++lastEnd;
}
}

std::string &ToString()
{
return data;
}

std::string data;
int paramCount;
static const char *unreservedChars;
static const char *hexChars;
};
const char *UrlEncoder::unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~";
const char *UrlEncoder::hexChars = "0123456789ABCDEF";

enum RequestType
{
MESSAGE,
Expand Down Expand Up @@ -143,30 +200,72 @@ namespace Reporting
return result;
}

std::string StripTrailingNull(const std::string &str)
{
size_t pos = str.find_first_of('\0');
if (pos != str.npos)
return str.substr(0, pos);
return str;
}

std::string GetPlatformIdentifer()
{
// TODO: Do we care about OS version?
#if defined(ANDROID)
return "Android";
#elif defined(_WIN64)
return "Windows 64";
#elif defined(_WIN32)
return "Windows";
#elif defined(IOS)
return "iOS";
#elif defined(__APPLE__)
return "Mac";
#elif defined(__SYMBIAN32__)
return "Symbian";
#elif defined(__FreeBSD__)
return "BSD";
#elif defined(BLACKBERRY)
return "Blackberry";
#elif defined(LOONGSON)
return "Loongson";
#elif defined(MEEGO_EDITION_HARMATTAN)
return "Nokia N9/N950";
#elif defined(__linux__)
return "Linux";
#else
return "Unknown";
#endif
}

int Process(int pos)
{
Payload &payload = payloadBuffer[pos];

const int PARAM_BUFFER_SIZE = 4096;
char temp[PARAM_BUFFER_SIZE];
std::string gpuPrimary, gpuFull;
gpu->GetReportingInfo(gpuPrimary, gpuFull);

// TODO: Need to escape these values, add more.
snprintf(temp, PARAM_BUFFER_SIZE - 1, "version=%s&game=%s_%s&game_title=%s",
PPSSPP_GIT_VERSION,
g_paramSFO.GetValueString("DISC_ID").c_str(),
g_paramSFO.GetValueString("DISC_VERSION").c_str(),
g_paramSFO.GetValueString("TITLE").c_str());
UrlEncoder postdata;
postdata.Add("version", PPSSPP_GIT_VERSION);
// TODO: Maybe ParamSFOData shouldn't include nulls in std::strings? Don't work to break savedata, though...
postdata.Add("game", StripTrailingNull(g_paramSFO.GetValueString("DISC_ID")) + "_" + StripTrailingNull(g_paramSFO.GetValueString("DISC_VERSION")));
postdata.Add("game_title", StripTrailingNull(g_paramSFO.GetValueString("TITLE")));
postdata.Add("gpu", gpuPrimary);
postdata.Add("gpu_full", gpuFull);
postdata.Add("cpu", cpu_info.Summarize());
postdata.Add("platform", GetPlatformIdentifer());

// TODO: Settings, savestate/savedata status, some measure of speed/fps?

std::string data;
switch (payload.type)
{
case MESSAGE:
// TODO: Escape.
data = std::string(temp) + "&message=" + payload.string1 + "&value=" + payload.string2;
postdata.Add("message", payload.string1);
postdata.Add("value", payload.string2);
payload.string1.clear();
payload.string2.clear();

SendReportRequest("/report/message", data);
SendReportRequest("/report/message", postdata.ToString());
break;
}

Expand Down
24 changes: 24 additions & 0 deletions GPU/GLES/DisplayListInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ GLES_GPU::GLES_GPU()
flushBeforeCommand_[flushBeforeCommandList[i]] = 1;
}
flushBeforeCommand_[1] = 0;

BuildReportingInfo();
}

GLES_GPU::~GLES_GPU() {
Expand All @@ -203,6 +205,28 @@ GLES_GPU::~GLES_GPU() {
delete [] flushBeforeCommand_;
}

// Let's avoid passing nulls into snprintf().
static const char *GetGLStringAlways(GLenum name) {
const GLubyte *value = glGetString(name);
if (!value)
return "?";
return (const char *)value;
}

// Needs to be called on GPU thread, not reporting thread.
void GLES_GPU::BuildReportingInfo() {
const char *glVendor = GetGLStringAlways(GL_VENDOR);
const char *glRenderer = GetGLStringAlways(GL_RENDERER);
const char *glVersion = GetGLStringAlways(GL_VERSION);
const char *glSlVersion = GetGLStringAlways(GL_SHADING_LANGUAGE_VERSION);
const char *glExtensions = GetGLStringAlways(GL_EXTENSIONS);

char temp[2048];
snprintf(temp, sizeof(temp), "%s (%s %s), %s (extensions: %s)", glVersion, glVendor, glRenderer, glSlVersion, glExtensions);
reportingPrimaryInfo_ = glVendor;
reportingFullInfo_ = temp;
}

void GLES_GPU::DeviceLost() {
// Simply drop all caches and textures.
// FBO:s appear to survive? Or no?
Expand Down
8 changes: 8 additions & 0 deletions GPU/GLES/DisplayListInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class GLES_GPU : public GPUCommon
}
virtual bool FramebufferDirty();

virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) {
primaryInfo = reportingPrimaryInfo_;
fullInfo = reportingFullInfo_;
}
std::vector<FramebufferInfo> GetFramebufferList();

protected:
Expand All @@ -69,6 +73,7 @@ class GLES_GPU : public GPUCommon
void DoBlockTransfer();
void ApplyDrawState(int prim);
void CheckFlushOp(u32 op, u32 diff);
void BuildReportingInfo();

// Applies states for debugging if enabled.
void BeginDebugDraw();
Expand All @@ -81,4 +86,7 @@ class GLES_GPU : public GPUCommon

u8 *flushBeforeCommand_;
bool resized_;

std::string reportingPrimaryInfo_;
std::string reportingFullInfo_;
};
2 changes: 2 additions & 0 deletions GPU/GPUInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "GPUState.h"
#include "Core/HLE/sceKernelThread.h"
#include <list>
#include <string>

class PointerWrap;

Expand Down Expand Up @@ -186,6 +187,7 @@ class GPUInterface

// Debugging
virtual void DumpNextFrame() = 0;
virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) = 0;
virtual const std::list<int>& GetDisplayLists() = 0;
virtual DisplayList* GetCurrentDisplayList() = 0;
virtual bool DecodeTexture(u8* dest, GPUgstate state) = 0;
Expand Down
4 changes: 4 additions & 0 deletions GPU/Null/NullGpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class NullGPU : public GPUCommon
virtual void DumpNextFrame() {}

virtual void Resized() {}
virtual void GetReportingInfo(std::string &primaryInfo, std::string &fullInfo) {
primaryInfo = "NULL";
fullInfo = "NULL";
}

protected:
virtual void FastRunLoop(DisplayList &list);
Expand Down

0 comments on commit 8561531

Please sign in to comment.