| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // Copyright 2014 Citra Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #pragma once
- #include <algorithm>
- #include <functional>
- #include <vector>
- #include "core/hle/service/gsp_gpu.h"
- class GraphicsDebugger {
- public:
- // Base class for all objects which need to be notified about GPU events
- class DebuggerObserver {
- public:
- DebuggerObserver() : observed(nullptr) {}
- virtual ~DebuggerObserver() {
- if (observed)
- observed->UnregisterObserver(this);
- }
- /**
- * Called when a GX command has been processed and is ready for being
- * read via GraphicsDebugger::ReadGXCommandHistory.
- * @param total_command_count Total number of commands in the GX history
- * @note All methods in this class are called from the GSP thread
- */
- virtual void GXCommandProcessed(int total_command_count) {
- const Service::GSP::Command& cmd =
- observed->ReadGXCommandHistory(total_command_count - 1);
- LOG_TRACE(Debug_GPU, "Received command: id=%x", (int)cmd.id.Value());
- }
- protected:
- const GraphicsDebugger* GetDebugger() const {
- return observed;
- }
- private:
- GraphicsDebugger* observed;
- friend class GraphicsDebugger;
- };
- void GXCommandProcessed(u8* command_data) {
- if (observers.empty())
- return;
- gx_command_history.emplace_back();
- Service::GSP::Command& cmd = gx_command_history.back();
- memcpy(&cmd, command_data, sizeof(Service::GSP::Command));
- ForEachObserver([this](DebuggerObserver* observer) {
- observer->GXCommandProcessed(static_cast<int>(this->gx_command_history.size()));
- });
- }
- const Service::GSP::Command& ReadGXCommandHistory(int index) const {
- // TODO: Is this thread-safe?
- return gx_command_history[index];
- }
- void RegisterObserver(DebuggerObserver* observer) {
- // TODO: Check for duplicates
- observers.push_back(observer);
- observer->observed = this;
- }
- void UnregisterObserver(DebuggerObserver* observer) {
- observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
- observer->observed = nullptr;
- }
- private:
- void ForEachObserver(std::function<void(DebuggerObserver*)> func) {
- std::for_each(observers.begin(), observers.end(), func);
- }
- std::vector<DebuggerObserver*> observers;
- std::vector<Service::GSP::Command> gx_command_history;
- };
|