Revert "Be less dumb."

Revert "Actually, filename really does need to be a parameter because of some random debug thing."
Revert "fix non-HAVE_WX case"
Revert "Handle screenshot saving in RenderBase.  Removes dependency on D3DX11 for screenshots (texture dumping is still broken)."

This reverts commits 00fe5057f1, 74b5fb3ab4, cd46138d29 and 5f72542e06 because taking screenshots in D3D still crashed for me so there was no point in the code changes (which I found ugly anyway).
This commit is contained in:
Tony Wasserka
2013-11-10 00:10:20 +01:00
parent 3de2ee5d46
commit 0b02880b76
7 changed files with 148 additions and 111 deletions

View File

@ -11,6 +11,9 @@
#include <cstdio>
#include "GLUtil.h"
#if defined(HAVE_WX) && HAVE_WX
#include "WxUtils.h"
#endif
#include "FileUtil.h"
@ -22,6 +25,7 @@
#include "DriverDetails.h"
#include "VideoConfig.h"
#include "Statistics.h"
#include "ImageWrite.h"
#include "PixelEngine.h"
#include "Render.h"
#include "BPStructs.h"
@ -58,6 +62,10 @@
#include "AVIDump.h"
#endif
#if defined(HAVE_WX) && HAVE_WX
#include <wx/image.h>
#endif
// glew1.8 doesn't define KHR_debug
#ifndef GL_DEBUG_OUTPUT
#define GL_DEBUG_OUTPUT 0x92E0
@ -70,6 +78,17 @@ void VideoConfig::UpdateProjectionHack()
}
#if defined(HAVE_WX) && HAVE_WX
// Screenshot thread struct
typedef struct
{
int W, H;
std::string filename;
wxImage *img;
} ScrStrct;
#endif
int OSDInternalW, OSDInternalH;
namespace OGL
@ -108,6 +127,10 @@ static u32 s_blendMode;
static bool s_vsync;
#if defined(HAVE_WX) && HAVE_WX
static std::thread scrshotThread;
#endif
// EFB cache related
static const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks.
static const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up
@ -616,6 +639,11 @@ Renderer::Renderer()
Renderer::~Renderer()
{
#if defined(HAVE_WX) && HAVE_WX
if (scrshotThread.joinable())
scrshotThread.join();
#endif
}
void Renderer::Shutdown()
@ -1391,9 +1419,11 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& r
// Save screenshot
if (s_bScreenshot)
{
TakeScreenshot(flipped_trc, s_sScreenshotName);
s_bScreenshot = false;
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
SaveScreenshot(s_sScreenshotName, flipped_trc);
// Reset settings
s_sScreenshotName.clear();
s_bScreenshot = false;
}
// Frame dumps are handled a little differently in Windows
@ -1771,22 +1801,71 @@ void Renderer::SetInterlacingMode()
void Renderer::FlipImageData(u8 *data, int w, int h)
{
// XXX make this faster
u8* __restrict top = data;
u8* bot = data + w * h * 3;
// Flip image upside down. Damn OpenGL.
for (int y = 0; y < h / 2; y++)
{
size_t stride = w * 3;
bot -= stride;
u8* __restrict brow = bot;
for(size_t x = 0; x < stride; x++)
for(int x = 0; x < w; x++)
{
std::swap(*top++, *brow++);
std::swap(data[(y * w + x) * 3], data[((h - 1 - y) * w + x) * 3]);
std::swap(data[(y * w + x) * 3 + 1], data[((h - 1 - y) * w + x) * 3 + 1]);
std::swap(data[(y * w + x) * 3 + 2], data[((h - 1 - y) * w + x) * 3 + 2]);
}
}
}
void Renderer::TakeScreenshot(const TargetRectangle &back_rc, std::string filename)
}
// TODO: remove
extern bool g_aspect_wide;
#if defined(HAVE_WX) && HAVE_WX
void TakeScreenshot(ScrStrct* threadStruct)
{
// These will contain the final image size
float FloatW = (float)threadStruct->W;
float FloatH = (float)threadStruct->H;
// Handle aspect ratio for the final ScrStrct to look exactly like what's on screen.
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH)
{
bool use16_9 = g_aspect_wide;
// Check for force-settings and override.
if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_16_9)
use16_9 = true;
else if (g_ActiveConfig.iAspectRatio == ASPECT_FORCE_4_3)
use16_9 = false;
float Ratio = (FloatW / FloatH) / (!use16_9 ? (4.0f / 3.0f) : (16.0f / 9.0f));
// If ratio > 1 the picture is too wide and we have to limit the width.
if (Ratio > 1)
FloatW /= Ratio;
// ratio == 1 or the image is too high, we have to limit the height.
else
FloatH *= Ratio;
// This is a bit expensive on high resolutions
threadStruct->img->Rescale((int)FloatW, (int)FloatH, wxIMAGE_QUALITY_HIGH);
}
// Save the screenshot and finally kill the wxImage object
// This is really expensive when saving to PNG, but not at all when using BMP
threadStruct->img->SaveFile(StrToWxStr(threadStruct->filename),
wxBITMAP_TYPE_PNG);
threadStruct->img->Destroy();
// Show success messages
OSD::AddMessage(StringFromFormat("Saved %i x %i %s", (int)FloatW, (int)FloatH,
threadStruct->filename.c_str()), 2000);
delete threadStruct;
}
#endif
namespace OGL
{
bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &back_rc)
{
u32 W = back_rc.GetWidth();
u32 H = back_rc.GetHeight();
@ -1800,13 +1879,38 @@ void Renderer::TakeScreenshot(const TargetRectangle &back_rc, std::string filena
{
free(data);
OSD::AddMessage("Error capturing or saving screenshot.", 2000);
return;
return false;
}
// Turn image upside down
FlipImageData(data, W, H);
SaveScreenshot(data, W, H, filename);
#if defined(HAVE_WX) && HAVE_WX
// Create wxImage
wxImage *a = new wxImage(W, H, data);
if (scrshotThread.joinable())
scrshotThread.join();
ScrStrct *threadStruct = new ScrStrct;
threadStruct->filename = filename;
threadStruct->img = a;
threadStruct->H = H; threadStruct->W = W;
scrshotThread = std::thread(TakeScreenshot, threadStruct);
#ifdef _WIN32
SetThreadPriority(scrshotThread.native_handle(), THREAD_PRIORITY_BELOW_NORMAL);
#endif
bool result = true;
OSD::AddMessage("Saving Screenshot... ", 2000);
#else
bool result = SaveTGA(filename.c_str(), W, H, data);
free(data);
#endif
return result;
}
}

View File

@ -63,7 +63,7 @@ public:
void RenderText(const char* pstr, int left, int top, u32 color) override;
void DrawDebugInfo();
static void FlipImageData(u8 *data, int w, int h);
void FlipImageData(u8 *data, int w, int h);
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
@ -80,7 +80,7 @@ public:
void UpdateViewport() override;
static void TakeScreenshot(const TargetRectangle &rc, std::string filename);
bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc);
private:
void UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const u32* data);

View File

@ -341,7 +341,7 @@ void VertexManager::vFlush()
tr.right = Renderer::GetTargetWidth();
tr.top = 0;
tr.bottom = Renderer::GetTargetHeight();
Renderer::TakeScreenshot(tr, str);
g_renderer->SaveScreenshot(str, tr);
}
#endif
g_Config.iSaveTargetId++;