Skip to content

Commit

Permalink
Disable screenshot reading earlier
Browse files Browse the repository at this point in the history
  • Loading branch information
vontell committed Nov 15, 2024
1 parent 8792b8d commit 218acca
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,17 @@ private static RenderTexture GetRenderTexture()

private void UpdateGameFacePixelHash()
{
if (_isActive)
// If we are running in -nographics mode, the async task below fails, causing an exception inside
// the AsyncGPUReadback.Request that is difficult to catch. This ensures that the image data
// is only read when we have graphics
if (_isActive && SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null)
{
// have to re-get this every time because it changes on resolution and other screen changes that update the gameface render target
var cohtmlViewTexture = GetRenderTexture();
if (cohtmlViewTexture != null)
{
var wasActive = Interlocked.CompareExchange(ref _requestInProgress, string.Empty, null);

// If we are running in -nographics mode, the async task below fails, causing an exception inside
// the AsyncGPUReadback.Request that is difficult to catch. This ensures that the image data
// is only read when we have graphics
if (wasActive == null && SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null)
if (wasActive == null)
{
var frame = Time.frameCount;
AsyncGPUReadback.Request(cohtmlViewTexture, 0, request =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,88 +290,101 @@ private IEnumerator UpdateGPUData(int frame, Action<(byte[], int, int)?> onCompl
}
}
}

// wait for end of frame or graphics data will be incorrect
yield return new WaitForEndOfFrame();

// get this in there so we don't get duplicate requests out for the same frame
if (GPUReadbackRequests.TryAdd(frame, null))

// If we are running in -nographics mode, the async task fails, causing an exception inside
// the AsyncGPUReadback.Request that is difficult to catch. This ensures that the screenshot
// is only taken when we have graphics
if (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null)
{
var screenWidth = Screen.width;
var screenHeight = Screen.height;

if (_screenShotTexture == null || _screenShotTexture.width != screenWidth || _screenShotTexture.height != screenHeight)
// wait for end of frame or graphics data will be incorrect
yield return new WaitForEndOfFrame();

// get this in there so we don't get duplicate requests out for the same frame
if (GPUReadbackRequests.TryAdd(frame, null))
{
if (_screenShotTexture != null)
{
Object.Destroy(_screenShotTexture);
}
var screenWidth = Screen.width;
var screenHeight = Screen.height;

if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal)
{
// why Metal defaults to B8G8R8A8_SRGB and thus flips the colors.. who knows..
// this setting stops it from spamming log errors
_screenShotTexture = new RenderTexture(screenWidth, screenHeight, 0, GraphicsFormat.R8G8B8A8_SRGB);
}
else
if (_screenShotTexture == null || _screenShotTexture.width != screenWidth ||
_screenShotTexture.height != screenHeight)
{
_screenShotTexture = new RenderTexture(screenWidth, screenHeight, 0);
if (_screenShotTexture != null)
{
Object.Destroy(_screenShotTexture);
}

if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal)
{
// why Metal defaults to B8G8R8A8_SRGB and thus flips the colors.. who knows..
// this setting stops it from spamming log errors
_screenShotTexture = new RenderTexture(screenWidth, screenHeight, 0,
GraphicsFormat.R8G8B8A8_SRGB);
}
else
{
_screenShotTexture = new RenderTexture(screenWidth, screenHeight, 0);
}
}
}

var theGraphicsFormat = _screenShotTexture.graphicsFormat;

// If we are running in -nographics mode, the async task fails, causing an exception inside
// the AsyncGPUReadback.Request that is difficult to catch. This ensures that the screenshot
// is only taken when we have graphics
if (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null)
{
var theGraphicsFormat = _screenShotTexture.graphicsFormat;

try
{
ScreenCapture.CaptureScreenshotIntoRenderTexture(_screenShotTexture);
var readbackRequest = AsyncGPUReadback.Request(_screenShotTexture, 0, GraphicsFormat.R8G8B8A8_SRGB, request =>
{
if (!request.hasError)
var readbackRequest = AsyncGPUReadback.Request(_screenShotTexture, 0,
GraphicsFormat.R8G8B8A8_SRGB, request =>
{
var pixels = request.GetData<Color32>();
var copyBuffer = _copyBuffer.Value; // uses a threadlocal to avoid re-allocating this on every readback
if (SystemInfo.graphicsUVStartsAtTop)
if (!request.hasError)
{
// the pixels from the GPU are upside down, we need to reverse this for it to be right side up
var halfHeight = screenHeight / 2;
for (var i = 0; i <= halfHeight; i++)
var pixels = request.GetData<Color32>();
var copyBuffer =
_copyBuffer
.Value; // uses a threadlocal to avoid re-allocating this on every readback
if (SystemInfo.graphicsUVStartsAtTop)
{
// swap rows
// bottom row to buffer
NativeArray<Color32>.Copy(pixels, i * screenWidth, copyBuffer, 0, screenWidth);
// top row to bottom
NativeArray<Color32>.Copy(pixels, (screenHeight - i - 1) * screenWidth, pixels, i * screenWidth, screenWidth);
// buffer to top row
NativeArray<Color32>.Copy(copyBuffer, 0, pixels, (screenHeight - i - 1) * screenWidth, screenWidth);
}
} //else.. we're fine

var imageOutput = ImageConversion.EncodeNativeArrayToJPG(pixels, theGraphicsFormat, (uint)screenWidth, (uint)screenHeight);

RGDebug.LogDebug($"ScreenshotCapture - Captured screenshot for frame # {frame}");
AddFrame(frame, (imageOutput.ToArray(), screenWidth, screenHeight));
}
else
{
RGDebug.LogWarning($"ScreenshotCapture - Error capturing screenshot for frame # {frame}");
AddFrame(frame, null);
}
// the pixels from the GPU are upside down, we need to reverse this for it to be right side up
var halfHeight = screenHeight / 2;
for (var i = 0; i <= halfHeight; i++)
{
// swap rows
// bottom row to buffer
NativeArray<Color32>.Copy(pixels, i * screenWidth, copyBuffer, 0,
screenWidth);
// top row to bottom
NativeArray<Color32>.Copy(pixels, (screenHeight - i - 1) * screenWidth,
pixels, i * screenWidth, screenWidth);
// buffer to top row
NativeArray<Color32>.Copy(copyBuffer, 0, pixels,
(screenHeight - i - 1) * screenWidth, screenWidth);
}
} //else.. we're fine

var imageOutput = ImageConversion.EncodeNativeArrayToJPG(pixels, theGraphicsFormat,
(uint)screenWidth, (uint)screenHeight);

RGDebug.LogDebug($"ScreenshotCapture - Captured screenshot for frame # {frame}");
AddFrame(frame, (imageOutput.ToArray(), screenWidth, screenHeight));
}
else
{
RGDebug.LogWarning(
$"ScreenshotCapture - Error capturing screenshot for frame # {frame}");
AddFrame(frame, null);
}

HandleCompletedActionCallbacks();
});
HandleCompletedActionCallbacks();
});
// update from null to the real request
GPUReadbackRequests[frame] = readbackRequest;

}
catch (Exception e)
{
RGDebug.LogWarning($"ScreenshotCapture - Exception starting to capture screenshot for frame # {frame} - {e.Message}");
RGDebug.LogWarning(
$"ScreenshotCapture - Exception starting to capture screenshot for frame # {frame} - {e.Message}");
}

}
}
}
Expand Down

0 comments on commit 218acca

Please sign in to comment.