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

Allow taking screenshots in the app menu #19126

Merged
merged 1 commit into from
May 10, 2024
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: 1 addition & 1 deletion Core/SaveState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ namespace SaveState
case SAVESTATE_SAVE_SCREENSHOT:
{
int maxResMultiplier = 2;
tempResult = TakeGameScreenshot(op.filename, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, maxResMultiplier);
tempResult = TakeGameScreenshot(nullptr, op.filename, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, maxResMultiplier);
callbackResult = tempResult ? Status::SUCCESS : Status::FAILURE;
if (!tempResult) {
ERROR_LOG(SAVESTATE, "Failed to take a screenshot for the savestate! %s", op.filename.c_str());
Expand Down
17 changes: 10 additions & 7 deletions Core/Screenshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "Core/Screenshot.h"
#include "Core/Core.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "GPU/Common/FramebufferManagerCommon.h"
#include "GPU/GPUInterface.h"
#include "GPU/GPUState.h"

Expand Down Expand Up @@ -328,28 +329,30 @@ static GPUDebugBuffer ApplyRotation(const GPUDebugBuffer &buf, DisplayRotation r
return rotated;
}

bool TakeGameScreenshot(const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width, int *height, int maxRes) {
if (!gpuDebug) {
ERROR_LOG(SYSTEM, "Can't take screenshots when GPU not running");
return false;
}
bool TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width, int *height, int maxRes) {
GPUDebugBuffer buf;
bool success = false;
u32 w = (u32)-1;
u32 h = (u32)-1;

if (type == SCREENSHOT_DISPLAY || type == SCREENSHOT_RENDER) {
if (!gpuDebug) {
ERROR_LOG(SYSTEM, "Can't take screenshots when GPU not running");
return false;
}
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 = gpuDebug->GetOutputFramebuffer(temp);
success = ::GetOutputFramebuffer(draw, buf);
if (success) {
buf = ApplyRotation(temp, g_display.rotation);
}
} else {
success = gpuDebug->GetOutputFramebuffer(buf);
_dbg_assert_(draw);
success = ::GetOutputFramebuffer(draw, buf);
}

if (!success) {
Expand Down
5 changes: 4 additions & 1 deletion Core/Screenshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "Common/File/Path.h"

struct GPUDebugBuffer;
namespace Draw {
class DrawContext;
}

enum class ScreenshotFormat {
PNG,
Expand All @@ -38,7 +41,7 @@ enum ScreenshotType {
const u8 *ConvertBufferToScreenshot(const GPUDebugBuffer &buf, bool alpha, u8 *&temp, u32 &w, u32 &h);

// Can only be used while in game.
bool TakeGameScreenshot(const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width = nullptr, int *height = nullptr, int maxRes = -1);
bool TakeGameScreenshot(Draw::DrawContext *draw, const Path &filename, ScreenshotFormat fmt, ScreenshotType type, int *width = nullptr, int *height = nullptr, int maxRes = -1);

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
17 changes: 12 additions & 5 deletions GPU/Common/FramebufferManagerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3076,15 +3076,22 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G
return retval;
}

bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
bool GetOutputFramebuffer(Draw::DrawContext *draw, GPUDebugBuffer &buffer) {
int w, h;
draw_->GetFramebufferDimensions(nullptr, &w, &h);
Draw::DataFormat fmt = draw_->PreferredFramebufferReadbackFormat(nullptr);
draw->GetFramebufferDimensions(nullptr, &w, &h);
Draw::DataFormat fmt = draw->PreferredFramebufferReadbackFormat(nullptr);
// Ignore preferred formats other than BGRA.
if (fmt != Draw::DataFormat::B8G8R8A8_UNORM)
fmt = Draw::DataFormat::R8G8B8A8_UNORM;
buffer.Allocate(w, h, fmt == Draw::DataFormat::R8G8B8A8_UNORM ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA, false);
bool retval = draw_->CopyFramebufferToMemory(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, fmt, buffer.GetData(), w, Draw::ReadbackMode::BLOCK, "GetOutputFramebuffer");

bool flipped = g_Config.iGPUBackend == (int)GPUBackend::OPENGL;

buffer.Allocate(w, h, fmt == Draw::DataFormat::R8G8B8A8_UNORM ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA, flipped);
return draw->CopyFramebufferToMemory(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, fmt, buffer.GetData(), w, Draw::ReadbackMode::BLOCK, "GetOutputFramebuffer");
}

bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
bool retval = ::GetOutputFramebuffer(draw_, buffer);
// That may have unbound the framebuffer, rebind to avoid crashes when debugging.
RebindFramebuffer("RebindFramebuffer - GetOutputFramebuffer");
return retval;
Expand Down
3 changes: 3 additions & 0 deletions GPU/Common/FramebufferManagerCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,6 @@ class FramebufferManagerCommon {
u8 *convBuf_ = nullptr;
u32 convBufSize_ = 0;
};

// Should probably live elsewhere.
bool GetOutputFramebuffer(Draw::DrawContext *draw, GPUDebugBuffer &buffer);
6 changes: 3 additions & 3 deletions UI/NativeApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ void NativeShutdownGraphics() {
INFO_LOG(SYSTEM, "NativeShutdownGraphics done");
}

static void TakeScreenshot() {
static void TakeScreenshot(Draw::DrawContext *draw) {
Path path = GetSysDirectory(DIRECTORY_SCREENSHOT);
if (!File::Exists(path)) {
File::CreateDir(path);
Expand All @@ -991,7 +991,7 @@ static void TakeScreenshot() {
i++;
}

bool success = TakeGameScreenshot(filename, g_Config.bScreenshotsAsPNG ? ScreenshotFormat::PNG : ScreenshotFormat::JPG, SCREENSHOT_OUTPUT);
bool success = TakeGameScreenshot(draw, filename, g_Config.bScreenshotsAsPNG ? ScreenshotFormat::PNG : ScreenshotFormat::JPG, SCREENSHOT_OUTPUT);
if (success) {
g_OSD.Show(OSDType::MESSAGE_FILE_LINK, filename.ToString(), 0.0f, "screenshot_link");
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
Expand All @@ -1012,7 +1012,7 @@ static void TakeScreenshot() {

void CallbackPostRender(UIContext *dc, void *userdata) {
if (g_TakeScreenshot) {
TakeScreenshot();
TakeScreenshot(dc->GetDrawContext());
g_TakeScreenshot = false;
}
}
Expand Down
2 changes: 1 addition & 1 deletion UI/ReportScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ ScreenRenderFlags ReportScreen::render(ScreenRenderMode mode) {
File::CreateDir(path);
}
screenshotFilename_ = path / ".reporting.jpg";
if (TakeGameScreenshot(screenshotFilename_, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, 4)) {
if (TakeGameScreenshot(screenManager()->getDrawContext(), screenshotFilename_, ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, 4)) {
// Redo the views already, now with a screenshot included.
RecreateViews();
} else {
Expand Down
1 change: 0 additions & 1 deletion Windows/MainWindowMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ namespace MainWindow {
EnableMenuItem(menu, ID_DEBUG_LOADSYMFILE, menuEnable);
EnableMenuItem(menu, ID_DEBUG_SAVESYMFILE, menuEnable);
EnableMenuItem(menu, ID_DEBUG_RESETSYMBOLTABLE, menuEnable);
EnableMenuItem(menu, ID_DEBUG_TAKESCREENSHOT, menuEnable);
EnableMenuItem(menu, ID_DEBUG_SHOWDEBUGSTATISTICS, menuInGameEnable);
EnableMenuItem(menu, ID_DEBUG_EXTRACTFILE, menuEnable);
EnableMenuItem(menu, ID_DEBUG_MEMORYBASE, menuInGameEnable);
Expand Down
Loading