mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 10:03:23 +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
|
#if MOBILEGL_WAYLAND_WINDOWS
|
||||||
// A Wayland window shows what is attached to it: the frame is read back and attached
|
// 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.
|
// 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
|
#endif
|
||||||
if (!backendObject->SwapEGLBuffers(dpy, draw)) {
|
if (!backendObject->SwapEGLBuffers(dpy, draw)) {
|
||||||
MGLOG_E_ONCE("eglSwapBuffers failed on thread=%s dpy=%p draw=%p", CurrentThreadIdString().c_str(), 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 "../EGLImpl/EGLImpl.h"
|
||||||
#include "../GetProcAddress.h"
|
#include "../GetProcAddress.h"
|
||||||
#include <Init.h>
|
#include <Init.h>
|
||||||
|
#include <Config.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Impl::GLXImpl {
|
namespace MobileGL::MG_Impl::GLXImpl {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -187,6 +188,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
|||||||
Uint32 Width = 0;
|
Uint32 Width = 0;
|
||||||
Uint32 Height = 0;
|
Uint32 Height = 0;
|
||||||
std::chrono::steady_clock::time_point LastSizePoll{};
|
std::chrono::steady_clock::time_point LastSizePoll{};
|
||||||
|
Bool RemotePbuffer = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::recursive_mutex& RegistryMutex() {
|
std::recursive_mutex& RegistryMutex() {
|
||||||
@@ -294,6 +296,10 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
|||||||
if (width == surface.Width && height == surface.Height) {
|
if (width == surface.Width && height == surface.Height) {
|
||||||
return;
|
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,
|
if (EGLImpl::ResizePlatformWindowSurface(surface.Display, surface.Surface,
|
||||||
static_cast<EGLint>(width),
|
static_cast<EGLint>(width),
|
||||||
static_cast<EGLint>(height))) {
|
static_cast<EGLint>(height))) {
|
||||||
@@ -323,8 +329,13 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
|||||||
EGL_HEIGHT, static_cast<EGLAttrib>(height),
|
EGL_HEIGHT, static_cast<EGLAttrib>(height),
|
||||||
EGL_NONE,
|
EGL_NONE,
|
||||||
};
|
};
|
||||||
EGLSurface surface = EGLImpl::CreatePlatformWindowSurface(
|
const Bool remotePbuffer = MG_Config::Transport == MG_Config::TransportMode::Spawn;
|
||||||
context.Display, context.Config, reinterpret_cast<void*>(drawable), attribs);
|
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) {
|
if (surface == EGL_NO_SURFACE) {
|
||||||
MGLOG_E_ONCE("glx: failed to create window surface for drawable 0x%lx (%ux%u)", drawable,
|
MGLOG_E_ONCE("glx: failed to create window surface for drawable 0x%lx (%ux%u)", drawable,
|
||||||
width, height);
|
width, height);
|
||||||
@@ -336,6 +347,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
|
|||||||
record.Surface = surface;
|
record.Surface = surface;
|
||||||
record.Width = width;
|
record.Width = width;
|
||||||
record.Height = height;
|
record.Height = height;
|
||||||
|
record.RemotePbuffer = remotePbuffer;
|
||||||
record.LastSizePoll = std::chrono::steady_clock::now();
|
record.LastSizePoll = std::chrono::steady_clock::now();
|
||||||
auto [inserted, _] = surfaces.emplace(drawable, record);
|
auto [inserted, _] = surfaces.emplace(drawable, record);
|
||||||
return &inserted->second;
|
return &inserted->second;
|
||||||
|
|||||||
Reference in New Issue
Block a user