Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SDL for replay. #88

Merged
merged 1 commit into from
Jun 19, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions qtcreator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ add_definitions("-DVOGL_USE_LINUX_API=1")
add_definitions("-DSDL_VIDEO_OPENGL_GLX=1")
add_definitions("-DSDL_VIDEO_DRIVER_X11=1")
add_definitions("-DSDL_VIDEO_DRIVER_X11_DYNAMIC=1")
add_definitions("-DVOGL_PLATFORM_HAS_SDL=1")
add_definitions("-DVOGL_PLATFORM_HAS_X11=1")
add_definitions("-DVOGL_PLATFORM_HAS_GLX=1")
add_definitions("-DPLATFORM_POSIX=1")
Expand Down
1 change: 0 additions & 1 deletion src/voglbench/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,3 @@ target_link_libraries(${PROJECT_NAME}
)

build_options_finalize()

348 changes: 0 additions & 348 deletions src/voglbench/voglbench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@
#include "SDL.h"
#endif

#if defined(PLATFORM_POSIX)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#endif

//$ TODO: investigate using SDL for windows and any keyboard controls.
//$ Run clang-format on everything.
//$ Use Telemetry to speed this bugger up.
Expand Down Expand Up @@ -313,41 +307,6 @@ static void voglbench_deinit()
colorized_console::deinit();
}

#if VOGL_PLATFORM_HAS_X11
//----------------------------------------------------------------------------------------------------------------------
// X11_Pending - from SDL
//----------------------------------------------------------------------------------------------------------------------
static int X11_Pending(Display *display)
{
VOGL_FUNC_TRACER

/* Flush the display connection and look to see if events are queued */
XFlush(display);
if (XEventsQueued(display, QueuedAlready))
{
return 1;
}

/* More drastic measures are required -- see if X is ready to talk */
{
static struct timeval zero_time; /* static == 0 */
int x11_fd;
fd_set fdset;

x11_fd = ConnectionNumber(display);
FD_ZERO(&fdset);
FD_SET(x11_fd, &fdset);
if (select(x11_fd + 1, &fdset, NULL, NULL, &zero_time) == 1)
{
return (XPending(display));
}
}

/* Oh well, nothing is ready .. */
return 0;
}
#endif

//----------------------------------------------------------------------------------------------------------------------
// get_replayer_flags_from_command_line_params
//----------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -619,309 +578,6 @@ static uint get_replayer_flags_from_command_line_params()
error_exit:
return false;
}

#elif (VOGL_PLATFORM_HAS_X11)
//----------------------------------------------------------------------------------------------------------------------
// tool_replay_mode
//----------------------------------------------------------------------------------------------------------------------
static bool tool_replay_mode()
{
VOGL_FUNC_TRACER

dynamic_string trace_filename(g_command_line_params().get_value_as_string_or_empty("", 1));
if (trace_filename.is_empty())
{
vogl_error_printf("No trace file specified!\n");
return false;
}

dynamic_string actual_trace_filename;
vogl_unique_ptr<vogl_trace_file_reader> pTrace_reader(vogl_open_trace_file(
trace_filename,
actual_trace_filename,
g_command_line_params().get_value_as_string_or_empty("loose_file_path").get_ptr()));
if (!pTrace_reader.get())
{
vogl_error_printf("File not found, or unable to determine file type of trace file \"%s\"\n", trace_filename.get_ptr());
return false;
}

vogl_printf("Reading trace file %s\n", actual_trace_filename.get_ptr());

vogl_gl_replayer replayer;
vogl_replay_window window;

uint replayer_flags = get_replayer_flags_from_command_line_params();

// TODO: This will create a window with default attributes, which seems fine for the majority of traces.
// Unfortunately, some GL call streams *don't* want an alpha channel, or depth, or stencil etc. in the default framebuffer so this may become a problem.
// Also, this design only supports a single window, which is going to be a problem with multiple window traces.
if (!window.open(g_command_line_params().get_value_as_int("width", 0, 1024, 1, 65535), g_command_line_params().get_value_as_int("height", 0, 768, 1, 65535), g_command_line_params().get_value_as_int("msaa", 0, 0, 0, 65535)))
{
vogl_error_printf("Failed initializing replay window\n");
return false;
}

if (!replayer.init(replayer_flags, &window, pTrace_reader->get_sof_packet(), pTrace_reader->get_multi_blob_manager()))
{
vogl_error_printf("Failed initializing GL replayer\n");
return false;
}

// Disable all glGetError() calls in vogl_utils.cpp.
vogl_disable_gl_get_error();

XSelectInput(window.get_display(), window.get_xwindow(),
EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask);

Atom wmDeleteMessage = XInternAtom(window.get_display(), "WM_DELETE_WINDOW", False);
XSetWMProtocols(window.get_display(), window.get_xwindow(), &wmDeleteMessage, 1);

// Bool win_mapped = false;

vogl_gl_state_snapshot *pSnapshot = NULL;
int64_t snapshot_loop_start_frame = -1;
int64_t snapshot_loop_end_frame = -1;

vogl::hash_map<uint64_t> keys_pressed, keys_down;

int loop_frame = g_command_line_params().get_value_as_int("loop_frame", 0, -1);
int loop_len = math::maximum<int>(g_command_line_params().get_value_as_int("loop_len", 0, 1), 1);
int loop_count = math::maximum<int>(g_command_line_params().get_value_as_int("loop_count", 0, cINT32_MAX), 1);
bool endless_mode = g_command_line_params().get_value_as_bool("endless");

timer tm;
tm.start();

for (;;)
{
tmZone(TELEMETRY_LEVEL0, TMZF_NONE, "Main Loop");

while (X11_Pending(window.get_display()))
{
XEvent newEvent;

// Watch for new X eventsn
XNextEvent(window.get_display(), &newEvent);

switch (newEvent.type)
{
case KeyPress:
{
KeySym xsym = XLookupKeysym(&newEvent.xkey, 0);

//printf("KeyPress 0%04llX %" PRIu64 "\n", (uint64_t)xsym, (uint64_t)xsym);

keys_down.insert(xsym);
keys_pressed.insert(xsym);

break;
}
case KeyRelease:
{
KeySym xsym = XLookupKeysym(&newEvent.xkey, 0);

//printf("KeyRelease 0x%04llX %" PRIu64 "\n", (uint64_t)xsym, (uint64_t)xsym);

keys_down.erase(xsym);

break;
}
case FocusIn:
case FocusOut:
{
//printf("FocusIn/FocusOut\n");

keys_down.reset();

break;
}
case MappingNotify:
{
//XRefreshKeyboardMapping(&newEvent);
break;
}
case UnmapNotify:
{
// printf("UnmapNotify\n");
// win_mapped = false;

keys_down.reset();

break;
}
case MapNotify:
{
// printf("MapNotify\n");
// win_mapped = true;

keys_down.reset();

if (!replayer.update_window_dimensions())
goto error_exit;

break;
}
case ConfigureNotify:
{
if (!replayer.update_window_dimensions())
goto error_exit;

break;
}
case DestroyNotify:
{
vogl_message_printf("Exiting\n");
goto normal_exit;
}
case ClientMessage:
{
if (newEvent.xclient.data.l[0] == (int)wmDeleteMessage)
{
vogl_message_printf("Exiting\n");
goto normal_exit;
}

break;
}
default:
break;
}
}

if (replayer.get_at_frame_boundary())
{
if ((!pSnapshot) && (loop_frame != -1) && (static_cast<int64_t>(replayer.get_frame_index()) == loop_frame))
{
vogl_debug_printf("Capturing replayer state at start of frame %u\n", replayer.get_frame_index());

pSnapshot = replayer.snapshot_state();

if (pSnapshot)
{
vogl_printf("Snapshot succeeded\n");

snapshot_loop_start_frame = pTrace_reader->get_cur_frame();
snapshot_loop_end_frame = pTrace_reader->get_cur_frame() + loop_len;

vogl_debug_printf("Loop start: %" PRIi64 " Loop end: %" PRIi64 "\n", snapshot_loop_start_frame, snapshot_loop_end_frame);
}
else
{
vogl_error_printf("Snapshot failed!\n");
loop_frame = -1;
}
}
}

vogl_gl_replayer::status_t status = replayer.process_pending_window_resize();
if (status == vogl_gl_replayer::cStatusOK)
{
for (;;)
{
if (replayer.has_pending_packets())
{
status = replayer.process_pending_packets();
}
else
{
status = replayer.process_next_packet(*pTrace_reader);
}

if ((status == vogl_gl_replayer::cStatusNextFrame) ||
(status == vogl_gl_replayer::cStatusResizeWindow) ||
(status == vogl_gl_replayer::cStatusAtEOF) ||
(status == vogl_gl_replayer::cStatusHardFailure))
{
break;
}
}
}

if (status == vogl_gl_replayer::cStatusHardFailure)
break;

if (status == vogl_gl_replayer::cStatusAtEOF)
{
vogl_message_printf("At trace EOF, frame index %u\n", replayer.get_frame_index());
}

if (replayer.get_at_frame_boundary() &&
pSnapshot &&
(loop_count > 0) &&
((pTrace_reader->get_cur_frame() == snapshot_loop_end_frame) || (status == vogl_gl_replayer::cStatusAtEOF)))
{
status = replayer.begin_applying_snapshot(pSnapshot, false);
if ((status != vogl_gl_replayer::cStatusOK) && (status != vogl_gl_replayer::cStatusResizeWindow))
goto error_exit;

pTrace_reader->seek_to_frame(static_cast<uint>(snapshot_loop_start_frame));

vogl_debug_printf("Applying snapshot and seeking back to frame %" PRIi64 "\n", snapshot_loop_start_frame);
loop_count--;
}
else
{
bool print_progress = (status == vogl_gl_replayer::cStatusAtEOF) ||
((replayer.get_at_frame_boundary()) && ((replayer.get_frame_index() % 100) == 0));
if (print_progress)
{
if (pTrace_reader->get_type() == cBINARY_TRACE_FILE_READER)
{
vogl_binary_trace_file_reader &binary_trace_reader = *static_cast<vogl_binary_trace_file_reader *>(pTrace_reader.get());

vogl_printf("Replay now at frame index %u, trace file offet %" PRIu64 ", GL call counter %" PRIu64 ", %3.2f%% percent complete\n",
replayer.get_frame_index(),
binary_trace_reader.get_cur_file_ofs(),
replayer.get_last_parsed_call_counter(),
binary_trace_reader.get_trace_file_size() ? (binary_trace_reader.get_cur_file_ofs() * 100.0f) / binary_trace_reader.get_trace_file_size() : 0);
}
}

if (status == vogl_gl_replayer::cStatusAtEOF)
{
if (!endless_mode)
{
double time_since_start = tm.get_elapsed_secs();

vogl_printf("%u total swaps, %.3f secs, %3.3f avg fps\n", replayer.get_total_swaps(), time_since_start, replayer.get_frame_index() / time_since_start);
break;
}

vogl_printf("Resetting state and rewinding back to frame 0\n");

replayer.reset_state();

if (!pTrace_reader->seek_to_frame(0))
{
vogl_error_printf("Failed rewinding trace reader!\n");
goto error_exit;
}
}
}

telemetry_tick();
}

normal_exit:
return true;

error_exit:
return false;
}

//----------------------------------------------------------------------------------------------------------------------
// xerror_handler
//----------------------------------------------------------------------------------------------------------------------
static int xerror_handler(Display *dsp, XErrorEvent *error)
{
char error_string[256];
XGetErrorText(dsp, error->error_code, error_string, sizeof(error_string));

fprintf(stderr, "voglbench: Fatal X Windows Error: %s\n", error_string);
abort();
}

#else
#error "Need to provide tool_replay_mode for this platform."
#endif
Expand All @@ -943,10 +599,6 @@ int main(int argc, char *argv[])
// Initialize vogl_core.
vogl_core_init();

#if VOGL_PLATFORM_HAS_X11
XSetErrorHandler(xerror_handler);
#endif

if (!voglbench_init(argc, argv))
{
voglbench_deinit();
Expand Down
Loading