mesa/tests/gtk4_render_test.py
Peter Kopec 19b63476db Include universal gating smoke test suite
Resolves: RHEL-154255
2026-03-11 09:57:51 +01:00

147 lines
4.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""
GTK4 Rendering Test - Verifies actual rendering by drawing and saving
Tests the s390x Mesa bug where GTK apps show black screens
"""
import sys
import os
# Parse renderer argument BEFORE importing GTK
# GSK_RENDERER must be set before GTK initializes
renderer = None
output_file = None
for i, arg in enumerate(sys.argv[1:], 1):
if arg.startswith('--renderer='):
renderer = arg.split('=', 1)[1]
elif not arg.startswith('--'):
output_file = arg
if renderer:
os.environ['GSK_RENDERER'] = renderer
print(f"Setting GSK_RENDERER={renderer} before GTK import")
#Set debug to print rear renderer of app
os.environ['GSK_DEBUG'] = "renderer"
# Now import GTK (after setting environment)
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, GLib
import cairo
class RenderTestApp(Gtk.Application):
def __init__(self, output_file):
super().__init__(application_id='org.test.gtk4render')
self.output_file = output_file
self.rendered = False
self.drawing_area = None
def do_activate(self):
window = Gtk.ApplicationWindow(application=self)
window.set_title("GTK4 Rendering Test")
window.set_default_size(400, 300)
self.drawing_area = Gtk.DrawingArea()
self.drawing_area.set_draw_func(self.draw_callback)
window.set_child(self.drawing_area)
window.present()
# Wait for rendering, then save and quit
GLib.timeout_add(2000, self.save_and_quit)
def draw_callback(self, area, cr, width, height):
"""Draw colorful pattern to prove rendering works"""
# Red rectangle
cr.set_source_rgb(1.0, 0.0, 0.0)
cr.rectangle(10, 10, 100, 100)
cr.fill()
# Green rectangle
cr.set_source_rgb(0.0, 1.0, 0.0)
cr.rectangle(130, 10, 100, 100)
cr.fill()
# Blue rectangle
cr.set_source_rgb(0.0, 0.0, 1.0)
cr.rectangle(250, 10, 100, 100)
cr.fill()
# Yellow circle
cr.set_source_rgb(1.0, 1.0, 0.0)
cr.arc(200, 200, 50, 0, 2 * 3.14159)
cr.fill()
print(f"Draw callback called - rendering {width}x{height} surface")
self.rendered = True
def save_and_quit(self):
"""Save the rendered surface to PNG and exit"""
if not self.rendered:
print("WARNING: Draw function not called yet")
print("RESULT: WARN - Rendering may not have occurred")
self.quit()
return False
try:
# Get the window and widget dimensions
width = self.drawing_area.get_width()
height = self.drawing_area.get_height()
print(f"Creating Cairo surface {width}x{height}")
# Create a Cairo image surface
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
cr = cairo.Context(surface)
# Re-render to this surface
self.draw_callback(None, cr, width, height)
# Save to PNG
surface.write_to_png(self.output_file)
# Check file was created and has reasonable size
if os.path.exists(self.output_file):
file_size = os.path.getsize(self.output_file)
print(f"SUCCESS: Saved rendering to {self.output_file} ({file_size} bytes)")
if file_size > 1000:
print("RESULT: PASS - Rendering verified")
else:
print(f"RESULT: FAIL - PNG file too small ({file_size} bytes)")
else:
print(f"RESULT: FAIL - Failed to create {self.output_file}")
except Exception as e:
print(f"ERROR: {e}")
import traceback
traceback.print_exc()
print("RESULT: FAIL - Exception during rendering")
self.quit()
return False
def main():
global output_file
if not output_file:
print(f"Usage: {sys.argv[0]} <output.png> [--renderer=ngl|gl|cairo|vulkan]")
print(f" --renderer: GSK renderer to use (default: auto-detect)")
sys.exit(1)
print(f"GTK4 Rendering Test - will save to {output_file}")
print(f"GSK_RENDERER: {os.environ.get('GSK_RENDERER', 'not set (auto-detect)')}")
print(f"GTK_RENDERER: {os.environ.get('GTK_RENDERER', 'not set')}")
app = RenderTestApp(output_file)
exit_status = app.run(None)
sys.exit(exit_status)
if __name__ == '__main__':
main()