Simple UI for frame seeking.

This commit is contained in:
Ben Vanik
2015-02-21 11:19:00 -08:00
parent 5227fe72b5
commit 07c592942f
14 changed files with 795 additions and 202 deletions

View File

@@ -93,8 +93,6 @@ uint64_t CommandProcessor::QueryTime() {
bool CommandProcessor::Initialize(std::unique_ptr<GLContext> context) {
context_ = std::move(context);
pending_fn_event_ = CreateEvent(nullptr, TRUE, FALSE, nullptr);
worker_running_ = true;
worker_thread_ = std::thread([this]() {
poly::threading::set_name("GL4 Worker");
@@ -118,8 +116,6 @@ void CommandProcessor::Shutdown() {
shader_cache_.clear();
context_.reset();
CloseHandle(pending_fn_event_);
}
void CommandProcessor::BeginTracing(const std::wstring& root_path) {
@@ -130,10 +126,12 @@ void CommandProcessor::BeginTracing(const std::wstring& root_path) {
void CommandProcessor::EndTracing() { trace_writer_.Close(); }
void CommandProcessor::CallInThread(std::function<void()> fn) {
assert_null(pending_fn_);
pending_fn_ = std::move(fn);
WaitForSingleObject(pending_fn_event_, INFINITE);
ResetEvent(pending_fn_event_);
if (pending_fns_.empty() &&
worker_thread_.get_id() == std::this_thread::get_id()) {
fn();
} else {
pending_fns_.push(std::move(fn));
}
}
void CommandProcessor::WorkerMain() {
@@ -144,11 +142,10 @@ void CommandProcessor::WorkerMain() {
}
while (worker_running_) {
if (pending_fn_) {
auto fn = std::move(pending_fn_);
pending_fn_ = nullptr;
while (!pending_fns_.empty()) {
auto fn = std::move(pending_fns_.front());
pending_fns_.pop();
fn();
SetEvent(pending_fn_event_);
}
uint32_t write_ptr_index = write_ptr_index_.load();
@@ -166,10 +163,10 @@ void CommandProcessor::WorkerMain() {
SwitchToThread();
MemoryBarrier();
write_ptr_index = write_ptr_index_.load();
} while (!pending_fn_ && (write_ptr_index == 0xBAADF00D ||
read_ptr_index_ == write_ptr_index));
} while (pending_fns_.empty() && (write_ptr_index == 0xBAADF00D ||
read_ptr_index_ == write_ptr_index));
// ReturnFromWait();
if (pending_fn_) {
if (!pending_fns_.empty()) {
continue;
}
}

View File

@@ -13,6 +13,7 @@
#include <atomic>
#include <functional>
#include <memory>
#include <queue>
#include <thread>
#include <unordered_map>
#include <vector>
@@ -212,8 +213,7 @@ class CommandProcessor {
std::atomic<bool> worker_running_;
std::unique_ptr<GLContext> context_;
SwapHandler swap_handler_;
std::function<void()> pending_fn_;
HANDLE pending_fn_event_;
std::queue<std::function<void()>> pending_fns_;
SwapMode swap_mode_;

View File

@@ -126,99 +126,102 @@ void GL4GraphicsSystem::RequestSwap() {
command_processor_->CallInThread([&]() { command_processor_->IssueSwap(); });
}
const uint8_t* GL4GraphicsSystem::PlayTrace(const uint8_t* trace_data,
size_t trace_size,
TracePlaybackMode playback_mode) {
auto trace_ptr = trace_data;
command_processor_->CallInThread([&]() {
bool pending_break = false;
const PacketStartCommand* pending_packet = nullptr;
while (trace_ptr < trace_data + trace_size) {
auto type =
static_cast<TraceCommandType>(poly::load<uint32_t>(trace_ptr));
switch (type) {
case TraceCommandType::kPrimaryBufferStart: {
auto cmd =
reinterpret_cast<const PrimaryBufferStartCommand*>(trace_ptr);
//
trace_ptr += sizeof(*cmd) + cmd->count * 4;
break;
}
case TraceCommandType::kPrimaryBufferEnd: {
auto cmd =
reinterpret_cast<const PrimaryBufferEndCommand*>(trace_ptr);
//
trace_ptr += sizeof(*cmd);
break;
}
case TraceCommandType::kIndirectBufferStart: {
auto cmd =
reinterpret_cast<const IndirectBufferStartCommand*>(trace_ptr);
//
trace_ptr += sizeof(*cmd) + cmd->count * 4;
break;
}
case TraceCommandType::kIndirectBufferEnd: {
auto cmd =
reinterpret_cast<const IndirectBufferEndCommand*>(trace_ptr);
//
trace_ptr += sizeof(*cmd);
break;
}
case TraceCommandType::kPacketStart: {
auto cmd = reinterpret_cast<const PacketStartCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
std::memcpy(memory()->Translate(cmd->base_ptr), trace_ptr,
cmd->count * 4);
trace_ptr += cmd->count * 4;
pending_packet = cmd;
break;
}
case TraceCommandType::kPacketEnd: {
auto cmd = reinterpret_cast<const PacketEndCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
if (pending_packet) {
command_processor_->ExecutePacket(pending_packet->base_ptr,
pending_packet->count);
pending_packet = nullptr;
}
if (pending_break) {
return;
}
break;
}
case TraceCommandType::kMemoryRead: {
auto cmd = reinterpret_cast<const MemoryReadCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
std::memcpy(memory()->Translate(cmd->base_ptr), trace_ptr,
cmd->length);
trace_ptr += cmd->length;
break;
}
case TraceCommandType::kMemoryWrite: {
auto cmd = reinterpret_cast<const MemoryWriteCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
// ?
trace_ptr += cmd->length;
break;
}
case TraceCommandType::kEvent: {
auto cmd = reinterpret_cast<const EventCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
switch (cmd->event_type) {
case EventType::kSwap: {
if (playback_mode == TracePlaybackMode::kBreakOnSwap) {
pending_break = true;
void GL4GraphicsSystem::PlayTrace(const uint8_t* trace_data, size_t trace_size,
TracePlaybackMode playback_mode) {
command_processor_->CallInThread(
[this, trace_data, trace_size, playback_mode]() {
command_processor_->set_swap_mode(SwapMode::kIgnored);
auto trace_ptr = trace_data;
bool pending_break = false;
const PacketStartCommand* pending_packet = nullptr;
while (trace_ptr < trace_data + trace_size) {
auto type =
static_cast<TraceCommandType>(poly::load<uint32_t>(trace_ptr));
switch (type) {
case TraceCommandType::kPrimaryBufferStart: {
auto cmd =
reinterpret_cast<const PrimaryBufferStartCommand*>(trace_ptr);
//
trace_ptr += sizeof(*cmd) + cmd->count * 4;
break;
}
case TraceCommandType::kPrimaryBufferEnd: {
auto cmd =
reinterpret_cast<const PrimaryBufferEndCommand*>(trace_ptr);
//
trace_ptr += sizeof(*cmd);
break;
}
case TraceCommandType::kIndirectBufferStart: {
auto cmd = reinterpret_cast<const IndirectBufferStartCommand*>(
trace_ptr);
//
trace_ptr += sizeof(*cmd) + cmd->count * 4;
break;
}
case TraceCommandType::kIndirectBufferEnd: {
auto cmd =
reinterpret_cast<const IndirectBufferEndCommand*>(trace_ptr);
//
trace_ptr += sizeof(*cmd);
break;
}
case TraceCommandType::kPacketStart: {
auto cmd = reinterpret_cast<const PacketStartCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
std::memcpy(memory()->Translate(cmd->base_ptr), trace_ptr,
cmd->count * 4);
trace_ptr += cmd->count * 4;
pending_packet = cmd;
break;
}
case TraceCommandType::kPacketEnd: {
auto cmd = reinterpret_cast<const PacketEndCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
if (pending_packet) {
command_processor_->ExecutePacket(pending_packet->base_ptr,
pending_packet->count);
pending_packet = nullptr;
}
if (pending_break) {
return;
}
break;
}
case TraceCommandType::kMemoryRead: {
auto cmd = reinterpret_cast<const MemoryReadCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
std::memcpy(memory()->Translate(cmd->base_ptr), trace_ptr,
cmd->length);
trace_ptr += cmd->length;
break;
}
case TraceCommandType::kMemoryWrite: {
auto cmd = reinterpret_cast<const MemoryWriteCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
// ?
trace_ptr += cmd->length;
break;
}
case TraceCommandType::kEvent: {
auto cmd = reinterpret_cast<const EventCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
switch (cmd->event_type) {
case EventType::kSwap: {
if (playback_mode == TracePlaybackMode::kBreakOnSwap) {
pending_break = true;
}
break;
}
}
break;
}
}
break;
}
}
}
});
return trace_ptr;
command_processor_->set_swap_mode(SwapMode::kNormal);
});
}
void GL4GraphicsSystem::MarkVblank() {

View File

@@ -38,8 +38,8 @@ class GL4GraphicsSystem : public GraphicsSystem {
void RequestSwap() override;
const uint8_t* PlayTrace(const uint8_t* trace_data, size_t trace_size,
TracePlaybackMode playback_mode) override;
void PlayTrace(const uint8_t* trace_data, size_t trace_size,
TracePlaybackMode playback_mode) override;
private:
void MarkVblank();

View File

@@ -91,6 +91,9 @@ LRESULT WGLControl::WndProc(HWND hWnd, UINT message, WPARAM wParam,
current_paint_callback_ = nullptr;
}
poly::ui::UIEvent e(this);
OnPaint(e);
// TODO(benvanik): profiler present.
Profiler::Present();
}