Skip to content
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
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2411,8 +2411,6 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/Screenshot.h
Core/System.cpp
Core/System.h
Core/ThreadPools.cpp
Core/ThreadPools.h
Core/Util/AtracTrack.cpp
Core/Util/AtracTrack.h
Core/Util/AudioFormat.cpp
Expand Down
16 changes: 16 additions & 0 deletions Common/Thread/Promise.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@
#include "Common/Thread/Channel.h"
#include "Common/Thread/ThreadManager.h"

// Nobody needs to wait for this (except threadpool shutdown).
template<class T>
class IndependentTask : public Task {
public:
IndependentTask(TaskType type, TaskPriority prio, T func) : func_(std::move(func)), type_(type), prio_(prio) {}
TaskType Type() const override { return type_; }
TaskPriority Priority() const override { return prio_; }
void Run() override {
func_();
}
private:
T func_;
TaskType type_;
TaskPriority prio_;
};

template<class T>
class PromiseTask : public Task {
public:
Expand Down
2 changes: 2 additions & 0 deletions Common/Thread/ThreadManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const int MAX_CORES_TO_USE = 16;
const int MIN_IO_BLOCKING_THREADS = 4;
static constexpr size_t TASK_PRIORITY_COUNT = (size_t)TaskPriority::COUNT;

ThreadManager g_threadManager;

struct GlobalThreadContext {
std::mutex mutex;
std::deque<Task *> compute_queue[TASK_PRIORITY_COUNT];
Expand Down
2 changes: 0 additions & 2 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,6 @@
<ClCompile Include="MIPS\MIPSStackWalk.cpp" />
<ClCompile Include="Screenshot.cpp" />
<ClCompile Include="System.cpp" />
<ClCompile Include="ThreadPools.cpp" />
<ClCompile Include="TiltEventProcessor.cpp" />
<ClCompile Include="Util\AtracTrack.cpp" />
<ClCompile Include="Util\AudioFormat.cpp" />
Expand Down Expand Up @@ -1470,7 +1469,6 @@
<ClInclude Include="Screenshot.h" />
<ClInclude Include="System.h" />
<ClInclude Include="ThreadEventQueue.h" />
<ClInclude Include="ThreadPools.h" />
<ClInclude Include="TiltEventProcessor.h" />
<ClInclude Include="Util\AtracTrack.h" />
<ClInclude Include="Util\AudioFormat.h" />
Expand Down
6 changes: 0 additions & 6 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -952,9 +952,6 @@
<ClCompile Include="KeyMap.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="ThreadPools.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="Debugger\WebSocket\InputSubscriber.cpp">
<Filter>Debugger\WebSocket</Filter>
</ClCompile>
Expand Down Expand Up @@ -2034,9 +2031,6 @@
<ClInclude Include="KeyMap.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="ThreadPools.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="Debugger\WebSocket\InputSubscriber.h">
<Filter>Debugger\WebSocket</Filter>
</ClInclude>
Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/sceKernelMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <sstream>

#include "Common/Thread/ParallelLoop.h"
#include "Common/Thread/ThreadManager.h"
#include "Core/CoreTiming.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HLE/HLE.h"
Expand All @@ -30,7 +31,6 @@
#include "Core/MemMapHelpers.h"
#include "Core/Reporting.h"
#include "Core/System.h"
#include "Core/ThreadPools.h"
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"
Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/sceKernelModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ void PSPModule::GetLongInfo(char *ptr, int bufSize) const {
StringWriter w(ptr, bufSize);
w.F("%s: Version %d.%d. %d segments", nm.name, nm.version[1], nm.version[0], nm.nsegment).endl();
w.F("Memory block: %08x (%08x/%d bytes)", memoryBlockAddr, memoryBlockSize, memoryBlockSize).endl();
for (int i = 0; i < nm.nsegment; i++) {
for (int i = 0; i < (int)nm.nsegment; i++) {
w.F(" %08x (%08x bytes)\n", nm.segmentaddr[i], nm.segmentsize[i]);
}
w.F("Text: %08x (%08x bytes)\n", nm.text_addr, nm.text_size);
Expand Down
43 changes: 28 additions & 15 deletions Core/SaveState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,13 +466,12 @@ double g_lastSaveTime = -1.0;
Enqueue(Operation(SAVESTATE_REWIND, Path(), -1, callback, cbUserData));
}

void SaveScreenshot(const Path &filename, Callback callback, void *cbUserData) {
static void SaveScreenshot(const Path &filename) {
screenshotFailures = 0;
Enqueue(Operation(SAVESTATE_SAVE_SCREENSHOT, filename, -1, callback, cbUserData));
Enqueue(Operation(SAVESTATE_SAVE_SCREENSHOT, filename, -1, nullptr, nullptr));
}

bool CanRewind()
{
bool CanRewind() {
return !rewindStates.Empty();
}

Expand Down Expand Up @@ -690,7 +689,7 @@ double g_lastSaveTime = -1.0;
DeleteIfExists(shotUndo);
RenameIfExists(shot, shotUndo);
}
SaveScreenshot(shot, Callback(), 0);
SaveScreenshot(shot);
Save(fn.WithExtraExtension(".tmp"), slot, renameCallback, cbUserData);
} else {
if (callback) {
Expand Down Expand Up @@ -966,11 +965,9 @@ double g_lastSaveTime = -1.0;

bool readbackImage = false;

for (size_t i = 0, n = operations.size(); i < n; ++i) {
Operation &op = operations[i];
for (const auto &op : operations) {
CChunkFileReader::Error result;
Status callbackResult;
bool tempResult;
std::string callbackMessage;
std::string title;

Expand Down Expand Up @@ -1056,14 +1053,16 @@ double g_lastSaveTime = -1.0;
break;

case SAVESTATE_VERIFY:
tempResult = CChunkFileReader::Verify(state) == CChunkFileReader::ERROR_NONE;
{
int tempResult = CChunkFileReader::Verify(state) == CChunkFileReader::ERROR_NONE;
callbackResult = tempResult ? Status::SUCCESS : Status::FAILURE;
if (tempResult) {
INFO_LOG(Log::SaveState, "Verified save state system");
} else {
ERROR_LOG(Log::SaveState, "Save state system verification failed");
}
break;
}

case SAVESTATE_REWIND:
INFO_LOG(Log::SaveState, "Rewinding to recent savestate snapshot");
Expand Down Expand Up @@ -1093,18 +1092,32 @@ double g_lastSaveTime = -1.0;

case SAVESTATE_SAVE_SCREENSHOT:
{
_dbg_assert_(!op.callback);

int maxResMultiplier = 2;
tempResult = TakeGameScreenshot(nullptr, op.filename, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, maxResMultiplier);
callbackResult = tempResult ? Status::SUCCESS : Status::FAILURE;
if (!tempResult) {
ScreenshotResult tempResult = TakeGameScreenshot(nullptr, op.filename, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, maxResMultiplier, [](bool success) {
if (success) {
screenshotFailures = 0;
}
});

switch (tempResult) {
case ScreenshotResult::ScreenshotNotPossible:
// Try again soon, for a short while.
callbackResult = Status::FAILURE;
WARN_LOG(Log::SaveState, "Failed to take a screenshot for the savestate! (%s) The savestate will lack an icon.", op.filename.c_str());
if (coreState != CORE_STEPPING_CPU && screenshotFailures++ < SCREENSHOT_FAILURE_RETRIES) {
// Requeue for next frame (if we were stepping, no point, will just spam errors quickly).
SaveScreenshot(op.filename, op.callback, op.cbUserData);
SaveScreenshot(op.filename);
}
} else {
screenshotFailures = 0;
break;
case ScreenshotResult::DelayedResult:
case ScreenshotResult::Success:
// We might not know if the file write succeeded yet though.
callbackResult = Status::SUCCESS;
break;
}

readbackImage = true;
break;
}
Expand Down
61 changes: 31 additions & 30 deletions Core/Screenshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
#include "Common/File/FileUtil.h"
#include "Common/File/Path.h"
#include "Common/Log.h"
#include "Common/System/System.h"
#include "Common/System/Display.h"
#include "Common/System/NativeApp.h"
#include "Common/Thread/Promise.h"
#include "Core/Screenshot.h"
#include "Core/System.h"
#include "GPU/Common/GPUDebugInterface.h"
Expand Down Expand Up @@ -328,56 +331,54 @@ static GPUDebugBuffer ApplyRotation(const GPUDebugBuffer &buf, DisplayRotation r
return rotated;
}

bool TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width, int *height, int maxRes) {
ScreenshotResult TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int maxRes, std::function<void(bool success)> callback) {
GPUDebugBuffer buf;
bool success = false;
u32 w = (u32)-1;
u32 h = (u32)-1;

if (type == SCREENSHOT_DISPLAY || type == SCREENSHOT_RENDER) {
if (!gpuDebug) {
ERROR_LOG(Log::System, "Can't take screenshots when GPU not running");
return false;
return ScreenshotResult::ScreenshotNotPossible;
}
if (!gpuDebug->GetCurrentFramebuffer(buf, type == SCREENSHOT_RENDER ? GPU_DBG_FRAMEBUF_RENDER : GPU_DBG_FRAMEBUF_DISPLAY, maxRes)) {
return ScreenshotResult::ScreenshotNotPossible;
}
success = gpuDebug->GetCurrentFramebuffer(buf, type == SCREENSHOT_RENDER ? GPU_DBG_FRAMEBUF_RENDER : GPU_DBG_FRAMEBUF_DISPLAY, maxRes);
w = maxRes > 0 ? 480 * maxRes : PSP_CoreParameter().renderWidth;
h = maxRes > 0 ? 272 * maxRes : PSP_CoreParameter().renderHeight;
} else if (g_display.rotation != DisplayRotation::ROTATE_0) {
_dbg_assert_(draw);
GPUDebugBuffer temp;
success = ::GetOutputFramebuffer(draw, temp);
if (success) {
buf = ApplyRotation(temp, g_display.rotation);
if (!::GetOutputFramebuffer(draw, temp)) {
return ScreenshotResult::ScreenshotNotPossible;
}
buf = ApplyRotation(temp, g_display.rotation);
} else {
_dbg_assert_(draw);
success = ::GetOutputFramebuffer(draw, buf);
}

if (!success) {
return false;
}

if (success) {
u8 *flipbuffer = nullptr;
const u8 *buffer = ConvertBufferToScreenshot(buf, false, flipbuffer, w, h);
success = buffer != nullptr;
if (success) {
if (width)
*width = w;
if (height)
*height = h;

success = Save888RGBScreenshot(filename, fmt, buffer, w, h);
if (!GetOutputFramebuffer(draw, buf)) {
return ScreenshotResult::ScreenshotNotPossible;
}
delete[] flipbuffer;
}

if (!success) {
ERROR_LOG(Log::IO, "Failed to write screenshot.");
if (callback) {
g_threadManager.EnqueueTask(new IndependentTask(TaskType::CPU_COMPUTE, TaskPriority::LOW,
[buf = std::move(buf), callback = std::move(callback), filename, fmt, w, h]() {
u8 *flipbuffer = nullptr;
u32 width = w, height = h;
const u8 *buffer = ConvertBufferToScreenshot(buf, false, flipbuffer, width, height);
bool success = Save888RGBScreenshot(filename, fmt, buffer, width, height);
delete[] flipbuffer;
System_RunOnMainThread([success, callback = std::move(callback)]() {
callback(success);
});
}));
return ScreenshotResult::DelayedResult;
}

return success;
u8 *flipbuffer = nullptr;
const u8 *buffer = ConvertBufferToScreenshot(buf, false, flipbuffer, w, h);
bool success = Save888RGBScreenshot(filename, fmt, buffer, w, h);
delete[] flipbuffer;
return success ? ScreenshotResult::Success : ScreenshotResult::FailedToWriteFile;
}

bool Save888RGBScreenshot(const Path &filename, ScreenshotFormat fmt, const u8 *bufferRGB888, int w, int h) {
Expand Down
15 changes: 14 additions & 1 deletion Core/Screenshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "Common/File/Path.h"

#include <functional>

struct GPUDebugBuffer;
namespace Draw {
class DrawContext;
Expand All @@ -29,6 +31,8 @@ enum class ScreenshotFormat {
JPG,
};

// NOTE: The first two may need rotation, depending on the backend and screen orientation.
// This is handled internally in TakeGameScreenshot().
enum ScreenshotType {
// What's being show on screen (e.g. including FPS, etc.)
SCREENSHOT_OUTPUT,
Expand All @@ -38,10 +42,19 @@ enum ScreenshotType {
SCREENSHOT_RENDER,
};

enum class ScreenshotResult {
ScreenshotNotPossible,
DelayedResult, // This specifies that the actual result is one of the two below and will arrive in the callback.
// These result can be delayed and arrive in the callback, if one is specified.
FailedToWriteFile,
Success,
};

const u8 *ConvertBufferToScreenshot(const GPUDebugBuffer &buf, bool alpha, u8 *&temp, u32 &w, u32 &h);

// Can only be used while in game.
bool TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width = nullptr, int *height = nullptr, int maxRes = -1);
// If the callback is passed in, the saving action happens on a background thread.
ScreenshotResult TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int maxRes = -1, std::function<void(bool success)> callback = nullptr);

bool Save888RGBScreenshot(const Path &filename, ScreenshotFormat fmt, const u8 *bufferRGB888, int w, int h);
bool Save8888RGBAScreenshot(const Path &filename, const u8 *bufferRGBA8888, int w, int h);
Expand Down
3 changes: 0 additions & 3 deletions Core/ThreadPools.cpp

This file was deleted.

5 changes: 0 additions & 5 deletions Core/ThreadPools.h

This file was deleted.

6 changes: 3 additions & 3 deletions GPU/Common/GPUDebugInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ struct GPUDebugBuffer {

void ZeroBytes();

u32 GetRawPixel(int x, int y) const;
void SetRawPixel(int x, int y, u32 c);

u8 *GetData() {
return data_;
}

u32 GetRawPixel(int x, int y) const;
void SetRawPixel(int x, int y, u32 c);

const u8 *GetData() const {
return data_;
}
Expand Down
2 changes: 1 addition & 1 deletion GPU/Debugger/Record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "Common/CommonTypes.h"
#include "Common/File/FileUtil.h"
#include "Common/Thread/ThreadManager.h"
#include "Common/Thread/ParallelLoop.h"
#include "Common/Log.h"
#include "Common/StringUtils.h"
Expand All @@ -36,7 +37,6 @@
#include "Core/HLE/sceDisplay.h"
#include "Core/MemMap.h"
#include "Core/System.h"
#include "Core/ThreadPools.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "GPU/GPUCommon.h"
#include "GPU/GPUState.h"
Expand Down
3 changes: 1 addition & 2 deletions GPU/Software/SoftGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1445,8 +1445,7 @@ bool SoftGPU::GetCurrentTexture(GPUDebugBuffer &buffer, int level, bool *isFrame
return Rasterizer::GetCurrentTexture(buffer, level);
}

bool SoftGPU::GetCurrentClut(GPUDebugBuffer &buffer)
{
bool SoftGPU::GetCurrentClut(GPUDebugBuffer &buffer) {
const u32 bpp = gstate.getClutPaletteFormat() == GE_CMODE_32BIT_ABGR8888 ? 4 : 2;
const u32 pixels = 1024 / bpp;

Expand Down
Loading
Loading