mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
GPU: Rotate screenshot framebuffer per display.
This commit is contained in:
parent
1197795945
commit
28a4057115
@ -24,6 +24,7 @@
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/System/Display.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Screenshot.h"
|
||||
#include "Core/Core.h"
|
||||
@ -295,6 +296,36 @@ const u8 *ConvertBufferToScreenshot(const GPUDebugBuffer &buf, bool alpha, u8 *&
|
||||
return temp ? temp : buffer;
|
||||
}
|
||||
|
||||
static GPUDebugBuffer ApplyRotation(const GPUDebugBuffer &buf, DisplayRotation rotation) {
|
||||
GPUDebugBuffer rotated;
|
||||
|
||||
// This is a simple but not terribly efficient rotation.
|
||||
if (rotation == DisplayRotation::ROTATE_90) {
|
||||
rotated.Allocate(buf.GetHeight(), buf.GetStride(), buf.GetFormat(), false);
|
||||
for (u32 y = 0; y < buf.GetStride(); ++y) {
|
||||
for (u32 x = 0; x < buf.GetHeight(); ++x) {
|
||||
rotated.SetRawPixel(x, y, buf.GetRawPixel(buf.GetStride() - y - 1, x));
|
||||
}
|
||||
}
|
||||
} else if (rotation == DisplayRotation::ROTATE_180) {
|
||||
rotated.Allocate(buf.GetStride(), buf.GetHeight(), buf.GetFormat(), false);
|
||||
for (u32 y = 0; y < buf.GetHeight(); ++y) {
|
||||
for (u32 x = 0; x < buf.GetStride(); ++x) {
|
||||
rotated.SetRawPixel(x, y, buf.GetRawPixel(buf.GetStride() - x - 1, buf.GetHeight() - y - 1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rotated.Allocate(buf.GetHeight(), buf.GetStride(), buf.GetFormat(), false);
|
||||
for (u32 y = 0; y < buf.GetStride(); ++y) {
|
||||
for (u32 x = 0; x < buf.GetHeight(); ++x) {
|
||||
rotated.SetRawPixel(x, y, buf.GetRawPixel(y, buf.GetHeight() - x - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rotated;
|
||||
}
|
||||
|
||||
bool TakeGameScreenshot(const char *filename, ScreenshotFormat fmt, ScreenshotType type, int *width, int *height, int maxRes) {
|
||||
if (!gpuDebug) {
|
||||
ERROR_LOG(SYSTEM, "Can't take screenshots when GPU not running");
|
||||
@ -311,6 +342,12 @@ bool TakeGameScreenshot(const char *filename, ScreenshotFormat fmt, ScreenshotTy
|
||||
// Only crop to the top left when using a render screenshot.
|
||||
w = maxRes > 0 ? 480 * maxRes : PSP_CoreParameter().renderWidth;
|
||||
h = maxRes > 0 ? 272 * maxRes : PSP_CoreParameter().renderHeight;
|
||||
} else if (g_display_rotation != DisplayRotation::ROTATE_0) {
|
||||
GPUDebugBuffer temp;
|
||||
success = gpuDebug->GetOutputFramebuffer(temp);
|
||||
if (success) {
|
||||
buf = ApplyRotation(temp, g_display_rotation);
|
||||
}
|
||||
} else {
|
||||
success = gpuDebug->GetOutputFramebuffer(buf);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ void GPUDebugBuffer::Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt,
|
||||
fmt_ = fmt;
|
||||
flipped_ = flipped;
|
||||
|
||||
u32 pixelSize = PixelSize(fmt);
|
||||
u32 pixelSize = PixelSize();
|
||||
data_ = new u8[pixelSize * stride * height];
|
||||
}
|
||||
|
||||
@ -50,8 +50,8 @@ void GPUDebugBuffer::Free() {
|
||||
data_ = NULL;
|
||||
}
|
||||
|
||||
u32 GPUDebugBuffer::PixelSize(GPUDebugBufferFormat fmt) const {
|
||||
switch (fmt) {
|
||||
u32 GPUDebugBuffer::PixelSize() const {
|
||||
switch (fmt_) {
|
||||
case GPU_DBG_FORMAT_8888:
|
||||
case GPU_DBG_FORMAT_8888_BGRA:
|
||||
case GPU_DBG_FORMAT_FLOAT:
|
||||
@ -81,7 +81,7 @@ u32 GPUDebugBuffer::GetRawPixel(int x, int y) const {
|
||||
y = height_ - y - 1;
|
||||
}
|
||||
|
||||
u32 pixelSize = PixelSize(fmt_);
|
||||
u32 pixelSize = PixelSize();
|
||||
u32 byteOffset = pixelSize * (stride_ * y + x);
|
||||
const u8 *ptr = &data_[byteOffset];
|
||||
|
||||
@ -98,3 +98,36 @@ u32 GPUDebugBuffer::GetRawPixel(int x, int y) const {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GPUDebugBuffer::SetRawPixel(int x, int y, u32 c) {
|
||||
if (data_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (flipped_) {
|
||||
y = height_ - y - 1;
|
||||
}
|
||||
|
||||
u32 pixelSize = PixelSize();
|
||||
u32 byteOffset = pixelSize * (stride_ * y + x);
|
||||
u8 *ptr = &data_[byteOffset];
|
||||
|
||||
switch (pixelSize) {
|
||||
case 4:
|
||||
*(u32 *)ptr = c;
|
||||
break;
|
||||
case 3:
|
||||
ptr[0] = (c >> 0) & 0xFF;
|
||||
ptr[1] = (c >> 8) & 0xFF;
|
||||
ptr[2] = (c >> 16) & 0xFF;
|
||||
break;
|
||||
case 2:
|
||||
*(u16 *)ptr = (u16)c;
|
||||
break;
|
||||
case 1:
|
||||
*ptr = (u8)c;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -140,6 +140,7 @@ struct GPUDebugBuffer {
|
||||
}
|
||||
|
||||
u32 GetRawPixel(int x, int y) const;
|
||||
void SetRawPixel(int x, int y, u32 c);
|
||||
|
||||
const u8 *GetData() const {
|
||||
return data_;
|
||||
@ -161,9 +162,9 @@ struct GPUDebugBuffer {
|
||||
return fmt_;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 PixelSize(GPUDebugBufferFormat fmt) const;
|
||||
u32 PixelSize() const;
|
||||
|
||||
private:
|
||||
bool alloc_ = false;
|
||||
u8 *data_ = nullptr;
|
||||
u32 stride_ = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user