mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
Handle insets correctly for the in-game final screen blit.
Should help #12982 in case of phones with inset cameras.
This commit is contained in:
parent
e559fc022f
commit
c8d48a8777
@ -655,13 +655,15 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int
|
||||
SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
draw_->SetScissorRect(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
} else {
|
||||
// We are drawing to the back buffer so need to flip.
|
||||
// We are drawing directly to the back buffer so need to flip.
|
||||
// Should more of this be handled by the presentation engine?
|
||||
if (needBackBufferYSwap_)
|
||||
std::swap(v0, v1);
|
||||
flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
|
||||
flags = flags | DRAWTEX_TO_BACKBUFFER;
|
||||
FRect frame = GetInsetScreenFrame(pixelWidth_, pixelHeight_);
|
||||
FRect rc;
|
||||
CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL);
|
||||
CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, ROTATION_LOCKED_HORIZONTAL);
|
||||
SetViewport2D(rc.x, rc.y, rc.w, rc.h);
|
||||
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
|
||||
}
|
||||
|
@ -557,8 +557,9 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
||||
} else {
|
||||
float pixelW = PSP_CoreParameter().pixelWidth;
|
||||
float pixelH = PSP_CoreParameter().pixelHeight;
|
||||
FRect frame = GetInsetScreenFrame(pixelW, pixelH);
|
||||
FRect rc;
|
||||
CenterDisplayOutputRect(&rc, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL);
|
||||
CenterDisplayOutputRect(&rc, 480, 272, frame, ROTATION_LOCKED_HORIZONTAL);
|
||||
displayOffsetX = rc.x;
|
||||
displayOffsetY = rc.y;
|
||||
renderWidth = rc.w;
|
||||
|
@ -19,8 +19,10 @@
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
#include <cstdint>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "file/vfs.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
@ -39,19 +41,40 @@ struct Vertex {
|
||||
uint32_t rgba;
|
||||
};
|
||||
|
||||
void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, float frameH, int rotation) {
|
||||
FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight) {
|
||||
FRect rc = FRect{
|
||||
0.0f,
|
||||
0.0f,
|
||||
pixelWidth,
|
||||
pixelHeight,
|
||||
};
|
||||
|
||||
float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT);
|
||||
float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT);
|
||||
float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP);
|
||||
float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM);
|
||||
|
||||
// Adjust left edge to compensate for cutouts (notches) if any.
|
||||
rc.x += left;
|
||||
rc.w -= (left + right);
|
||||
rc.y += top;
|
||||
rc.h -= (top + bottom);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &frame, int rotation) {
|
||||
float outW;
|
||||
float outH;
|
||||
|
||||
bool rotated = rotation == ROTATION_LOCKED_VERTICAL || rotation == ROTATION_LOCKED_VERTICAL180;
|
||||
|
||||
if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::STRETCH) {
|
||||
outW = frameW;
|
||||
outH = frameH;
|
||||
outW = frame.w;
|
||||
outH = frame.h;
|
||||
} else {
|
||||
if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::MANUAL) {
|
||||
float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frameW;
|
||||
float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frameH;
|
||||
float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frame.w;
|
||||
float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frame.h;
|
||||
// Have to invert Y for GL
|
||||
if (GetGPUBackend() == GPUBackend::OPENGL) {
|
||||
offsetY = offsetY * -1.0f;
|
||||
@ -60,24 +83,24 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW,
|
||||
float smallDisplayW = origW * customZoom;
|
||||
float smallDisplayH = origH * customZoom;
|
||||
if (!rotated) {
|
||||
rc->x = floorf(((frameW - smallDisplayW) / 2.0f) + offsetX);
|
||||
rc->y = floorf(((frameH - smallDisplayH) / 2.0f) + offsetY);
|
||||
rc->x = floorf(((frame.w - smallDisplayW) / 2.0f) + offsetX);
|
||||
rc->y = floorf(((frame.h - smallDisplayH) / 2.0f) + offsetY);
|
||||
rc->w = floorf(smallDisplayW);
|
||||
rc->h = floorf(smallDisplayH);
|
||||
return;
|
||||
} else {
|
||||
rc->x = floorf(((frameW - smallDisplayH) / 2.0f) + offsetX);
|
||||
rc->y = floorf(((frameH - smallDisplayW) / 2.0f) + offsetY);
|
||||
rc->x = floorf(((frame.w - smallDisplayH) / 2.0f) + offsetX);
|
||||
rc->y = floorf(((frame.h - smallDisplayW) / 2.0f) + offsetY);
|
||||
rc->w = floorf(smallDisplayH);
|
||||
rc->h = floorf(smallDisplayW);
|
||||
return;
|
||||
}
|
||||
} else if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) {
|
||||
// Stretch to 1080 for 272*4. But don't distort if not widescreen (i.e. ultrawide of halfwide.)
|
||||
float pixelCrop = frameH / 270.0f;
|
||||
float pixelCrop = frame.h / 270.0f;
|
||||
float resCommonWidescreen = pixelCrop - floor(pixelCrop);
|
||||
if (!rotated && resCommonWidescreen == 0.0f && frameW >= pixelCrop * 480.0f) {
|
||||
rc->x = floorf((frameW - pixelCrop * 480.0f) * 0.5f);
|
||||
if (!rotated && resCommonWidescreen == 0.0f && frame.w >= pixelCrop * 480.0f) {
|
||||
rc->x = floorf((frame.h - pixelCrop * 480.0f) * 0.5f);
|
||||
rc->y = floorf(-pixelCrop);
|
||||
rc->w = floorf(pixelCrop * 480.0f);
|
||||
rc->h = floorf(pixelCrop * 272.0f);
|
||||
@ -86,26 +109,26 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW,
|
||||
}
|
||||
|
||||
float origRatio = !rotated ? origW / origH : origH / origW;
|
||||
float frameRatio = frameW / frameH;
|
||||
float frameRatio = frame.w / frame.h;
|
||||
|
||||
if (origRatio > frameRatio) {
|
||||
// Image is wider than frame. Center vertically.
|
||||
outW = frameW;
|
||||
outH = frameW / origRatio;
|
||||
outW = frame.w;
|
||||
outH = frame.w / origRatio;
|
||||
// Stretch a little bit
|
||||
if (!rotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH)
|
||||
outH = (frameH + outH) / 2.0f; // (408 + 720) / 2 = 564
|
||||
outH = (frame.h + outH) / 2.0f; // (408 + 720) / 2 = 564
|
||||
} else {
|
||||
// Image is taller than frame. Center horizontally.
|
||||
outW = frameH * origRatio;
|
||||
outH = frameH;
|
||||
outW = frame.h * origRatio;
|
||||
outH = frame.h;
|
||||
if (rotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH)
|
||||
outW = (frameH + outH) / 2.0f; // (408 + 720) / 2 = 564
|
||||
outW = (frame.h + outH) / 2.0f; // (408 + 720) / 2 = 564
|
||||
}
|
||||
}
|
||||
|
||||
rc->x = floorf((frameW - outW) / 2.0f);
|
||||
rc->y = floorf((frameH - outH) / 2.0f);
|
||||
rc->x = floorf((frame.w - outW) / 2.0f + frame.x);
|
||||
rc->y = floorf((frame.h - outH) / 2.0f + frame.y);
|
||||
rc->w = floorf(outW);
|
||||
rc->h = floorf(outH);
|
||||
}
|
||||
@ -119,6 +142,10 @@ PresentationCommon::~PresentationCommon() {
|
||||
}
|
||||
|
||||
void PresentationCommon::GetCardboardSettings(CardboardSettings *cardboardSettings) {
|
||||
if (!g_Config.bEnableCardboardVR) {
|
||||
cardboardSettings->enabled = false;
|
||||
return;
|
||||
}
|
||||
// Calculate Cardboard Settings
|
||||
float cardboardScreenScale = g_Config.iCardboardScreenSize / 100.0f;
|
||||
float cardboardScreenWidth = pixelWidth_ / 2.0f * cardboardScreenScale;
|
||||
@ -131,7 +158,7 @@ void PresentationCommon::GetCardboardSettings(CardboardSettings *cardboardSettin
|
||||
float cardboardUserYShift = g_Config.iCardboardYShift / 100.0f * cardboardMaxYShift;
|
||||
float cardboardScreenY = cardboardMaxYShift + cardboardUserYShift;
|
||||
|
||||
cardboardSettings->enabled = g_Config.bEnableCardboardVR;
|
||||
cardboardSettings->enabled = true;
|
||||
cardboardSettings->leftEyeXPosition = cardboardLeftEyeX;
|
||||
cardboardSettings->rightEyeXPosition = cardboardRightEyeX;
|
||||
cardboardSettings->screenYPosition = cardboardScreenY;
|
||||
@ -253,7 +280,8 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha
|
||||
} else if (shaderInfo->outputResolution) {
|
||||
// If the current shader uses output res (not next), we will use output res for it.
|
||||
FRect rc;
|
||||
CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, g_Config.iInternalScreenRotation);
|
||||
FRect frame = GetInsetScreenFrame((float)pixelWidth_, (float)pixelHeight_);
|
||||
CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, g_Config.iInternalScreenRotation);
|
||||
nextWidth = (int)rc.w;
|
||||
nextHeight = (int)rc.h;
|
||||
}
|
||||
@ -499,8 +527,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
|
||||
int lastHeight = srcHeight_;
|
||||
|
||||
// These are the output coordinates.
|
||||
FRect frame = GetInsetScreenFrame((float)pixelWidth_, (float)pixelHeight_);
|
||||
FRect rc;
|
||||
CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation);
|
||||
CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, uvRotation);
|
||||
|
||||
if (GetGPUBackend() == GPUBackend::DIRECT3D9) {
|
||||
rc.x -= 0.5f;
|
||||
|
@ -45,7 +45,8 @@ struct FRect {
|
||||
float h;
|
||||
};
|
||||
|
||||
void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, float frameH, int rotation);
|
||||
FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight);
|
||||
void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &frame, int rotation);
|
||||
|
||||
namespace Draw {
|
||||
class Buffer;
|
||||
|
Loading…
Reference in New Issue
Block a user