mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Fix] (WSI): report Wayland present failure and keep GLX drawables off XIDs
Wayland Present() failure now returns EGL_BAD_SURFACE instead of being dropped. In spawn mode a GLX X drawable is backed by a remote pbuffer so the XID is never mistaken for an Android ANativeWindow; X11 pixel present and remote resize are still unimplemented.
This commit is contained in:
@@ -302,7 +302,10 @@ namespace MobileGL::MG_Impl::EGLImpl {
|
||||
#if MOBILEGL_WAYLAND_WINDOWS
|
||||
// A Wayland window shows what is attached to it: the frame is read back and attached
|
||||
// BEFORE the swap, while it is still the drawable's content.
|
||||
if (auto it = WaylandSurfaces().find(draw); it != WaylandSurfaces().end()) (void)it->second->Present();
|
||||
if (auto it = WaylandSurfaces().find(draw); it != WaylandSurfaces().end() && !it->second->Present()) {
|
||||
state->SetError(EGL_BAD_SURFACE);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
#endif
|
||||
if (!backendObject->SwapEGLBuffers(dpy, draw)) {
|
||||
MGLOG_E_ONCE("eglSwapBuffers failed on thread=%s dpy=%p draw=%p", CurrentThreadIdString().c_str(), dpy, draw);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../EGLImpl/EGLImpl.h"
|
||||
#include "../GetProcAddress.h"
|
||||
#include <Init.h>
|
||||
#include <Config.h>
|
||||
|
||||
namespace MobileGL::MG_Impl::GLXImpl {
|
||||
namespace {
|
||||
@@ -187,6 +188,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
||||
Uint32 Width = 0;
|
||||
Uint32 Height = 0;
|
||||
std::chrono::steady_clock::time_point LastSizePoll{};
|
||||
Bool RemotePbuffer = false;
|
||||
};
|
||||
|
||||
std::recursive_mutex& RegistryMutex() {
|
||||
@@ -294,6 +296,10 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
||||
if (width == surface.Width && height == surface.Height) {
|
||||
return;
|
||||
}
|
||||
// A remote X drawable is backed by a pbuffer; an XID has no meaning
|
||||
// to the Android worker. Its allocation cannot be resized by the
|
||||
// native-window hook. Keep the current allocation until recreated.
|
||||
if (surface.RemotePbuffer) return;
|
||||
if (EGLImpl::ResizePlatformWindowSurface(surface.Display, surface.Surface,
|
||||
static_cast<EGLint>(width),
|
||||
static_cast<EGLint>(height))) {
|
||||
@@ -323,8 +329,13 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
||||
EGL_HEIGHT, static_cast<EGLAttrib>(height),
|
||||
EGL_NONE,
|
||||
};
|
||||
EGLSurface surface = EGLImpl::CreatePlatformWindowSurface(
|
||||
context.Display, context.Config, reinterpret_cast<void*>(drawable), attribs);
|
||||
const Bool remotePbuffer = MG_Config::Transport == MG_Config::TransportMode::Spawn;
|
||||
const EGLint pbufferAttribs[] = {EGL_WIDTH, static_cast<EGLint>(width),
|
||||
EGL_HEIGHT, static_cast<EGLint>(height), EGL_NONE};
|
||||
EGLSurface surface = remotePbuffer
|
||||
? EGLImpl::CreatePbufferSurface(context.Display, context.Config, pbufferAttribs)
|
||||
: EGLImpl::CreatePlatformWindowSurface(
|
||||
context.Display, context.Config, reinterpret_cast<void*>(drawable), attribs);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
MGLOG_E_ONCE("glx: failed to create window surface for drawable 0x%lx (%ux%u)", drawable,
|
||||
width, height);
|
||||
@@ -336,6 +347,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
||||
record.Surface = surface;
|
||||
record.Width = width;
|
||||
record.Height = height;
|
||||
record.RemotePbuffer = remotePbuffer;
|
||||
record.LastSizePoll = std::chrono::steady_clock::now();
|
||||
auto [inserted, _] = surfaces.emplace(drawable, record);
|
||||
return &inserted->second;
|
||||
|
||||
Reference in New Issue
Block a user