mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-26 07:17:23 +00:00
[client] ds: refactor common EGL swap with damage logic
This commit creates a new utility library, eglutil.h, which contains code to detect and use EGL_KHR_swap_buffers_with_damage or its EXT equivalent. This logic used to be duplicated between the X11 and Wayland display servers, which is not ideal.
This commit is contained in:
parent
a8d4668c4d
commit
0cbc529640
@ -119,6 +119,7 @@ set(SOURCES
|
|||||||
src/clipboard.c
|
src/clipboard.c
|
||||||
src/kb.c
|
src/kb.c
|
||||||
src/egl_dynprocs.c
|
src/egl_dynprocs.c
|
||||||
|
src/eglutil.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Force cimgui to build as a static library.
|
# Force cimgui to build as a static library.
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
||||||
#include "egl_dynprocs.h"
|
#include "egl_dynprocs.h"
|
||||||
|
#include "eglutil.h"
|
||||||
|
|
||||||
bool waylandEGLInit(int w, int h)
|
bool waylandEGLInit(int w, int h)
|
||||||
{
|
{
|
||||||
@ -71,53 +72,19 @@ EGLDisplay waylandGetEGLDisplay(void)
|
|||||||
|
|
||||||
void waylandEGLSwapBuffers(EGLDisplay display, EGLSurface surface, const struct Rect * damage, int count)
|
void waylandEGLSwapBuffers(EGLDisplay display, EGLSurface surface, const struct Rect * damage, int count)
|
||||||
{
|
{
|
||||||
if (!wlWm.eglSwapWithDamageInit)
|
if (!wlWm.swapWithDamage.init)
|
||||||
{
|
{
|
||||||
const char *exts = eglQueryString(display, EGL_EXTENSIONS);
|
|
||||||
wlWm.eglSwapWithDamageInit = true;
|
|
||||||
if (wl_proxy_get_version((struct wl_proxy *) wlWm.surface) < 4)
|
if (wl_proxy_get_version((struct wl_proxy *) wlWm.surface) < 4)
|
||||||
|
{
|
||||||
DEBUG_INFO("Swapping buffers with damage: not supported, need wl_compositor v4");
|
DEBUG_INFO("Swapping buffers with damage: not supported, need wl_compositor v4");
|
||||||
else if (util_hasGLExt(exts, "EGL_KHR_swap_buffers_with_damage") && g_egl_dynProcs.eglSwapBuffersWithDamageKHR)
|
swapWithDamageDisable(&wlWm.swapWithDamage);
|
||||||
{
|
|
||||||
wlWm.eglSwapWithDamage = g_egl_dynProcs.eglSwapBuffersWithDamageKHR;
|
|
||||||
DEBUG_INFO("Using EGL_KHR_swap_buffers_with_damage");
|
|
||||||
}
|
|
||||||
else if (util_hasGLExt(exts, "EGL_EXT_swap_buffers_with_damage") && g_egl_dynProcs.eglSwapBuffersWithDamageEXT)
|
|
||||||
{
|
|
||||||
wlWm.eglSwapWithDamage = g_egl_dynProcs.eglSwapBuffersWithDamageEXT;
|
|
||||||
DEBUG_INFO("Using EGL_EXT_swap_buffers_with_damage");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DEBUG_INFO("Swapping buffers with damage: not supported");
|
swapWithDamageInit(&wlWm.swapWithDamage, display);
|
||||||
}
|
|
||||||
|
|
||||||
if (wlWm.eglSwapWithDamage && count)
|
|
||||||
{
|
|
||||||
if (count * 4 > wlWm.eglDamageRectCount)
|
|
||||||
{
|
|
||||||
free(wlWm.eglDamageRects);
|
|
||||||
wlWm.eglDamageRects = malloc(sizeof(EGLint) * count * 4);
|
|
||||||
if (!wlWm.eglDamageRects)
|
|
||||||
DEBUG_FATAL("Out of memory");
|
|
||||||
wlWm.eglDamageRectCount = count * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
wlWm.eglDamageRects[i*4+0] = damage[i].x;
|
|
||||||
wlWm.eglDamageRects[i*4+1] = damage[i].y;
|
|
||||||
wlWm.eglDamageRects[i*4+2] = damage[i].w;
|
|
||||||
wlWm.eglDamageRects[i*4+3] = damage[i].h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
waylandPresentationFrame();
|
waylandPresentationFrame();
|
||||||
wlWm.eglSwapWithDamage(display, surface, wlWm.eglDamageRects, count);
|
swapWithDamage(&wlWm.swapWithDamage, display, surface, damage, count);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
waylandPresentationFrame();
|
|
||||||
eglSwapBuffers(display, surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wlWm.needsResize)
|
if (wlWm.needsResize)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
# include <wayland-egl.h>
|
# include <wayland-egl.h>
|
||||||
# include <EGL/egl.h>
|
# include <EGL/egl.h>
|
||||||
# include <EGL/eglext.h>
|
# include <EGL/eglext.h>
|
||||||
|
# include "eglutil.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
@ -101,10 +102,7 @@ struct WaylandDSState
|
|||||||
|
|
||||||
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
||||||
struct wl_egl_window * eglWindow;
|
struct wl_egl_window * eglWindow;
|
||||||
bool eglSwapWithDamageInit;
|
struct SwapWithDamageData swapWithDamage;
|
||||||
eglSwapBuffersWithDamageKHR_t eglSwapWithDamage;
|
|
||||||
EGLint * eglDamageRects;
|
|
||||||
int eglDamageRectCount;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_OPENGL
|
#ifdef ENABLE_OPENGL
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#ifdef ENABLE_EGL
|
#ifdef ENABLE_EGL
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
#include "egl_dynprocs.h"
|
#include "egl_dynprocs.h"
|
||||||
|
#include "eglutil.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
@ -943,40 +944,11 @@ static EGLNativeWindowType x11GetEGLNativeWindow(void)
|
|||||||
static void x11EGLSwapBuffers(EGLDisplay display, EGLSurface surface,
|
static void x11EGLSwapBuffers(EGLDisplay display, EGLSurface surface,
|
||||||
const struct Rect * damage, int count)
|
const struct Rect * damage, int count)
|
||||||
{
|
{
|
||||||
static bool detectDone = false;
|
static struct SwapWithDamageData data = {0};
|
||||||
static eglSwapBuffersWithDamageKHR_t swapWithDamage = NULL;
|
if (!data.init)
|
||||||
|
swapWithDamageInit(&data, display);
|
||||||
|
|
||||||
if (!detectDone)
|
swapWithDamage(&data, display, surface, damage, count);
|
||||||
{
|
|
||||||
const char *exts = eglQueryString(display, EGL_EXTENSIONS);
|
|
||||||
DEBUG_INFO("%s", exts);
|
|
||||||
if (util_hasGLExt(exts, "EGL_KHR_swap_buffers_with_damage"))
|
|
||||||
swapWithDamage = g_egl_dynProcs.eglSwapBuffersWithDamageKHR;
|
|
||||||
else if (util_hasGLExt(exts, "EGL_EXT_swap_buffers_with_damage"))
|
|
||||||
swapWithDamage = g_egl_dynProcs.eglSwapBuffersWithDamageEXT;
|
|
||||||
|
|
||||||
if (swapWithDamage)
|
|
||||||
DEBUG_INFO("Using eglSwapBuffersWithDamage");
|
|
||||||
|
|
||||||
detectDone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (swapWithDamage && count)
|
|
||||||
{
|
|
||||||
EGLint rects[count*4];
|
|
||||||
EGLint *p = rects;
|
|
||||||
for(int i = 0; i < count; ++i, p += 4)
|
|
||||||
{
|
|
||||||
p[0] = damage[i].x;
|
|
||||||
p[1] = damage[i].y;
|
|
||||||
p[2] = damage[i].w;
|
|
||||||
p[3] = damage[i].h;
|
|
||||||
}
|
|
||||||
|
|
||||||
swapWithDamage(display, surface, rects, count);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
eglSwapBuffers(display, surface);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
41
client/include/eglutil.h
Normal file
41
client/include/eglutil.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Looking Glass
|
||||||
|
* Copyright (C) 2017-2021 The Looking Glass Authors
|
||||||
|
* https://looking-glass.io
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_LG_GLUTIL_
|
||||||
|
#define _H_LG_GLUTIL_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "egl_dynprocs.h"
|
||||||
|
|
||||||
|
struct SwapWithDamageData
|
||||||
|
{
|
||||||
|
bool init;
|
||||||
|
eglSwapBuffersWithDamageKHR_t func;
|
||||||
|
};
|
||||||
|
|
||||||
|
void swapWithDamageInit(struct SwapWithDamageData * data, EGLDisplay display);
|
||||||
|
void swapWithDamageDisable(struct SwapWithDamageData * data);
|
||||||
|
void swapWithDamage(struct SwapWithDamageData * data, EGLDisplay display, EGLSurface surface,
|
||||||
|
const struct Rect * damage, int count);
|
||||||
|
|
||||||
|
#endif
|
73
client/src/eglutil.c
Normal file
73
client/src/eglutil.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* Looking Glass
|
||||||
|
* Copyright (C) 2017-2021 The Looking Glass Authors
|
||||||
|
* https://looking-glass.io
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "eglutil.h"
|
||||||
|
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "egl_dynprocs.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
void swapWithDamageInit(struct SwapWithDamageData * data, EGLDisplay display)
|
||||||
|
{
|
||||||
|
const char *exts = eglQueryString(display, EGL_EXTENSIONS);
|
||||||
|
data->init = true;
|
||||||
|
|
||||||
|
if (util_hasGLExt(exts, "EGL_KHR_swap_buffers_with_damage") && g_egl_dynProcs.eglSwapBuffersWithDamageKHR)
|
||||||
|
{
|
||||||
|
data->func = g_egl_dynProcs.eglSwapBuffersWithDamageKHR;
|
||||||
|
DEBUG_INFO("Using EGL_KHR_swap_buffers_with_damage");
|
||||||
|
}
|
||||||
|
else if (util_hasGLExt(exts, "EGL_EXT_swap_buffers_with_damage") && g_egl_dynProcs.eglSwapBuffersWithDamageEXT)
|
||||||
|
{
|
||||||
|
data->func = g_egl_dynProcs.eglSwapBuffersWithDamageEXT;
|
||||||
|
DEBUG_INFO("Using EGL_EXT_swap_buffers_with_damage");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->func = NULL;
|
||||||
|
DEBUG_INFO("Swapping buffers with damage: not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void swapWithDamageDisable(struct SwapWithDamageData * data)
|
||||||
|
{
|
||||||
|
data->init = false;
|
||||||
|
data->func = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swapWithDamage(struct SwapWithDamageData * data, EGLDisplay display, EGLSurface surface,
|
||||||
|
const struct Rect * damage, int count)
|
||||||
|
{
|
||||||
|
if (!data->func || !count)
|
||||||
|
{
|
||||||
|
eglSwapBuffers(display, surface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLint rects[count * 4];
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
rects[i * 4 + 0] = damage[i].x;
|
||||||
|
rects[i * 4 + 1] = damage[i].y;
|
||||||
|
rects[i * 4 + 2] = damage[i].w;
|
||||||
|
rects[i * 4 + 3] = damage[i].h;
|
||||||
|
}
|
||||||
|
data->func(display, surface, rects, count);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user