You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/screenshot_utils.py

111 lines
4.5 KiB
Python

"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import azlmbr.atom
import azlmbr.legacy.general as general
from editor_python_test_tools.editor_test_helper import EditorTestHelper
DEFAULT_FRAME_WIDTH = 1920
DEFAULT_FRAME_HEIGHT = 1080
FOLDER_PATH = '@user@/PythonTests/Automated/Screenshots'
helper = EditorTestHelper(log_prefix="Atom_ScreenshotHelper")
class ScreenshotHelper(object):
"""
A helper to capture screenshots and wait for them.
"""
def __init__(self, idle_wait_frames_callback, frame_width=DEFAULT_FRAME_WIDTH, frame_height=DEFAULT_FRAME_HEIGHT):
super().__init__()
self.done = False
self.capturedScreenshot = False
self.max_frames_to_wait = 60
self.prepare_viewport_for_screenshot(frame_width, frame_height)
self.idle_wait_frames_callback = idle_wait_frames_callback
def capture_screenshot_blocking_in_game_mode(self, filename):
helper.enter_game_mode(["", ""])
general.idle_wait_frames(120)
self.capture_screenshot_blocking(filename)
helper.exit_game_mode(["", ""])
def prepare_viewport_for_screenshot(self, frame_width, frame_height):
cur_viewport_size = general.get_viewport_size()
if int(cur_viewport_size.x) != frame_width or int(cur_viewport_size.y) != frame_height:
general.set_viewport_expansion_policy('FixedSize')
general.idle_wait_frames(1)
general.set_viewport_size(frame_width, frame_height)
general.set_cvar_integer('r_DisplayInfo', 0)
general.update_viewport()
general.idle_wait_frames(120)
new_viewport_size = general.get_viewport_size()
if int(new_viewport_size.x) != frame_width or int(new_viewport_size.y) != frame_height:
general.log("Resolution is incorrect!")
general.log(f"width: {int(new_viewport_size.x)}")
general.log(f"height: {int(new_viewport_size.y)}")
def capture_screenshot_blocking(self, filename, folder_path=FOLDER_PATH):
"""
Capture a screenshot and block the execution until the screenshot has been written to the disk.
"""
self.handler = azlmbr.atom.FrameCaptureNotificationBusHandler()
self.handler.connect()
self.handler.add_callback('OnCaptureFinished', self.on_screenshot_captured)
self.done = False
self.capturedScreenshot = False
success = azlmbr.atom.FrameCaptureRequestBus(
azlmbr.bus.Broadcast, "CaptureScreenshot", f"{folder_path}/{filename}")
if success:
self.wait_until_screenshot()
general.log("Screenshot taken.")
else:
general.log("Screenshot failed")
return self.capturedScreenshot
def on_screenshot_captured(self, parameters):
# the parameters come in as a tuple
if parameters[0] == azlmbr.atom.FrameCaptureResult_Success:
general.log(f"screenshot saved: {parameters[1]}")
self.capturedScreenshot = True
else:
general.log(f"screenshot failed: {parameters[1]}")
self.done = True
self.handler.disconnect()
def wait_until_screenshot(self):
frames_waited = 0
while self.done == False:
self.idle_wait_frames_callback(1)
if frames_waited > self.max_frames_to_wait:
general.log("timeout while waiting for the screenshot to be written")
self.handler.disconnect()
break
else:
frames_waited = frames_waited + 1
general.log(f"(waited {frames_waited} frames)")
def take_screenshot_game_mode(screenshot_name, entity_name=None):
"""
Enters game mode & takes a screenshot, then exits game mode after.
:param screenshot_name: name to give the captured screenshot .ppm file.
:param entity_name: name of the entity being tested (for generating unique log lines).
:return: None
"""
general.enter_game_mode()
helper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0)
general.log(f"{entity_name}_test: Entered game mode: {general.is_in_game_mode()}")
ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{screenshot_name}.ppm")
general.idle_wait(1.0)
general.exit_game_mode()
helper.wait_for_condition(lambda: not general.is_in_game_mode(), 2.0)
general.log(f"{entity_name}_test: Exit game mode: {not general.is_in_game_mode()}")