Merge pull request #8224 from hrydgard/clear-optimization

Don't clear at the start of frame, only when it's time to actually draw to the backbuffer
This commit is contained in:
Henrik Rydgård 2015-11-18 17:58:12 +01:00
commit ba2adb8502
10 changed files with 81 additions and 34 deletions

View File

@ -223,8 +223,8 @@ namespace DX9 {
// (it always runs at output resolution so FXAA may look odd).
float x, y, w, h;
int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, uvRotation);
DrawActiveTexture(drawPixelsTex_, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, uvRotation);
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation);
DrawActiveTexture(drawPixelsTex_, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, uvRotation);
}
void FramebufferManagerDX9::DrawActiveTexture(LPDIRECT3DTEXTURE9 tex, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation) {
@ -679,6 +679,8 @@ namespace DX9 {
void FramebufferManagerDX9::CopyDisplayToOutput() {
fbo_unbind();
if (useBufferedRendering_) {
// In buffered, we no longer clear the backbuffer before we start rendering.
ClearBuffer();
DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
}
currentRenderVfb_ = 0;
@ -744,8 +746,9 @@ namespace DX9 {
}
} else {
DEBUG_LOG(SCEGE, "Found no FBO to display! displayFBPtr = %08x", displayFramebufPtr_);
// No framebuffer to display! Clear to black.
ClearBuffer();
// No framebuffer to display! Clear to black. If buffered, we already did that.
if (!useBufferedRendering_)
ClearBuffer();
return;
}
}
@ -763,10 +766,6 @@ namespace DX9 {
}
displayFramebuf_ = vfb;
if (resized_) {
ClearBuffer();
}
if (vfb->fbo) {
DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address);
DisableState();

View File

@ -424,6 +424,7 @@ void FramebufferManager::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY,
}
void FramebufferManager::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) {
MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_Config.iTexFiltering == TEX_FILTER_NEAREST ? GL_NEAREST : GL_LINEAR);
@ -973,6 +974,19 @@ struct CardboardSettings * FramebufferManager::GetCardboardSettings(struct Cardb
void FramebufferManager::CopyDisplayToOutput() {
fbo_unbind();
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
if (useBufferedRendering_) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef USING_GLES2
glClearDepthf(0.0f);
#else
glClearDepth(0.0);
#endif
glClearStencil(0);
// Hardly necessary to clear depth and stencil I guess...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
currentRenderVfb_ = 0;
u32 offsetX = 0;

View File

@ -815,7 +815,7 @@ void ShaderListScreen::CreateViews() {
layout->Add(tabs_);
layout->Add(new Button(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
for (int i = 0; i < ARRAY_SIZE(shaderTypes); i++) {
for (size_t i = 0; i < ARRAY_SIZE(shaderTypes); i++) {
ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
LinearLayout *shaderList = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
ListShaders(shaderTypes[i].type, shaderList);

View File

@ -90,8 +90,7 @@ void EmuScreen::bootGame(const std::string &filename) {
//pre-emptive loading of game specific config if possible, to get all the settings
GameInfo *info = g_gameInfoCache.GetInfo(NULL, filename, 0);
if (info && !info->id.empty())
{
if (info && !info->id.empty()) {
g_Config.loadGameConfig(info->id);
}
@ -862,6 +861,24 @@ void EmuScreen::render() {
}
}
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
if (!useBufferedRendering) {
Thin3DContext *thin3d = screenManager()->getThin3DContext();
thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0);
T3DViewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = pixel_xres;
viewport.Height = pixel_yres;
viewport.MaxDepth = 1.0;
viewport.MinDepth = 0.0;
thin3d->SetViewports(1, &viewport);
thin3d->SetTargetSize(pixel_xres, pixel_yres);
}
// Reapply the graphics state of the PSP
ReapplyGfxState();
@ -883,7 +900,6 @@ void EmuScreen::render() {
if (invalid_)
return;
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
if (useBufferedRendering && g_Config.iGPUBackend == GPU_BACKEND_OPENGL)
fbo_unbind();

View File

@ -35,18 +35,18 @@ public:
EmuScreen(const std::string &filename);
~EmuScreen();
virtual void update(InputState &input) override;
virtual void render() override;
virtual void deviceLost() override;
virtual void dialogFinished(const Screen *dialog, DialogResult result) override;
virtual void sendMessage(const char *msg, const char *value) override;
void update(InputState &input) override;
void render() override;
void deviceLost() override;
void dialogFinished(const Screen *dialog, DialogResult result) override;
void sendMessage(const char *msg, const char *value) override;
virtual bool touch(const TouchInput &touch) override;
virtual bool key(const KeyInput &key) override;
virtual bool axis(const AxisInput &axis) override;
bool touch(const TouchInput &touch) override;
bool key(const KeyInput &key) override;
bool axis(const AxisInput &axis) override;
protected:
virtual void CreateViews() override;
void CreateViews() override;
UI::EventReturn OnDevTools(UI::EventParams &params);
private:

View File

@ -694,18 +694,6 @@ void DrawDownloadsOverlay(UIContext &dc) {
void NativeRender() {
g_GameManager.Update();
thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0);
T3DViewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = pixel_xres;
viewport.Height = pixel_yres;
viewport.MaxDepth = 1.0;
viewport.MinDepth = 0.0;
thin3d->SetViewports(1, &viewport);
thin3d->SetTargetSize(pixel_xres, pixel_yres);
float xres = dp_xres;
float yres = dp_yres;

View File

@ -1,3 +1,4 @@
#include "base/display.h"
#include "base/logging.h"
#include "input/input_state.h"
#include "ui/screen.h"
@ -109,13 +110,19 @@ void ScreenManager::render() {
iter--;
iter--;
Layer backback = *iter;
// Also shift to the right somehow...
// TODO: Make really sure that this "mismatched" pre/post only happens
// when screens are "compatible" (both are UIScreens, for example).
backback.screen->preRender();
backback.screen->render();
stack_.back().screen->render();
stack_.back().screen->postRender();
break;
}
default:
stack_.back().screen->preRender();
stack_.back().screen->render();
stack_.back().screen->postRender();
break;
}
} else {

View File

@ -46,7 +46,9 @@ public:
virtual void onFinish(DialogResult reason) {}
virtual void update(InputState &input) {}
virtual void preRender() {}
virtual void render() {}
virtual void postRender() {}
virtual void deviceLost() {}
virtual void resized() {}
virtual void dialogFinished(const Screen *dialog, DialogResult result) {}

View File

@ -1,3 +1,4 @@
#include "base/display.h"
#include "input/input_state.h"
#include "input/keycodes.h"
#include "ui/ui_screen.h"
@ -36,6 +37,24 @@ void UIScreen::update(InputState &input) {
}
}
void UIScreen::preRender() {
Thin3DContext *thin3d = screenManager()->getThin3DContext();
thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0);
T3DViewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = pixel_xres;
viewport.Height = pixel_yres;
viewport.MaxDepth = 1.0;
viewport.MinDepth = 0.0;
thin3d->SetViewports(1, &viewport);
thin3d->SetTargetSize(pixel_xres, pixel_yres);
}
void UIScreen::postRender() {
}
void UIScreen::render() {
DoRecreateViews();

View File

@ -12,7 +12,9 @@ public:
~UIScreen();
virtual void update(InputState &input) override;
virtual void preRender() override;
virtual void render() override;
virtual void postRender() override;
virtual bool touch(const TouchInput &touch) override;
virtual bool key(const KeyInput &touch) override;