mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-10 19:43:23 +09:00
[Feature] (GL): glFlush presents the display host's frame for a compositor that never swaps
kwin draws the desktop into the display host's frame and then calls glFlush - and glFlush alone; it never calls eglSwapBuffers. The stream reached the server and the server drew, but the display host was never told a frame was done, so nothing reached the glass. When the surfaceless-bind hook has taken the host frame, glFlush now swaps that surface after flushing the stream: that swap is the host's "frame is done". A swap of a surface the EGL state does not know used to return EGL_BAD_SURFACE without a word - the whole reason the host frame's presents were invisible - so that refusal is now reported once.
This commit is contained in:
@@ -254,6 +254,7 @@ namespace MobileGL::MG_Impl::EGLImpl {
|
||||
return EGL_FALSE;
|
||||
}
|
||||
if (!state->ValidateSurfaceOnDisplay(dpy, draw)) {
|
||||
MGLOG_E_ONCE("eglSwapBuffers: surface %p is not a surface of display %p (EGL_BAD_SURFACE)", draw, dpy);
|
||||
state->SetError(EGL_BAD_SURFACE);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
// names is an object eglCreateImageKHR built (its geometry, its fourcc and the descriptors it owns),
|
||||
// and that object lives in the EGL state. Same include the other GLImpl files that touch it use.
|
||||
#include <MG_State/EGLState/Core.h>
|
||||
// The compositor's frame boundary: glFlush presents the display host's frame when the surfaceless
|
||||
// bind hook took one (see EGLImpl.cpp). The EGL side declares the pair and the swap entry.
|
||||
#include <MG_Impl/EGLImpl/EGLImpl.h>
|
||||
|
||||
#define DECLARE_GL_FUNCTION_STUB_HEAD(type, name, ...) MOBILEGL_GL_API type gl##name(__VA_ARGS__) {
|
||||
|
||||
@@ -132,6 +135,17 @@ MOBILEGL_GL_API void glFlush() {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
MobileGL::MG_Pipe::MGPipeClientFlush();
|
||||
#endif
|
||||
// A COMPOSITOR'S FRAME BOUNDARY. kwin binds the display host's frame surface and draws the
|
||||
// desktop into it, then calls glFlush - and glFlush alone. It never calls eglSwapBuffers, so
|
||||
// without this the stream reached the server and the server drew, but the display host was
|
||||
// never told a frame was done: the host's own present loop (AHardwareBuffer_acquire ->
|
||||
// draw -> notify) is what puts pixels on the glass, and its notify is exactly this swap.
|
||||
// Guarded by whether the surfaceless-bind hook actually took the host frame.
|
||||
if (MobileGL::MG_Impl::EGLImpl::g_hostFramePresentSurface != nullptr &&
|
||||
MobileGL::MG_Impl::EGLImpl::g_hostFramePresentDisplay != nullptr) {
|
||||
MobileGL::MG_Impl::EGLImpl::SwapBuffers(MobileGL::MG_Impl::EGLImpl::g_hostFramePresentDisplay,
|
||||
MobileGL::MG_Impl::EGLImpl::g_hostFramePresentSurface);
|
||||
}
|
||||
}
|
||||
DECLARE_GL_FUNCTION_HEAD(void, FramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, FramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, FramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) DECLARE_GL_FUNCTION_END_NO_RETURN(void, FramebufferTexture2D, target, attachment, textarget, texture, level)
|
||||
|
||||
Reference in New Issue
Block a user