Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
MBetterc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Mbetter
MBetterc
Commits
3bdf31e2
Commit
3bdf31e2
authored
Dec 03, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add GPU rendering detection
parent
40789eb5
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
342 additions
and
4 deletions
+342
-4
gpu_debug.py
gpu_debug.py
+215
-0
player.py
mbetterclient/qt_player/player.py
+127
-4
No files found.
gpu_debug.py
0 → 100644
View file @
3bdf31e2
#!/usr/bin/env python3
"""
GPU Acceleration Diagnostic Script for Qt WebEngine
Tests GPU functionality and Qt WebEngine GPU acceleration status
"""
import
os
import
sys
import
subprocess
import
logging
from
pathlib
import
Path
# Setup logging
logging
.
basicConfig
(
level
=
logging
.
INFO
,
format
=
'
%(asctime)
s -
%(levelname)
s -
%(message)
s'
)
logger
=
logging
.
getLogger
(
__name__
)
def
run_command
(
cmd
,
shell
=
False
):
"""Run a command and return output"""
try
:
result
=
subprocess
.
run
(
cmd
,
shell
=
shell
,
capture_output
=
True
,
text
=
True
,
timeout
=
30
)
return
result
.
returncode
,
result
.
stdout
,
result
.
stderr
except
subprocess
.
TimeoutExpired
:
return
-
1
,
""
,
"Command timed out"
except
Exception
as
e
:
return
-
1
,
""
,
str
(
e
)
def
check_nvidia_gpu
():
"""Check NVIDIA GPU status"""
logger
.
info
(
"=== NVIDIA GPU Status ==="
)
# Check nvidia-smi
code
,
stdout
,
stderr
=
run_command
([
"nvidia-smi"
])
if
code
==
0
:
logger
.
info
(
"nvidia-smi output:"
)
logger
.
info
(
stdout
)
else
:
logger
.
error
(
f
"nvidia-smi failed: {stderr}"
)
# Check GPU processes
code
,
stdout
,
stderr
=
run_command
([
"nvidia-smi"
,
"pmon"
])
if
code
==
0
:
logger
.
info
(
"GPU processes:"
)
logger
.
info
(
stdout
)
else
:
logger
.
warning
(
f
"Could not check GPU processes: {stderr}"
)
def
check_opengl
():
"""Check OpenGL functionality"""
logger
.
info
(
"=== OpenGL Status ==="
)
# Check glxinfo
code
,
stdout
,
stderr
=
run_command
([
"glxinfo"
,
"|"
,
"head"
,
"-20"
],
shell
=
True
)
if
code
==
0
:
logger
.
info
(
"OpenGL info:"
)
logger
.
info
(
stdout
)
else
:
logger
.
warning
(
f
"glxinfo failed: {stderr}"
)
# Check if direct rendering is enabled
code
,
stdout
,
stderr
=
run_command
([
"glxinfo"
,
"|"
,
"grep"
,
"direct"
],
shell
=
True
)
if
code
==
0
:
logger
.
info
(
"Direct rendering status:"
)
logger
.
info
(
stdout
)
else
:
logger
.
warning
(
"Could not check direct rendering"
)
def
check_qt_environment
():
"""Check Qt environment variables"""
logger
.
info
(
"=== Qt Environment Variables ==="
)
qt_vars
=
[
'QT_QPA_PLATFORM'
,
'QT_DEBUG_PLUGINS'
,
'QTWEBENGINE_DISABLE_SANDBOX'
,
'QTWEBENGINE_CHROMIUM_FLAGS'
,
'QTWEBENGINE_REMOTE_DEBUGGING'
,
'LIBGL_ALWAYS_SOFTWARE'
,
'MESA_GL_VERSION_OVERRIDE'
,
'DISPLAY'
,
'XDG_SESSION_TYPE'
]
for
var
in
qt_vars
:
value
=
os
.
environ
.
get
(
var
)
if
value
:
logger
.
info
(
f
"{var}={value}"
)
else
:
logger
.
info
(
f
"{var}=<not set>"
)
def
check_qt_webengine_gpu
():
"""Check Qt WebEngine GPU acceleration"""
logger
.
info
(
"=== Qt WebEngine GPU Acceleration Test ==="
)
# Test Qt WebEngine GPU blacklist
test_flags
=
[
"--disable-gpu"
,
"--enable-gpu-rasterization"
,
"--enable-zero-copy"
,
"--disable-software-rasterizer"
]
for
flag
in
test_flags
:
logger
.
info
(
f
"Testing with flag: {flag}"
)
# This would require running a Qt app with these flags
def
create_qt_gpu_test
():
"""Create a minimal Qt WebEngine GPU test"""
logger
.
info
(
"=== Creating Qt GPU Test Script ==="
)
test_script
=
'''
import sys
import os
from PyQt6.QtWidgets import QApplication
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtCore import QUrl, QTimer
def test_gpu():
app = QApplication(sys.argv)
# Create WebEngine view
view = QWebEngineView()
# Test HTML with WebGL
html = """
<!DOCTYPE html>
<html>
<head>
<title>GPU Test</title>
</head>
<body>
<h1>Qt WebEngine GPU Test</h1>
<canvas id="glcanvas" width="300" height="300"></canvas>
<script>
const canvas = document.getElementById('glcanvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (gl) {
console.log('WebGL is supported');
gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
document.body.innerHTML += '<p style="color: green;">WebGL: SUCCESS</p>';
} else {
console.log('WebGL is not supported');
document.body.innerHTML += '<p style="color: red;">WebGL: FAILED</p>';
}
</script>
</body>
</html>
"""
view.setHtml(html)
view.show()
# Check GPU processes after 5 seconds
def check_gpu_processes():
import subprocess
try:
result = subprocess.run(['nvidia-smi', 'pmon'], capture_output=True, text=True)
print("GPU processes during Qt WebEngine test:")
print(result.stdout)
except Exception as e:
print(f"Could not check GPU processes: {e}")
QTimer.singleShot(5000, check_gpu_processes)
return app.exec()
if __name__ == "__main__":
sys.exit(test_gpu())
'''
with
open
(
'qt_gpu_test.py'
,
'w'
)
as
f
:
f
.
write
(
test_script
)
logger
.
info
(
"Created qt_gpu_test.py - run this to test Qt WebEngine GPU acceleration"
)
def
check_qt_plugins
():
"""Check Qt plugin availability"""
logger
.
info
(
"=== Qt Plugins Status ==="
)
try
:
from
PyQt6.QtCore
import
QLibraryInfo
plugins_path
=
QLibraryInfo
.
path
(
QLibraryInfo
.
LibraryPath
.
PluginsPath
)
logger
.
info
(
f
"Qt plugins path: {plugins_path}"
)
if
os
.
path
.
exists
(
plugins_path
):
# List platform plugins
platform_path
=
os
.
path
.
join
(
plugins_path
,
'platforms'
)
if
os
.
path
.
exists
(
platform_path
):
platforms
=
os
.
listdir
(
platform_path
)
logger
.
info
(
f
"Available platform plugins: {platforms}"
)
else
:
logger
.
warning
(
"No platforms plugin directory found"
)
else
:
logger
.
error
(
"Qt plugins path does not exist"
)
except
Exception
as
e
:
logger
.
error
(
f
"Could not check Qt plugins: {e}"
)
def
main
():
"""Main diagnostic function"""
logger
.
info
(
"Starting GPU acceleration diagnostics..."
)
check_nvidia_gpu
()
check_opengl
()
check_qt_environment
()
check_qt_plugins
()
create_qt_gpu_test
()
logger
.
info
(
"=== Diagnostic Complete ==="
)
logger
.
info
(
"Run 'python qt_gpu_test.py' to test Qt WebEngine GPU acceleration"
)
logger
.
info
(
"Check the output for WebGL support and GPU process monitoring"
)
if
__name__
==
"__main__"
:
main
()
\ No newline at end of file
mbetterclient/qt_player/player.py
View file @
3bdf31e2
...
...
@@ -650,19 +650,59 @@ class OverlayWebView(QWebEngineView):
def
setup_web_view
(
self
):
"""Setup web view with proper transparency for overlay"""
logger
.
debug
(
"OverlayWebView.setup_web_view() - Starting setup"
)
logger
.
info
(
"OverlayWebView.setup_web_view() - Starting setup"
)
#
Detect Mesa software render
ing
#
Enhanced GPU detection and logg
ing
import
os
is_mesa
=
os
.
environ
.
get
(
'LIBGL_ALWAYS_SOFTWARE'
)
==
'1'
or
\
os
.
environ
.
get
(
'MESA_GL_VERSION_OVERRIDE'
)
is
not
None
# Log GPU-related environment variables
gpu_env_vars
=
[
'LIBGL_ALWAYS_SOFTWARE'
,
'MESA_GL_VERSION_OVERRIDE'
,
'QTWEBENGINE_CHROMIUM_FLAGS'
,
'QT_QPA_PLATFORM'
,
'DISPLAY'
,
'XDG_SESSION_TYPE'
]
logger
.
info
(
"=== GPU Environment Check ==="
)
for
var
in
gpu_env_vars
:
value
=
os
.
environ
.
get
(
var
)
logger
.
info
(
f
"{var}: {value if value else '<not set>'}"
)
# Check for NVIDIA GPU
try
:
import
subprocess
result
=
subprocess
.
run
([
'nvidia-smi'
,
'--query-gpu=name,memory.total,memory.used'
,
'--format=csv,noheader,nounits'
],
capture_output
=
True
,
text
=
True
,
timeout
=
5
)
if
result
.
returncode
==
0
:
logger
.
info
(
f
"NVIDIA GPU detected: {result.stdout.strip()}"
)
else
:
logger
.
warning
(
"nvidia-smi not available or failed"
)
except
Exception
as
e
:
logger
.
warning
(
f
"Could not check NVIDIA GPU: {e}"
)
# Check OpenGL
try
:
result
=
subprocess
.
run
([
'glxinfo'
,
'|'
,
'grep'
,
'"OpenGL renderer"'
],
shell
=
True
,
capture_output
=
True
,
text
=
True
,
timeout
=
5
)
if
result
.
returncode
==
0
:
logger
.
info
(
f
"OpenGL renderer: {result.stdout.strip()}"
)
else
:
logger
.
warning
(
"Could not get OpenGL renderer info"
)
except
Exception
as
e
:
logger
.
warning
(
f
"Could not check OpenGL: {e}"
)
logger
.
info
(
f
"Mesa software rendering detection: {is_mesa}"
)
# Set transparent background on the web page
page
=
self
.
page
()
if
is_mesa
:
# Mesa-specific transparency settings
logger
.
debug
(
"Mesa software rendering detected - applying Mesa
transparency fixes"
)
logger
.
info
(
"Applying Mesa software rendering
transparency fixes"
)
page
.
setBackgroundColor
(
QColor
(
0
,
0
,
0
,
1
))
# Semi-transparent for Mesa
# Use CSS-based transparency for Mesa
page
.
runJavaScript
(
"""
...
...
@@ -671,6 +711,7 @@ class OverlayWebView(QWebEngineView):
"""
)
else
:
# Standard hardware transparency
logger
.
info
(
"Applying standard hardware transparency"
)
page
.
setBackgroundColor
(
QColor
(
0
,
0
,
0
,
0
))
# Fully transparent
# Widget should be visible but allow transparency
...
...
@@ -689,7 +730,7 @@ class OverlayWebView(QWebEngineView):
}
"""
)
logger
.
debug
(
f
"OverlayWebView setup completed - Mesa: {is_mesa}, transparency configured"
)
logger
.
info
(
f
"OverlayWebView setup completed - Mesa: {is_mesa}, transparency configured"
)
# Setup WebChannel
self
.
web_channel
=
QWebChannel
()
...
...
@@ -701,6 +742,9 @@ class OverlayWebView(QWebEngineView):
self
.
web_channel
.
registerObject
(
"overlay"
,
self
.
overlay_channel
)
page
.
setWebChannel
(
self
.
web_channel
)
# Monitor GPU processes after WebEngine initialization
self
.
_monitor_gpu_processes
()
# Console override moved to _enable_debug_console to ensure it runs after page load
# Note: Console message capturing via WebChannel is now handled by JavaScript overrides
...
...
@@ -1192,6 +1236,85 @@ class OverlayWebView(QWebEngineView):
except
Exception
as
e
:
logger
.
debug
(
f
"Failed to ensure console override: {e}"
)
def
_monitor_gpu_processes
(
self
):
"""Async GPU process monitoring for usability checking"""
try
:
logger
.
debug
(
"Starting async GPU process monitoring"
)
# Use QTimer for non-blocking GPU monitoring
from
PyQt6.QtCore
import
QTimer
def
check_gpu_async
():
"""Non-blocking GPU process check"""
try
:
import
subprocess
import
os
# Check for GPU processes that might interfere with video playback
gpu_processes
=
[]
# Check for known GPU-intensive processes
processes_to_check
=
[
'chrome'
,
'chromium'
,
'firefox'
,
'opera'
,
'safari'
]
for
proc_name
in
processes_to_check
:
try
:
# Use pgrep or tasklist to check for running processes
if
os
.
name
==
'nt'
:
# Windows
result
=
subprocess
.
run
([
'tasklist'
,
'/FI'
,
f
'IMAGENAME eq {proc_name}.exe'
],
capture_output
=
True
,
text
=
True
,
timeout
=
2
)
if
proc_name
.
lower
()
in
result
.
stdout
.
lower
():
gpu_processes
.
append
(
proc_name
)
else
:
# Unix-like systems
result
=
subprocess
.
run
([
'pgrep'
,
'-f'
,
proc_name
],
capture_output
=
True
,
text
=
True
,
timeout
=
2
)
if
result
.
returncode
==
0
:
gpu_processes
.
append
(
proc_name
)
except
(
subprocess
.
TimeoutExpired
,
subprocess
.
SubprocessError
,
FileNotFoundError
):
# Commands may not be available, continue
pass
if
gpu_processes
:
logger
.
info
(
f
"GPU-intensive processes detected: {', '.join(gpu_processes)}"
)
logger
.
warning
(
"Multiple GPU processes may impact video playback performance"
)
else
:
logger
.
debug
(
"No conflicting GPU processes detected"
)
# Check GPU memory usage if nvidia-smi is available
try
:
nvidia_result
=
subprocess
.
run
([
'nvidia-smi'
,
'--query-gpu=memory.used,memory.total'
,
'--format=csv,noheader,nounits'
],
capture_output
=
True
,
text
=
True
,
timeout
=
3
)
if
nvidia_result
.
returncode
==
0
:
lines
=
nvidia_result
.
stdout
.
strip
()
.
split
(
'
\n
'
)
for
i
,
line
in
enumerate
(
lines
):
if
','
in
line
:
used
,
total
=
line
.
split
(
','
)
used
=
int
(
used
.
strip
())
total
=
int
(
total
.
strip
())
usage_percent
=
(
used
/
total
)
*
100
if
total
>
0
else
0
logger
.
debug
(
f
"GPU {i} memory usage: {used}MB/{total}MB ({usage_percent:.1f}
%
)"
)
if
usage_percent
>
90
:
logger
.
warning
(
f
"GPU {i} memory usage is very high: {usage_percent:.1f}
%
"
)
except
(
subprocess
.
TimeoutExpired
,
subprocess
.
SubprocessError
,
FileNotFoundError
):
# nvidia-smi not available or failed
pass
except
Exception
as
e
:
logger
.
debug
(
f
"GPU monitoring check failed: {e}"
)
# Schedule the first check after a delay, then periodically
QTimer
.
singleShot
(
2000
,
check_gpu_async
)
# First check after 2 seconds
# Set up periodic monitoring every 30 seconds
self
.
_gpu_monitor_timer
=
QTimer
()
self
.
_gpu_monitor_timer
.
timeout
.
connect
(
check_gpu_async
)
self
.
_gpu_monitor_timer
.
start
(
30000
)
# 30 seconds
logger
.
debug
(
"GPU process monitoring scheduled"
)
except
Exception
as
e
:
logger
.
error
(
f
"Failed to start GPU process monitoring: {e}"
)
# Removed _on_javaScript_console_message method as console capturing now uses WebChannel
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment