Add early OS X compiling support from @Zorro666 - still non-functional!

* Build with cmake -DENABLE_VULKAN=OFF -DENABLE_QRENDERDOC=OFF
This commit is contained in:
baldurk
2016-05-31 12:05:45 +02:00
parent c0e0b105e4
commit c1f66de413
26 changed files with 956 additions and 108 deletions
+2
View File
@@ -45,6 +45,8 @@ add_definitions(-DRENDERDOC_PLATFORM_POSIX)
if(ANDROID)
add_definitions(-DRENDERDOC_PLATFORM_ANDROID)
elseif(APPLE)
add_definitions(-DRENDERDOC_PLATFORM_APPLE)
elseif(UNIX)
add_definitions(-DRENDERDOC_PLATFORM_LINUX)
endif()
+35 -30
View File
@@ -19,6 +19,11 @@ if(ANDROID)
PRIVATE m
PRIVATE dl
PRIVATE ${CMAKE_THREAD_LIBS_INIT})
elseif(APPLE)
list(APPEND RDOC_LIBRARIES
PRIVATE m
PRIVATE dl
PRIVATE ${CMAKE_THREAD_LIBS_INIT})
elseif(UNIX)
find_package(PkgConfig REQUIRED)
find_package(Threads REQUIRED)
@@ -124,6 +129,25 @@ if(ANDROID)
data/embedded_files.h
os/posix/android/android_stringio.cpp
os/posix/android/android_callstack.cpp
os/posix/android/android_process.cpp
os/posix/android/android_threading.cpp
os/posix/posix_hook.cpp
os/posix/posix_hook.h
os/posix/posix_network.cpp
os/posix/posix_process.cpp
os/posix/posix_stringio.cpp
os/posix/posix_threading.cpp
os/posix/posix_specific.h)
# posix_libentry must be the last so that library_loaded is called after
# static objects are constructed.
list(APPEND sources os/posix/posix_libentry.cpp)
elseif(APPLE)
list(APPEND sources
data/embedded_files.h
os/posix/apple/apple_stringio.cpp
os/posix/apple/apple_callstack.cpp
os/posix/apple/apple_process.cpp
os/posix/apple/apple_threading.cpp
os/posix/posix_hook.cpp
os/posix/posix_hook.h
os/posix/posix_network.cpp
@@ -139,6 +163,8 @@ elseif(UNIX)
data/embedded_files.h
os/posix/linux/linux_stringio.cpp
os/posix/linux/linux_callstack.cpp
os/posix/linux/linux_process.cpp
os/posix/linux/linux_threading.cpp
os/posix/posix_hook.cpp
os/posix/posix_hook.h
os/posix/posix_network.cpp
@@ -156,7 +182,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
PROPERTIES COMPILE_FLAGS "-Wno-extra -Wno-unused-function")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_COMPILER_IS_GNUCXX OR APPLE)
set_source_files_properties(3rdparty/jpeg-compressor/jpgd.cpp
PROPERTIES COMPILE_FLAGS "-Wno-shift-negative-value")
endif()
@@ -206,40 +232,19 @@ set(data
set(data_objects)
if(UNIX)
# this is fragile...
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(bfdarch "i386")
set(bfdtarget "elf64-x86-64")
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686")
set(bfdarch "i386")
set(bfdtarget "elf32-i386")
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
set(bfdarch "aarch64")
set(bfdtarget "elf64-littleaarch64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
set(bfdarch "arm")
set(bfdtarget "elf32-littlearm")
else()
message(FATAL_ERROR "Unknown target architecture")
endif()
set(data_command ${CMAKE_OBJCOPY} -I binary -O ${bfdtarget} -B ${bfdarch})
foreach(res ${data})
# strip "data/"
string(SUBSTRING ${res} 5 -1 in)
set(working_dir ${CMAKE_CURRENT_SOURCE_DIR}/data)
set(in ${res})
set(working_dir ${CMAKE_CURRENT_SOURCE_DIR})
set(out_src ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/data.src/${in}.c)
get_filename_component(out_src_dir ${out_src} DIRECTORY)
set(out ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/data.obj/${in}.o)
get_filename_component(out_dir ${out} DIRECTORY)
add_custom_command(OUTPUT ${out}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir}
COMMAND ${data_command} ${in} ${out}
add_custom_command(OUTPUT ${out_src}
WORKING_DIRECTORY ${working_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_src_dir}
COMMAND xxd -i ${in} ${out_src}
DEPENDS ${res})
list(APPEND data_objects ${out})
list(APPEND data_objects ${out_src})
endforeach()
endif()
+2
View File
@@ -32,6 +32,8 @@
#define RENDERDOC_CC __cdecl
#elif defined(__linux__)
#define RENDERDOC_CC
#elif defined(__APPLE__)
#define RENDERDOC_CC
#else
#error "Unknown platform"
#endif
+3 -3
View File
@@ -25,9 +25,9 @@
#pragma once
#define DECLARE_EMBED(filename) \
extern char CONCAT(CONCAT(_binary_, filename), _start); \
extern char CONCAT(CONCAT(_binary_, filename), _end);
#define DECLARE_EMBED(filename) \
extern unsigned char CONCAT(data_, filename)[]; \
extern int CONCAT(CONCAT(data_, filename), _len);
DECLARE_EMBED(glsl_debuguniforms_h);
DECLARE_EMBED(glsl_texsample_h);
+4
View File
@@ -39,6 +39,10 @@ if(ANDROID)
list(APPEND sources
gl_replay_android.cpp
gl_hooks_android.cpp)
elseif(APPLE)
list(APPEND sources
gl_replay_apple.cpp
gl_hooks_apple.cpp)
elseif(UNIX)
list(APPEND sources
gl_replay_linux.cpp
+15
View File
@@ -75,6 +75,21 @@ struct GLWindowingData
GLXDrawable wnd;
};
#elif defined(RENDERDOC_PLATFORM_APPLE)
struct GLWindowingData
{
GLWindowingData()
{
ctx = NULL;
wnd = 0;
}
void SetCtx(void *c) { ctx = (void *)c; }
void *ctx;
void *wnd;
};
#elif defined(RENDERDOC_PLATFORM_ANDROID)
#include "EGL/egl.h"
+4 -6
View File
@@ -2790,9 +2790,7 @@ void WrappedOpenGL::ContextEndFrame()
{
Callstack::Stackwalk *call = Callstack::Collect();
RDCASSERT(call->NumLevels() < 0xff);
size_t numLevels = call->NumLevels();
uint32_t numLevels = (uint32_t)call->NumLevels();
uint64_t *stack = (uint64_t *)call->GetAddrs();
m_pSerialiser->SerialisePODArray("callstack", stack, numLevels);
@@ -2955,7 +2953,7 @@ void WrappedOpenGL::Serialise_DebugMessages()
RDCASSERT(call->NumLevels() < 0xff);
size_t numLevels = call->NumLevels();
uint32_t numLevels = (uint32_t)call->NumLevels();
uint64_t *stack = (uint64_t *)call->GetAddrs();
m_pSerialiser->SerialisePODArray("callstack", stack, numLevels);
@@ -2964,7 +2962,7 @@ void WrappedOpenGL::Serialise_DebugMessages()
}
else
{
size_t numLevels = 0;
uint32_t numLevels = 0;
uint64_t *stack = NULL;
m_pSerialiser->SerialisePODArray("callstack", stack, numLevels);
@@ -3590,7 +3588,7 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context)
if(HasCallstack)
{
size_t numLevels = 0;
uint32_t numLevels = 0;
uint64_t *stack = NULL;
m_pSerialiser->SerialisePODArray("callstack", stack, numLevels);
+83
View File
@@ -0,0 +1,83 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include <dlfcn.h>
#include <stdio.h>
#include "hooks/hooks.h"
#include "driver/gl/gl_common.h"
#include "driver/gl/gl_driver.h"
#include "driver/gl/gl_hookset.h"
#include "driver/gl/gl_hookset_defs.h"
class OpenGLHook : LibraryHook
{
public:
OpenGLHook() {}
~OpenGLHook() {}
bool CreateHooks(const char *libName) { return false; }
void EnableHooks(const char *libName, bool enable) {}
void OptionsUpdated(const char *libName) {}
};
const GLHookSet &GetRealGLFunctions()
{
static GLHookSet dummyHookset = {};
RDCUNIMPLEMENTED("GetRealGLFunctions");
return dummyHookset;
}
void MakeContextCurrent(GLWindowingData data)
{
RDCUNIMPLEMENTED("MakeContextCurrent");
}
GLWindowingData MakeContext(GLWindowingData share)
{
RDCUNIMPLEMENTED("MakeContext");
return GLWindowingData();
}
void DeleteContext(GLWindowingData context)
{
RDCUNIMPLEMENTED("DeleteContext");
}
bool immediateBegin(GLenum mode, float width, float height)
{
RDCUNIMPLEMENTED("immediateBegin");
return false;
}
void immediateVert(float x, float y, float u, float v)
{
RDCUNIMPLEMENTED("immediateVert");
}
void immediateEnd()
{
RDCUNIMPLEMENTED("immediateEnd");
}
+70
View File
@@ -0,0 +1,70 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "gl_replay.h"
#include "gl_driver.h"
#include "gl_resources.h"
void GLReplay::MakeCurrentReplayContext(GLWindowingData *ctx)
{
RDCUNIMPLEMENTED("GLReplay::MakeCurrentReplayContext");
}
void GLReplay::SwapBuffers(GLWindowingData *ctx)
{
RDCUNIMPLEMENTED("GLReplay::SwapBuffers");
}
void GLReplay::CloseReplayContext()
{
RDCUNIMPLEMENTED("GLReplay::CloseReplayContext");
}
uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth)
{
RDCUNIMPLEMENTED("GLReplay::MakeOutputWindow");
return 0;
}
void GLReplay::DestroyOutputWindow(uint64_t id)
{
RDCUNIMPLEMENTED("GLReplay::DestroyOutputWindow");
}
void GLReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h)
{
RDCUNIMPLEMENTED("GLReplay::GetOutputWindowDimensions");
}
bool GLReplay::IsOutputWindowVisible(uint64_t id)
{
RDCUNIMPLEMENTED("GLReplay::IsOutputWindowVisible");
return false;
}
ReplayCreateStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **driver)
{
RDCUNIMPLEMENTED("GL_CreateReplayDevice");
return eReplayCreate_APIHardwareUnsupported;
}
@@ -0,0 +1,79 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include <unistd.h>
#include "os/os_specific.h"
extern char **environ;
char **GetCurrentEnvironment()
{
return environ;
}
int GetIdentPort(pid_t childPid)
{
int ret = 0;
string procfile = StringFormat::Fmt("/proc/%d/net/tcp", (int)childPid);
// try for a little while for the /proc entry to appear
for(int retry = 0; retry < 10; retry++)
{
// back-off for each retry
usleep(1000 + 500 * retry);
FILE *f = FileIO::fopen(procfile.c_str(), "r");
if(f == NULL)
{
// try again in a bit
continue;
}
// read through the proc file to check for an open listen socket
while(ret == 0 && !feof(f))
{
const size_t sz = 512;
char line[sz];
line[sz - 1] = 0;
fgets(line, sz - 1, f);
int socketnum = 0, hexip = 0, hexport = 0;
int num = sscanf(line, " %d: %x:%x", &socketnum, &hexip, &hexport);
// find open listen socket on 0.0.0.0:port
if(num == 3 && hexip == 0 && hexport >= RenderDoc_FirstCaptureNetworkPort &&
hexport <= RenderDoc_LastCaptureNetworkPort)
{
ret = hexport;
break;
}
}
FileIO::fclose(f);
}
return ret;
}
@@ -61,6 +61,14 @@ const char *GetTempRootPath()
{
return "/sdcard";
}
void GetExecutableFilename(string &selfName)
{
char path[512] = {0};
readlink("/proc/self/exe", path, 511);
selfName = string(path);
}
};
namespace StringFormat
@@ -0,0 +1,40 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "os/os_specific.h"
#include <time.h>
#include <unistd.h>
double Timing::GetTickFrequency()
{
return 1000000.0;
}
uint64_t Timing::GetTick()
{
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return uint64_t(ts.tv_sec) * 1000000000ULL + uint32_t(ts.tv_nsec & 0xffffffff);
}
@@ -0,0 +1,100 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "os/os_specific.h"
class AndroidCallstack : public Callstack::Stackwalk
{
public:
AndroidCallstack()
{
RDCEraseEl(addrs);
numLevels = 0;
}
AndroidCallstack(uint64_t *calls, size_t num) { Set(calls, num); }
~AndroidCallstack() {}
void Set(uint64_t *calls, size_t num)
{
numLevels = num;
for(int i = 0; i < numLevels; i++)
addrs[i] = calls[i];
}
size_t NumLevels() const { return 0; }
const uint64_t *GetAddrs() const { return addrs; }
private:
AndroidCallstack(const Callstack::Stackwalk &other);
uint64_t addrs[128];
int numLevels;
};
namespace Callstack
{
void Init()
{
}
Stackwalk *Collect()
{
return new AndroidCallstack();
}
Stackwalk *Create()
{
return new AndroidCallstack(NULL, 0);
}
bool GetLoadedModules(char *&buf, size_t &size)
{
if(buf)
{
buf[0] = 'A';
buf[1] = 'P';
buf[2] = 'P';
buf[3] = 'L';
buf[4] = 'C';
buf[5] = 'A';
buf[6] = 'L';
buf[7] = 'L';
}
size += 8;
return true;
}
class AndroidResolver : public Callstack::StackResolver
{
public:
Callstack::AddressDetails GetAddr(uint64_t addr) { return Callstack::AddressDetails(); }
};
StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths,
volatile bool *killSignal)
{
RDCERR("Callstack resolving not supported on Apple.");
return new AndroidResolver();
}
};
+135
View File
@@ -0,0 +1,135 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include <crt_externs.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include "os/os_specific.h"
char **GetCurrentEnvironment()
{
return *_NSGetEnviron();
}
std::string execcmd(const char *cmd)
{
FILE *pipe = popen(cmd, "r");
if(!pipe)
return "ERROR";
char buffer[128];
string result = "";
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
bool isNewline(char c)
{
return c == '\n' || c == '\r';
}
int GetIdentPort(pid_t childPid)
{
string lsof = StringFormat::Fmt("lsof -p %d -a -i 4 -F n", (int)childPid);
string result = execcmd(lsof.c_str());
// Parse the result expecting:
// p<PID>
// n*:<PORT>
const size_t len = result.length();
bool found = false;
if(result[0] == 'p')
{
size_t i = 1;
for(; i < len; i++)
{
if(result[i] < '0' || result[i] > '9')
break;
}
result[i++] = 0;
if(isNewline(result[i]))
i++;
const int pid = std::stoi(&result[1]);
if(pid == (int)childPid)
{
while(i < len)
{
if(result[i] == 'n')
{
char *portStr = NULL;
for(; i < len; i++)
{
if(result[i] == ':')
{
portStr = &result[i + 1];
}
if(isNewline(result[i]))
{
result[i++] = 0;
if(i < len && isNewline(result[i]))
result[i++] = 0;
break;
}
}
const int port = std::stoi(portStr);
if(port >= RenderDoc_FirstCaptureNetworkPort && port <= RenderDoc_LastCaptureNetworkPort)
{
return port;
}
// continue on to next port
}
else
{
RDCERR("Malformed line - expected 'n':\n%s", &result[i]);
break;
}
}
}
else
{
RDCERR("pid from lsof output doesn't match childPid");
}
}
else
{
RDCERR("lsof output doesn't begin with p<PID>:\n%s", &result[0]);
}
return 0;
}
+110
View File
@@ -0,0 +1,110 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include <mach-o/dyld.h>
#include <unistd.h>
#include "os/os_specific.h"
typedef int Display;
namespace Keyboard
{
void Init()
{
}
bool PlatformHasKeyInput()
{
return false;
}
void CloneDisplay(Display *dpy)
{
}
void AddInputWindow(void *wnd)
{
}
void RemoveInputWindow(void *wnd)
{
}
bool GetKeyState(int key)
{
return false;
}
}
namespace FileIO
{
const char *GetTempRootPath()
{
return "/tmp";
}
void GetExecutableFilename(string &selfName)
{
char path[512] = {0};
uint32_t pathSize = (uint32_t)sizeof(path);
if(_NSGetExecutablePath(path, &pathSize) == 0)
{
selfName = string(path);
}
else
{
pathSize++;
char *allocPath = new char[pathSize];
memset(allocPath, 0, pathSize);
if(_NSGetExecutablePath(path, &pathSize) == 0)
{
selfName = string(path);
}
else
{
selfName = "/unknown/unknown";
RDCERR("Can't get executable name");
delete[] allocPath;
return; // don't try and readlink this
}
delete[] allocPath;
}
memset(path, 0, sizeof(path));
readlink(selfName.c_str(), path, 511);
if(path[0] != 0)
selfName = string(path);
}
};
namespace StringFormat
{
string Wide2UTF8(const std::wstring &s)
{
RDCFATAL("Converting wide strings to UTF-8 is not supported on Apple!");
return "";
}
};
@@ -0,0 +1,42 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "os/os_specific.h"
#include <mach/mach_time.h>
double Timing::GetTickFrequency()
{
mach_timebase_info_data_t timeInfo;
mach_timebase_info(&timeInfo);
uint64_t numer = timeInfo.numer;
uint64_t denom = timeInfo.denom;
return (double)numer / (double)denom;
}
uint64_t Timing::GetTick()
{
return mach_absolute_time();
}
@@ -0,0 +1,79 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include <unistd.h>
#include "os/os_specific.h"
extern char **environ;
char **GetCurrentEnvironment()
{
return environ;
}
int GetIdentPort(pid_t childPid)
{
int ret = 0;
string procfile = StringFormat::Fmt("/proc/%d/net/tcp", (int)childPid);
// try for a little while for the /proc entry to appear
for(int retry = 0; retry < 10; retry++)
{
// back-off for each retry
usleep(1000 + 500 * retry);
FILE *f = FileIO::fopen(procfile.c_str(), "r");
if(f == NULL)
{
// try again in a bit
continue;
}
// read through the proc file to check for an open listen socket
while(ret == 0 && !feof(f))
{
const size_t sz = 512;
char line[sz];
line[sz - 1] = 0;
fgets(line, sz - 1, f);
int socketnum = 0, hexip = 0, hexport = 0;
int num = sscanf(line, " %d: %x:%x", &socketnum, &hexip, &hexport);
// find open listen socket on 0.0.0.0:port
if(num == 3 && hexip == 0 && hexport >= RenderDoc_FirstCaptureNetworkPort &&
hexport <= RenderDoc_LastCaptureNetworkPort)
{
ret = hexport;
break;
}
}
FileIO::fclose(f);
}
return ret;
}
@@ -151,6 +151,14 @@ const char *GetTempRootPath()
{
return "/tmp";
}
void GetExecutableFilename(string &selfName)
{
char path[512] = {0};
readlink("/proc/self/exe", path, 511);
selfName = string(path);
}
};
namespace StringFormat
@@ -0,0 +1,40 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "os/os_specific.h"
#include <time.h>
#include <unistd.h>
double Timing::GetTickFrequency()
{
return 1000000.0;
}
uint64_t Timing::GetTick()
{
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return uint64_t(ts.tv_sec) * 1000000000ULL + uint32_t(ts.tv_nsec & 0xffffffff);
}
+13 -41
View File
@@ -23,6 +23,7 @@
******************************************************************************/
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@@ -33,6 +34,10 @@
#include "os/os_specific.h"
#include "serialise/string_utils.h"
// defined in foo/foo_process.cpp
char **GetCurrentEnvironment();
int GetIdentPort(pid_t childPid);
static vector<Process::EnvironmentModification> &GetEnvModifications()
{
static vector<Process::EnvironmentModification> envCallbacks;
@@ -78,7 +83,8 @@ void Process::RegisterEnvironmentModification(Process::EnvironmentModification m
void Process::ApplyEnvironmentModification()
{
// turn environment string to a UTF-8 map
map<string, string> currentEnv = EnvStringToEnvMap((const char **)environ);
char **currentEnvironment = GetCurrentEnvironment();
map<string, string> currentEnv = EnvStringToEnvMap((const char **)currentEnvironment);
vector<EnvironmentModification> &modifications = GetEnvModifications();
for(size_t i = 0; i < modifications.size(); i++)
@@ -297,7 +303,8 @@ uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const c
return 0;
}
return (uint32_t)RunProcess(app, workingDir, cmdLine, environ);
char **currentEnvironment = GetCurrentEnvironment();
return (uint32_t)RunProcess(app, workingDir, cmdLine, currentEnvironment);
}
uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir,
@@ -311,7 +318,8 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
}
// turn environment string to a UTF-8 map
map<string, string> env = EnvStringToEnvMap((const char **)environ);
char **currentEnvironment = GetCurrentEnvironment();
map<string, string> env = EnvStringToEnvMap((const char **)currentEnvironment);
vector<EnvironmentModification> &modifications = GetEnvModifications();
if(logfile == NULL)
@@ -400,46 +408,10 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
if(childPid != (pid_t)0)
{
// wait for child to have /proc/<pid> and read out tcp socket
// wait for child to have opened its socket
usleep(1000);
string procfile = StringFormat::Fmt("/proc/%d/net/tcp", (int)childPid);
// try for a little while for the /proc entry to appear
for(int retry = 0; retry < 10; retry++)
{
// back-off for each retry
usleep(1000 + 500 * retry);
FILE *f = FileIO::fopen(procfile.c_str(), "r");
if(f == NULL)
{
// try again in a bit
continue;
}
// read through the proc file to check for an open listen socket
while(ret == 0 && !feof(f))
{
const size_t sz = 512;
char line[sz];
line[sz - 1] = 0;
fgets(line, sz - 1, f);
int socketnum = 0, hexip = 0, hexport = 0;
int num = sscanf(line, " %d: %x:%x", &socketnum, &hexip, &hexport);
// find open listen socket on 0.0.0.0:port
if(num == 3 && hexip == 0 && hexport >= RenderDoc_FirstCaptureNetworkPort &&
hexport <= RenderDoc_LastCaptureNetworkPort)
{
ret = hexport;
}
}
FileIO::fclose(f);
}
ret = GetIdentPort(childPid);
if(waitForExit)
{
+2 -1
View File
@@ -33,7 +33,8 @@
#define OS_DEBUG_BREAK() raise(SIGTRAP)
#define GetEmbeddedResource(filename) \
string(&CONCAT(CONCAT(_binary_, filename), _start), &CONCAT(CONCAT(_binary_, filename), _end))
string(&CONCAT(data_, filename)[0], \
&CONCAT(data_, filename)[0] + CONCAT(CONCAT(data_, filename), _len))
namespace OSUtility
{
+4 -11
View File
@@ -90,14 +90,6 @@ string GetFullPathname(const string &filename)
return string(path);
}
void GetExecutableFilename(string &selfName)
{
char path[512] = {0};
readlink("/proc/self/exe", path, 511);
selfName = string(path);
}
string GetReplayAppFilename()
{
// look up the shared object's path via dladdr
@@ -146,9 +138,10 @@ string GetReplayAppFilename()
void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &logging_filename,
string &target)
{
char path[2048] = {0};
readlink("/proc/self/exe", path, 511);
const char *mod = strrchr(path, '/');
string path;
GetExecutableFilename(path);
const char *mod = strrchr(path.c_str(), '/');
if(mod == NULL)
mod = "unknown";
else
-12
View File
@@ -26,18 +26,6 @@
#include <unistd.h>
#include "os/os_specific.h"
double Timing::GetTickFrequency()
{
return 1000000.0;
}
uint64_t Timing::GetTick()
{
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return uint64_t(ts.tv_sec) * 1000000000ULL + uint32_t(ts.tv_nsec & 0xffffffff);
}
uint64_t Timing::GetUnixTimestamp()
{
return (uint64_t)time(NULL);
+16
View File
@@ -1905,6 +1905,22 @@ string ToStrHelper<false, int64_t>::Get(const int64_t &el)
return tostrBuf;
}
// this is super ugly, but I don't see a way around it - on other
// platforms size_t is typedef'd in such a way that the uint32_t or
// uint64_t specialisation will kick in. On apple, we need a
// specific size_t overload
#if defined(RENDERDOC_PLATFORM_APPLE)
template <>
string ToStrHelper<false, size_t>::Get(const size_t &el)
{
char tostrBuf[256] = {0};
StringFormat::snprintf(tostrBuf, 255, "%llu", (uint64_t)el);
return tostrBuf;
}
#endif
template <>
string ToStrHelper<false, uint64_t>::Get(const uint64_t &el)
{
+3 -4
View File
@@ -1,11 +1,11 @@
set(sources renderdoccmd.cpp)
set(definitions)
set(includes PRIVATE ${CMAKE_SOURCE_DIR}/renderdoc/api)
set(libraries PRIVATE renderdoc)
if(UNIX)
if(APPLE)
list(APPEND sources renderdoccmd_apple.cpp)
elseif(UNIX)
list(APPEND sources renderdoccmd_linux.cpp)
list(APPEND definitions PRIVATE -DLINUX)
find_package(OpenGL REQUIRED)
list(APPEND includes PRIVATE ${OPENGL_INCLUDE_DIR})
@@ -15,6 +15,5 @@ if(UNIX)
endif()
add_executable(renderdoccmd ${sources})
target_compile_definitions(renderdoccmd ${definitions})
target_include_directories(renderdoccmd ${includes})
target_link_libraries(renderdoccmd ${libraries})
+59
View File
@@ -0,0 +1,59 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include <string>
#include <locale.h>
#include <string.h>
#include <unistd.h>
#include <replay/renderdoc_replay.h>
using std::string;
string GetUsername()
{
char buf[256] = {0};
getlogin_r(buf, 255);
return string(buf, buf + strlen(buf));
}
void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg)
{
}
int renderdoccmd(int argc, char **argv);
int main(int argc, char *argv[])
{
setlocale(LC_CTYPE, "");
// do any apple-specific setup here
// process any apple-specific arguments here
return renderdoccmd(argc, argv);
}