Precompute the aspect ratio stretch to avoid having to change viewports twice each frame

This commit is contained in:
Cameron Gutman 2022-02-05 15:44:37 -06:00
commit 918fea7d4b

View file

@ -563,8 +563,6 @@ void D3D11VARenderer::setHdrMode(bool enabled)
void D3D11VARenderer::renderFrame(AVFrame* frame) void D3D11VARenderer::renderFrame(AVFrame* frame)
{ {
D3D11_VIEWPORT viewPort;
if (frame == nullptr) { if (frame == nullptr) {
// End of stream - nothing to do for us // End of stream - nothing to do for us
return; return;
@ -582,33 +580,9 @@ void D3D11VARenderer::renderFrame(AVFrame* frame)
// because the render target view will be unbound by Present(). // because the render target view will be unbound by Present().
m_DeviceContext->OMSetRenderTargets(1, &m_RenderTargetView, nullptr); m_DeviceContext->OMSetRenderTargets(1, &m_RenderTargetView, nullptr);
viewPort.MinDepth = 0;
viewPort.MaxDepth = 1;
// Set the viewport to render the video with aspect ratio scaling
SDL_Rect src, dst;
src.x = src.y = 0;
src.w = m_DecoderParams.width;
src.h = m_DecoderParams.height;
dst.x = dst.y = 0;
dst.w = m_DisplayWidth;
dst.h = m_DisplayHeight;
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
viewPort.TopLeftX = dst.x;
viewPort.TopLeftY = dst.y;
viewPort.Width = dst.w;
viewPort.Height = dst.h;
m_DeviceContext->RSSetViewports(1, &viewPort);
// Render our video frame with the aspect-ratio adjusted viewport // Render our video frame with the aspect-ratio adjusted viewport
renderVideo(frame); renderVideo(frame);
// Set the viewport to render overlays at the full window size
viewPort.TopLeftX = viewPort.TopLeftY = 0;
viewPort.Width = m_DisplayWidth;
viewPort.Height = m_DisplayHeight;
m_DeviceContext->RSSetViewports(1, &viewPort);
// Render overlays on top of the video stream // Render overlays on top of the video stream
for (int i = 0; i < Overlay::OverlayMax; i++) { for (int i = 0; i < Overlay::OverlayMax; i++) {
renderOverlay((Overlay::OverlayType)i); renderOverlay((Overlay::OverlayType)i);
@ -1237,18 +1211,34 @@ bool D3D11VARenderer::setupRenderingResources()
// Create our fixed vertex buffer for video rendering // Create our fixed vertex buffer for video rendering
{ {
SDL_assert(m_TextureAlignment != 0); // Scale video to the window size while preserving aspect ratio
SDL_Rect src, dst;
src.x = src.y = 0;
src.w = m_DecoderParams.width;
src.h = m_DecoderParams.height;
dst.x = dst.y = 0;
dst.w = m_DisplayWidth;
dst.h = m_DisplayHeight;
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
// Convert screen space to normalized device coordinates
SDL_FRect renderRect;
renderRect.x = ((float)dst.x / (m_DisplayWidth / 2)) - 1.0f;
renderRect.y = ((float)dst.y / (m_DisplayHeight / 2)) - 1.0f;
renderRect.w = (float)dst.w / (m_DisplayWidth / 2);
renderRect.h = (float)dst.h / (m_DisplayHeight / 2);
// Don't sample from the alignment padding area since that's not part of the video // Don't sample from the alignment padding area since that's not part of the video
SDL_assert(m_TextureAlignment != 0);
float uMax = (float)m_DecoderParams.width / FFALIGN(m_DecoderParams.width, m_TextureAlignment); float uMax = (float)m_DecoderParams.width / FFALIGN(m_DecoderParams.width, m_TextureAlignment);
float vMax = (float)m_DecoderParams.height / FFALIGN(m_DecoderParams.height, m_TextureAlignment); float vMax = (float)m_DecoderParams.height / FFALIGN(m_DecoderParams.height, m_TextureAlignment);
VERTEX verts[] = VERTEX verts[] =
{ {
{-1, -1, 0, vMax}, {renderRect.x, renderRect.y, 0, vMax},
{-1, 1, 0, 0}, {renderRect.x, renderRect.y+renderRect.h, 0, 0},
{ 1, -1, uMax, vMax}, {renderRect.x+renderRect.w, renderRect.y, uMax, vMax},
{ 1, 1, uMax, 0}, {renderRect.x+renderRect.w, renderRect.y+renderRect.h, uMax, 0},
}; };
D3D11_BUFFER_DESC vbDesc = {}; D3D11_BUFFER_DESC vbDesc = {};
@ -1299,6 +1289,20 @@ bool D3D11VARenderer::setupRenderingResources()
} }
} }
// Set a viewport that fills the window
{
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = m_DisplayWidth;
viewport.Height = m_DisplayHeight;
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
m_DeviceContext->RSSetViewports(1, &viewport);
}
return true; return true;
} }