Files
LibretroAdmin 39a506b9b1 rend: the screen's picture is kept when the context is destroyed and made again
A game that renders only part of the screen relies on the rest of
the picture staying as it was. Here the rest is in images that
belong to the graphics context, and going fullscreen, or changing a
video setting, destroys the context: the part the game was not
rendering came back black and stayed so until the game drew it again
- which on a loading screen or a menu can be never.

The picture is now fetched when the context is about to go
(rend/last_picture.h), and the first render to the screen in the new
context starts from it. In all four renderers:

- OpenGL, both: read from the framebuffer the frontend gave, and put
  into the one the first render is about to draw in. (OpenGL ES 2
  cannot put it back and is as it was.)
- Vulkan, both: copied from the image the last frame was drawn into,
  made a texture in the new context, and drawn in first where the
  last frame is drawn in for a render in part. The screen's images
  are made to be copied from, without the read-back memory other
  such images get.
- The first render to each framebuffer after a new renderer starts
  from an empty one, as before - unless a picture was kept for it.

One read of the picture for each context destroyed, nothing a frame.
A kept picture of another size is scaled to the new one's.

The test disc renders in part from frame 260 to its end again; the
last patch had it stop at frame 320 so that the fullscreen pass did
not come to depend on when its toggles fell. That pass now sends
three, the later ones while the disc renders in part, and the
per-pixel renderers have a fullscreen pass of their own. The core
says in its log when it keeps a picture, and the passes look for it.

With the putting-back switched off, the fullscreen pass fails on
OpenGL and on Vulkan (tried on the per-triangle renderers). With it,
the live test passes on gl, glcore and vulkan, both renderers each;
the Vulkan passes also with the validation layer on. The headless
test passes.
2026-10-08 03:21:44 +02:00

37 lines
581 B
C++

/* See last_picture.h. */
#include "last_picture.h"
#include <cstdlib>
static u8 *pixels;
static int pixels_w, pixels_h;
u8 *last_picture_keep(int width, int height)
{
last_picture_drop();
if (width <= 0 || height <= 0)
return NULL;
pixels = (u8 *)malloc((size_t)width * height * 4);
if (pixels != NULL)
{
pixels_w = width;
pixels_h = height;
}
return pixels;
}
const u8 *last_picture(int *width, int *height)
{
if (pixels != NULL)
{
*width = pixels_w;
*height = pixels_h;
}
return pixels;
}
void last_picture_drop(void)
{
free(pixels);
pixels = NULL;
}