diff --git a/CMakeLists.txt b/CMakeLists.txt index 640d323b45..0adcdf1aff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1501,6 +1501,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/Debugger/WebSocket/InputSubscriber.h Core/Debugger/WebSocket/LogBroadcaster.cpp Core/Debugger/WebSocket/LogBroadcaster.h + Core/Debugger/WebSocket/MemoryInfoSubscriber.cpp + Core/Debugger/WebSocket/MemoryInfoSubscriber.h Core/Debugger/WebSocket/MemorySubscriber.cpp Core/Debugger/WebSocket/MemorySubscriber.h Core/Debugger/WebSocket/SteppingBroadcaster.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 30c555b669..30498dc411 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -442,6 +442,7 @@ + @@ -988,6 +989,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index f66273cddd..3ae957593a 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -980,6 +980,9 @@ Debugger + + Debugger\WebSocket + @@ -1676,6 +1679,9 @@ Debugger + + Debugger\WebSocket + diff --git a/Core/Debugger/MemBlockInfo.cpp b/Core/Debugger/MemBlockInfo.cpp index 96b18bfa52..9377599918 100644 --- a/Core/Debugger/MemBlockInfo.cpp +++ b/Core/Debugger/MemBlockInfo.cpp @@ -87,6 +87,7 @@ static MemSlabMap writeMap; static MemSlabMap textureMap; static std::vector pendingNotifies; static std::mutex pendingMutex; +static int detailedOverride; MemSlabMap::MemSlabMap() { Reset(); @@ -373,7 +374,7 @@ void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_ bool needFlush = false; // When the setting is off, we skip smaller info to keep things fast. - if (g_Config.bDebugMemInfoDetailed || size >= 0x100) { + if (size >= 0x100 || MemBlockInfoDetailed()) { PendingNotifyMem info{ flags, start, size }; info.ticks = CoreTiming::GetTicks(); info.pc = pc; @@ -472,3 +473,16 @@ void MemBlockInfoDoState(PointerWrap &p) { writeMap.DoState(p); textureMap.DoState(p); } + +// Used by the debugger. +void MemBlockOverrideDetailed() { + detailedOverride++; +} + +void MemBlockReleaseDetailed() { + detailedOverride--; +} + +bool MemBlockInfoDetailed() { + return g_Config.bDebugMemInfoDetailed || detailedOverride != 0; +} diff --git a/Core/Debugger/MemBlockInfo.h b/Core/Debugger/MemBlockInfo.h index 4e38c8410d..aec9d03725 100644 --- a/Core/Debugger/MemBlockInfo.h +++ b/Core/Debugger/MemBlockInfo.h @@ -68,3 +68,7 @@ std::string GetMemWriteTagAt(uint32_t start, uint32_t size); void MemBlockInfoInit(); void MemBlockInfoShutdown(); void MemBlockInfoDoState(PointerWrap &p); + +void MemBlockOverrideDetailed(); +void MemBlockReleaseDetailed(); +bool MemBlockInfoDetailed(); diff --git a/Core/Debugger/WebSocket.cpp b/Core/Debugger/WebSocket.cpp index c609e08698..3bd69366d0 100644 --- a/Core/Debugger/WebSocket.cpp +++ b/Core/Debugger/WebSocket.cpp @@ -57,6 +57,7 @@ #include "Core/Debugger/WebSocket/GPURecordSubscriber.h" #include "Core/Debugger/WebSocket/HLESubscriber.h" #include "Core/Debugger/WebSocket/InputSubscriber.h" +#include "Core/Debugger/WebSocket/MemoryInfoSubscriber.h" #include "Core/Debugger/WebSocket/MemorySubscriber.h" #include "Core/Debugger/WebSocket/SteppingSubscriber.h" @@ -70,6 +71,7 @@ static const std::vector subscribers({ &WebSocketGPURecordInit, &WebSocketHLEInit, &WebSocketInputInit, + &WebSocketMemoryInfoInit, &WebSocketMemoryInit, &WebSocketSteppingInit, }); diff --git a/Core/Debugger/WebSocket/MemoryInfoSubscriber.cpp b/Core/Debugger/WebSocket/MemoryInfoSubscriber.cpp new file mode 100644 index 0000000000..e81fa2d44d --- /dev/null +++ b/Core/Debugger/WebSocket/MemoryInfoSubscriber.cpp @@ -0,0 +1,73 @@ +// Copyright (c) 2021- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Core/Debugger/MemBlockInfo.h" +#include "Core/Debugger/WebSocket/MemoryInfoSubscriber.h" +#include "Core/Debugger/WebSocket/WebSocketUtils.h" + +class WebSocketMemoryInfoState : public DebuggerSubscriber { +public: + WebSocketMemoryInfoState() { + } + ~WebSocketMemoryInfoState() override { + UpdateOverride(false); + } + + void Config(DebuggerRequest &req); + +protected: + void UpdateOverride(bool flag); + + bool detailOverride_ = false; +}; + +DebuggerSubscriber *WebSocketMemoryInfoInit(DebuggerEventHandlerMap &map) { + auto p = new WebSocketMemoryInfoState(); + map["memory.info.config"] = std::bind(&WebSocketMemoryInfoState::Config, p, std::placeholders::_1); + + return p; +} + +void WebSocketMemoryInfoState::UpdateOverride(bool flag) { + if (detailOverride_ && !flag) + MemBlockReleaseDetailed(); + if (!detailOverride_ && flag) + MemBlockOverrideDetailed(); + detailOverride_ = flag; +} + +// Update memory info tracking config (memory.info.config) +// +// Parameters: +// - detailed: optional, boolean to force enable detailed tracking (perf impact.) +// +// Response (same event name): +// - detailed: boolean state of tracking before any changes. +// +// Note: Even if you set false, may stay enabled if set by user or another debug session. +void WebSocketMemoryInfoState::Config(DebuggerRequest &req) { + bool setDetailed = req.HasParam("detailed"); + bool detailed = false; + if (!req.ParamBool("detailed", &detailed, DebuggerParamType::OPTIONAL)) + return; + + JsonWriter &json = req.Respond(); + json.writeBool("detailed", MemBlockInfoDetailed()); + + if (setDetailed) + UpdateOverride(detailed); +} diff --git a/Core/Debugger/WebSocket/MemoryInfoSubscriber.h b/Core/Debugger/WebSocket/MemoryInfoSubscriber.h new file mode 100644 index 0000000000..a093c5b693 --- /dev/null +++ b/Core/Debugger/WebSocket/MemoryInfoSubscriber.h @@ -0,0 +1,22 @@ +// Copyright (c) 2021- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "Core/Debugger/WebSocket/WebSocketUtils.h" + +DebuggerSubscriber *WebSocketMemoryInfoInit(DebuggerEventHandlerMap &map); diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index bccf2ce748..9a34a8ab94 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -1257,7 +1257,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 int avret = swr_convert(atrac->swrCtx_, &out, numSamples, inbuf, numSamples); if (outbufPtr != 0) { u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16); - if (packetAddr != 0 && g_Config.bDebugMemInfoDetailed) { + if (packetAddr != 0 && MemBlockInfoDetailed()) { const std::string tag = "AtracDecode/" + GetMemWriteTagAt(packetAddr, packetSize); NotifyMemInfo(MemBlockFlags::READ, packetAddr, packetSize, tag.c_str(), tag.size()); NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, tag.c_str(), tag.size()); diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index e974f4de54..31de118345 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -149,7 +149,7 @@ void VagDecoder::GetSamples(s16 *outSamples, int numSamples) { } if (readp > origp) { - if (g_Config.bDebugMemInfoDetailed) + if (MemBlockInfoDetailed()) NotifyMemInfo(MemBlockFlags::READ, read_, readp - origp, "SasVagDecoder"); read_ += readp - origp; } @@ -582,7 +582,7 @@ void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) { if (outputMode == PSP_SAS_OUTPUTMODE_MIXED) { // Okay, apply effects processing to the Send buffer. WriteMixedOutput(outp, inp, leftVol, rightVol); - if (g_Config.bDebugMemInfoDetailed) { + if (MemBlockInfoDetailed()) { if (inp) NotifyMemInfo(MemBlockFlags::READ, inAddr, grainSize * sizeof(u16) * 2, "SasMix"); NotifyMemInfo(MemBlockFlags::WRITE, outAddr, grainSize * sizeof(u16) * 2, "SasMix"); diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index c72b42d206..77d9054999 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -404,6 +404,7 @@ + @@ -637,6 +638,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index f324ec0208..1c49dfe521 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -697,6 +697,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket @@ -1512,6 +1515,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 04a223215c..38aba84863 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -418,6 +418,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/Debugger/WebSocket/InputSubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/LogBroadcaster.cpp \ $(SRC)/Core/Debugger/WebSocket/MemorySubscriber.cpp \ + $(SRC)/Core/Debugger/WebSocket/MemoryInfoSubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/SteppingBroadcaster.cpp \ $(SRC)/Core/Debugger/WebSocket/SteppingSubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/WebSocketUtils.cpp \