steamcompmgr: Add the ability to take different types of screenshots
All layers, screen buffer, full composition, etc.
This commit is contained in:
parent
59c1571e34
commit
ce281a9291
5 changed files with 75 additions and 28 deletions
|
|
@ -412,7 +412,7 @@ static void handle_signal( int sig )
|
|||
{
|
||||
switch ( sig ) {
|
||||
case SIGUSR2:
|
||||
take_screenshot();
|
||||
take_screenshot( TAKE_SCREENSHOT_BASEPLANE_ONLY );
|
||||
break;
|
||||
case SIGHUP:
|
||||
case SIGQUIT:
|
||||
|
|
|
|||
|
|
@ -3543,7 +3543,7 @@ extern uint32_t g_reshade_technique_idx;
|
|||
std::unique_ptr<std::thread> defer_wait_thread;
|
||||
uint64_t defer_sequence = 0;
|
||||
|
||||
bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTexture> pPipewireTexture, bool partial, bool defer )
|
||||
bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTexture> pPipewireTexture, bool partial, bool defer, std::shared_ptr<CVulkanTexture> pOutputOverride )
|
||||
{
|
||||
if ( defer_wait_thread )
|
||||
{
|
||||
|
|
@ -3585,7 +3585,11 @@ bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTex
|
|||
g_reshadeManager.clear();
|
||||
}
|
||||
|
||||
auto compositeImage = partial ? g_output.outputImagesPartialOverlay[ g_output.nOutImage ] : g_output.outputImages[ g_output.nOutImage ];
|
||||
std::shared_ptr<CVulkanTexture> compositeImage;
|
||||
if ( pOutputOverride )
|
||||
compositeImage = pOutputOverride;
|
||||
else
|
||||
compositeImage = partial ? g_output.outputImagesPartialOverlay[ g_output.nOutImage ] : g_output.outputImages[ g_output.nOutImage ];
|
||||
|
||||
auto cmdBuffer = g_device.commandBuffer();
|
||||
|
||||
|
|
@ -3723,6 +3727,7 @@ bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTex
|
|||
|
||||
if ( pPipewireTexture != nullptr )
|
||||
{
|
||||
|
||||
if (compositeImage->format() == pPipewireTexture->format() &&
|
||||
compositeImage->width() == pPipewireTexture->width() &&
|
||||
compositeImage->height() == pPipewireTexture->height()) {
|
||||
|
|
@ -3782,7 +3787,7 @@ bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTex
|
|||
g_device.wait(sequence);
|
||||
}
|
||||
|
||||
if ( !BIsSDLSession() )
|
||||
if ( !BIsSDLSession() && pOutputOverride == nullptr )
|
||||
{
|
||||
g_output.nOutImage = ( g_output.nOutImage + 1 ) % 3;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ std::shared_ptr<CVulkanTexture> vulkan_create_texture_from_dmabuf( struct wlr_dm
|
|||
std::shared_ptr<CVulkanTexture> vulkan_create_texture_from_bits( uint32_t width, uint32_t height, uint32_t contentWidth, uint32_t contentHeight, uint32_t drmFormat, CVulkanTexture::createFlags texCreateFlags, void *bits );
|
||||
std::shared_ptr<CVulkanTexture> vulkan_create_texture_from_wlr_buffer( struct wlr_buffer *buf );
|
||||
|
||||
bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTexture> pScreenshotTexture, bool partial, bool deferred );
|
||||
bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTexture> pScreenshotTexture, bool partial, bool deferred, std::shared_ptr<CVulkanTexture> pOutputOverride = nullptr );
|
||||
std::shared_ptr<CVulkanTexture> vulkan_get_last_output_image( bool partial, bool defer );
|
||||
std::shared_ptr<CVulkanTexture> vulkan_acquire_screenshot_texture(uint32_t width, uint32_t height, bool exportable, uint32_t drmFormat, EStreamColorspace colorspace = k_EStreamColorspace_Unknown);
|
||||
|
||||
|
|
|
|||
|
|
@ -1006,7 +1006,7 @@ struct wlr_buffer_map_entry {
|
|||
static std::mutex wlr_buffer_map_lock;
|
||||
static std::unordered_map<struct wlr_buffer*, wlr_buffer_map_entry> wlr_buffer_map;
|
||||
|
||||
static std::atomic< bool > g_bTakeScreenshot{false};
|
||||
static std::atomic< int > g_nTakeScreenshot{ 0 };
|
||||
static bool g_bPropertyRequestedScreenshot;
|
||||
|
||||
static std::atomic<bool> g_bForceRepaint{false};
|
||||
|
|
@ -2584,7 +2584,7 @@ paint_all(bool async)
|
|||
bool bDoComposite = true;
|
||||
|
||||
// Handoff from whatever thread to this one since we check ours twice
|
||||
bool takeScreenshot = g_bTakeScreenshot.exchange(false);
|
||||
int takeScreenshot = g_nTakeScreenshot.exchange( 0 );
|
||||
bool propertyRequestedScreenshot = g_bPropertyRequestedScreenshot;
|
||||
g_bPropertyRequestedScreenshot = false;
|
||||
|
||||
|
|
@ -2657,6 +2657,8 @@ paint_all(bool async)
|
|||
bNeedsFullComposite |= fadingOut;
|
||||
bNeedsFullComposite |= !g_reshade_effect.empty();
|
||||
|
||||
constexpr bool bHackForceNV12DumpScreenshot = false;
|
||||
|
||||
for (uint32_t i = 0; i < EOTF_Count; i++)
|
||||
{
|
||||
if (g_ColorMgmtLuts[i].HasLuts())
|
||||
|
|
@ -2944,8 +2946,6 @@ paint_all(bool async)
|
|||
|
||||
if ( takeScreenshot )
|
||||
{
|
||||
constexpr bool bHackForceNV12DumpScreenshot = false;
|
||||
|
||||
uint32_t drmCaptureFormat = bHackForceNV12DumpScreenshot
|
||||
? DRM_FORMAT_NV12
|
||||
: DRM_FORMAT_XRGB8888;
|
||||
|
|
@ -2954,25 +2954,58 @@ paint_all(bool async)
|
|||
|
||||
if ( pScreenshotTexture )
|
||||
{
|
||||
// Basically no color mgmt applied for screenshots. (aside from being able to handle HDR content with LUTs)
|
||||
for ( uint32_t nInputEOTF = 0; nInputEOTF < EOTF_Count; nInputEOTF++ )
|
||||
if ( takeScreenshot != TAKE_SCREENSHOT_SCREEN_BUFFER )
|
||||
{
|
||||
frameInfo.lut3D[nInputEOTF] = g_ScreenshotColorMgmtLuts[nInputEOTF].vk_lut3d;
|
||||
frameInfo.shaperLut[nInputEOTF] = g_ScreenshotColorMgmtLuts[nInputEOTF].vk_lut1d;
|
||||
}
|
||||
// Remove everything but base planes from the screenshot.
|
||||
for (int i = 0; i < frameInfo.layerCount; i++)
|
||||
{
|
||||
if (frameInfo.layers[i].zpos >= (int)g_zposExternalOverlay)
|
||||
// Basically no color mgmt applied for screenshots. (aside from being able to handle HDR content with LUTs)
|
||||
for ( uint32_t nInputEOTF = 0; nInputEOTF < EOTF_Count; nInputEOTF++ )
|
||||
{
|
||||
frameInfo.layerCount = i;
|
||||
break;
|
||||
frameInfo.lut3D[nInputEOTF] = g_ScreenshotColorMgmtLuts[nInputEOTF].vk_lut3d;
|
||||
frameInfo.shaperLut[nInputEOTF] = g_ScreenshotColorMgmtLuts[nInputEOTF].vk_lut1d;
|
||||
}
|
||||
|
||||
if ( takeScreenshot == TAKE_SCREENSHOT_BASEPLANE_ONLY )
|
||||
{
|
||||
// Remove everything but base planes from the screenshot.
|
||||
for (int i = 0; i < frameInfo.layerCount; i++)
|
||||
{
|
||||
if (frameInfo.layers[i].zpos >= (int)g_zposExternalOverlay)
|
||||
{
|
||||
frameInfo.layerCount = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable output color management (blending) if it was disabled by mura.
|
||||
frameInfo.applyOutputColorMgmt = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( is_mura_correction_enabled() )
|
||||
{
|
||||
// Remove the last layer which is for mura...
|
||||
for (int i = 0; i < frameInfo.layerCount; i++)
|
||||
{
|
||||
if (frameInfo.layers[i].zpos >= (int)g_zposMuraCorrection)
|
||||
{
|
||||
frameInfo.layerCount = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable output color management (blending) if it was disabled by mura.
|
||||
frameInfo.applyOutputColorMgmt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frameInfo.applyOutputColorMgmt = true;
|
||||
|
||||
bool bResult = vulkan_screenshot( &frameInfo, pScreenshotTexture );
|
||||
bool bResult;
|
||||
if ( takeScreenshot == TAKE_SCREENSHOT_FULL_COMPOSITION || takeScreenshot == TAKE_SCREENSHOT_SCREEN_BUFFER )
|
||||
bResult = vulkan_composite( &frameInfo, nullptr, false, false, pScreenshotTexture );
|
||||
else
|
||||
bResult = vulkan_screenshot( &frameInfo, pScreenshotTexture );
|
||||
|
||||
if ( bResult != true )
|
||||
{
|
||||
xwm_log.errorf("vulkan_screenshot failed");
|
||||
|
|
@ -3061,16 +3094,17 @@ paint_all(bool async)
|
|||
|
||||
screenshotThread.detach();
|
||||
|
||||
takeScreenshot = false;
|
||||
takeScreenshot = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xwm_log.errorf( "Oh no, we ran out of screenshot images. Not actually writing a screenshot." );
|
||||
XDeleteProperty( root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeScreenShotAtom );
|
||||
takeScreenshot = false;
|
||||
takeScreenshot = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gpuvis_trace_end_ctx_printf( paintID, "paint_all" );
|
||||
gpuvis_trace_printf( "paint_all %i layers, composite %i", (int)frameInfo.layerCount, bDoComposite );
|
||||
}
|
||||
|
|
@ -5326,7 +5360,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
|||
{
|
||||
if ( ev->state == PropertyNewValue )
|
||||
{
|
||||
g_bTakeScreenshot = true;
|
||||
g_nTakeScreenshot = (int)get_prop( ctx, ctx->root, ctx->atoms.gamescopeScreenShotAtom, None );
|
||||
g_bPropertyRequestedScreenshot = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -6430,9 +6464,9 @@ void nudge_steamcompmgr( void )
|
|||
xwm_log.errorf_errno( "nudge_steamcompmgr: write failed" );
|
||||
}
|
||||
|
||||
void take_screenshot( void )
|
||||
void take_screenshot( int flags )
|
||||
{
|
||||
g_bTakeScreenshot = true;
|
||||
g_nTakeScreenshot = flags;
|
||||
nudge_steamcompmgr();
|
||||
}
|
||||
|
||||
|
|
@ -7999,7 +8033,7 @@ steamcompmgr_main(int argc, char **argv)
|
|||
const bool bSurfaceWantsAsync = (g_HeldCommits[HELD_COMMIT_BASE] && g_HeldCommits[HELD_COMMIT_BASE]->async);
|
||||
|
||||
const bool bForceRepaint = g_bForceRepaint.exchange(false);
|
||||
const bool bForceSyncFlip = bForceRepaint || g_bTakeScreenshot || is_fading_out();
|
||||
const bool bForceSyncFlip = bForceRepaint || is_fading_out();
|
||||
// If we are compositing, always force sync flips because we currently wait
|
||||
// for composition to finish before submitting.
|
||||
// If we want to do async + composite, we should set up syncfile stuff and have DRM wait on it.
|
||||
|
|
|
|||
|
|
@ -43,6 +43,14 @@ extern bool g_bForceHDRSupportDebug;
|
|||
|
||||
extern EStreamColorspace g_ForcedNV12ColorSpace;
|
||||
|
||||
enum TakeScreenshotMode_t
|
||||
{
|
||||
TAKE_SCREENSHOT_BASEPLANE_ONLY = 1, // Just the game/base plane
|
||||
TAKE_SCREENSHOT_ALL_REAL_LAYERS = 2, // Just the game + steam overlay/perf overlays
|
||||
TAKE_SCREENSHOT_FULL_COMPOSITION = 3, // Everything, but no display color management + no mura
|
||||
TAKE_SCREENSHOT_SCREEN_BUFFER = 4, // Yes, mura comp, color management! Exactly what we put on the screen.
|
||||
};
|
||||
|
||||
class MouseCursor
|
||||
{
|
||||
public:
|
||||
|
|
@ -129,7 +137,7 @@ extern bool g_bFSRActive;
|
|||
extern uint32_t inputCounter;
|
||||
|
||||
void nudge_steamcompmgr( void );
|
||||
void take_screenshot( void );
|
||||
void take_screenshot( int flags = TAKE_SCREENSHOT_BASEPLANE_ONLY );
|
||||
void force_repaint( void );
|
||||
|
||||
extern void mangoapp_update( uint64_t visible_frametime, uint64_t app_frametime_ns, uint64_t latency_ns );
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue