mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 23:07:18 +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/kb.c
|
||||
src/egl_dynprocs.c
|
||||
src/eglutil.c
|
||||
)
|
||||
|
||||
# Force cimgui to build as a static library.
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
||||
#include "egl_dynprocs.h"
|
||||
#include "eglutil.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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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");
|
||||
swapWithDamageDisable(&wlWm.swapWithDamage);
|
||||
}
|
||||
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();
|
||||
wlWm.eglSwapWithDamage(display, surface, wlWm.eglDamageRects, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
waylandPresentationFrame();
|
||||
eglSwapBuffers(display, surface);
|
||||
}
|
||||
waylandPresentationFrame();
|
||||
swapWithDamage(&wlWm.swapWithDamage, display, surface, damage, count);
|
||||
|
||||
if (wlWm.needsResize)
|
||||
{
|
||||
|
@ -27,6 +27,7 @@
|
||||
# include <wayland-egl.h>
|
||||
# include <EGL/egl.h>
|
||||
# include <EGL/eglext.h>
|
||||
# include "eglutil.h"
|
||||
#endif
|
||||
|
||||
#include "app.h"
|
||||
@ -101,10 +102,7 @@ struct WaylandDSState
|
||||
|
||||
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
||||
struct wl_egl_window * eglWindow;
|
||||
bool eglSwapWithDamageInit;
|
||||
eglSwapBuffersWithDamageKHR_t eglSwapWithDamage;
|
||||
EGLint * eglDamageRects;
|
||||
int eglDamageRectCount;
|
||||
struct SwapWithDamageData swapWithDamage;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
|
@ -38,6 +38,7 @@
|
||||
#ifdef ENABLE_EGL
|
||||
#include <EGL/eglext.h>
|
||||
#include "egl_dynprocs.h"
|
||||
#include "eglutil.h"
|
||||
#endif
|
||||
|
||||
#include "app.h"
|
||||
@ -943,40 +944,11 @@ static EGLNativeWindowType x11GetEGLNativeWindow(void)
|
||||
static void x11EGLSwapBuffers(EGLDisplay display, EGLSurface surface,
|
||||
const struct Rect * damage, int count)
|
||||
{
|
||||
static bool detectDone = false;
|
||||
static eglSwapBuffersWithDamageKHR_t swapWithDamage = NULL;
|
||||
static struct SwapWithDamageData data = {0};
|
||||
if (!data.init)
|
||||
swapWithDamageInit(&data, display);
|
||||
|
||||
if (!detectDone)
|
||||
{
|
||||
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);
|
||||
swapWithDamage(&data, display, surface, damage, count);
|
||||
}
|
||||
#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