[client] all: unify the LG splash screen into an overlay

This commit is contained in:
Geoffrey McRae
2022-05-27 02:07:20 +10:00
parent 8974ae4fb5
commit 5de175c1f3
13 changed files with 200 additions and 427 deletions

View File

@@ -55,10 +55,6 @@ build_shaders(
shader/cursor_mono.frag
shader/damage.vert
shader/damage.frag
shader/splash_bg.vert
shader/splash_bg.frag
shader/splash_logo.vert
shader/splash_logo.frag
shader/basic.vert
shader/ffx_cas.frag
shader/ffx_fsr1_easu.frag
@@ -87,7 +83,6 @@ add_library(renderer_EGL STATIC
desktop_rects.c
cursor.c
draw.c
splash.c
damage.c
framebuffer.c
postprocess.c

View File

@@ -45,11 +45,9 @@
#include "damage.h"
#include "desktop.h"
#include "cursor.h"
#include "splash.h"
#include "postprocess.h"
#include "util.h"
#define SPLASH_FADE_TIME 1000000
#define MAX_BUFFER_AGE 3
#define DESKTOP_DAMAGE_COUNT 4
#define MAX_ACCUMULATED_DAMAGE ((KVMFR_MAX_DAMAGE_RECTS + MAX_OVERLAY_RECTS + 2) * MAX_BUFFER_AGE)
@@ -77,15 +75,11 @@ struct Inst
EGL_Desktop * desktop; // the desktop
EGL_Cursor * cursor; // the mouse cursor
EGL_Splash * splash; // the splash screen
EGL_Damage * damage; // the damage display
bool imgui; // if imgui was initialized
LG_RendererFormat format;
bool formatValid;
bool start;
uint64_t waitFadeTime;
bool waitDone;
int width, height;
float uiScale;
@@ -284,7 +278,6 @@ static void egl_deinitialize(LG_Renderer * renderer)
egl_desktopFree(&this->desktop);
egl_cursorFree (&this->cursor);
egl_splashFree (&this->splash);
egl_damageFree (&this->damage);
LG_LOCK_FREE(this->lock);
@@ -323,7 +316,6 @@ static void egl_onRestart(LG_Renderer * renderer)
eglDestroyContext(this->display, this->frameContext);
this->frameContext = NULL;
this->start = false;
INTERLOCKED_SECTION(this->desktopDamageLock, {
this->desktopDamage[this->desktopDamageIdx].count = -1;
@@ -592,8 +584,6 @@ static bool egl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, int d
}
ringbuffer_push(this->importTimings, &(float){ (nanotime() - start) * 1e-6f });
this->start = true;
INTERLOCKED_SECTION(this->desktopDamageLock, {
struct DesktopDamage * damage = this->desktopDamage + this->desktopDamageIdx;
if (damage->count == -1 || damageRectsCount == 0 ||
@@ -928,12 +918,6 @@ static bool egl_renderStartup(LG_Renderer * renderer, bool useDMA)
return false;
}
if (!egl_splashInit(&this->splash))
{
DEBUG_ERROR("Failed to initialize the splash screen");
return false;
}
if (!egl_damageInit(&this->damage))
{
DEBUG_ERROR("Failed to initialize the damage display");
@@ -954,8 +938,8 @@ static bool egl_renderStartup(LG_Renderer * renderer, bool useDMA)
static bool egl_needsRender(LG_Renderer * renderer)
{
struct Inst * this = UPCAST(struct Inst, renderer);
return !this->waitDone;
//struct Inst * this = UPCAST(struct Inst, renderer);
return false;
}
inline static EGLint egl_bufferAge(struct Inst * this)
@@ -1012,7 +996,7 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
{
struct Inst * this = UPCAST(struct Inst, renderer);
EGLint bufferAge = egl_bufferAge(this);
bool renderAll = invalidateWindow || !this->start || this->hadOverlay ||
bool renderAll = invalidateWindow || this->hadOverlay ||
bufferAge <= 0 || bufferAge > MAX_BUFFER_AGE ||
this->showSpice;
@@ -1089,7 +1073,7 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
}
++this->overlayHistoryIdx;
if (this->start && this->destRect.w > 0 && this->destRect.h > 0)
if (this->destRect.w > 0 && this->destRect.h > 0)
{
if (egl_desktopRender(this->desktop,
this->destRect.w, this->destRect.h,
@@ -1097,14 +1081,6 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
this->scaleX , this->scaleY ,
this->scaleType , rotate, renderAll ? NULL : accumulated))
{
if (!this->waitFadeTime)
{
if (!this->params.quickSplash)
this->waitFadeTime = microtime() + SPLASH_FADE_TIME;
else
this->waitDone = true;
}
if (!this->showSpice)
cursorState = egl_cursorRender(this->cursor,
(this->format.rotate + rotate) % LG_ROTATE_MAX,
@@ -1116,35 +1092,6 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
renderLetterBox(this);
if (!this->waitDone)
{
float a = 1.0f;
if (!this->waitFadeTime)
a = 1.0f;
else
{
uint64_t t = microtime();
if (t > this->waitFadeTime)
this->waitDone = true;
else
{
uint64_t delta = this->waitFadeTime - t;
a = 1.0f / SPLASH_FADE_TIME * delta;
}
}
if (!this->waitDone)
{
egl_splashRender(this->splash, a, this->splashRatio);
hasOverlay = true;
}
}
else if (!this->start)
{
egl_splashRender(this->splash, 1.0f, this->splashRatio);
hasOverlay = true;
}
hasOverlay |= egl_damageRender(this->damage, rotate, newFrame ? desktopDamage : NULL);
hasOverlay |= invalidateWindow;
@@ -1271,8 +1218,6 @@ static void egl_spiceShow(LG_Renderer * renderer, bool show)
struct Inst * this = UPCAST(struct Inst, renderer);
this->showSpice = show;
egl_desktopSpiceShow(this->desktop, show);
if (show)
this->start = true;
}
struct LG_RendererOps LGR_EGL =

View File

@@ -1,178 +0,0 @@
/**
* Looking Glass
* Copyright © 2017-2022 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 "splash.h"
#include "common/debug.h"
#include "draw.h"
#include "texture.h"
#include "shader.h"
#include "model.h"
#include <GLES3/gl3.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
// these headers are auto generated by cmake
#include "splash_bg.vert.h"
#include "splash_bg.frag.h"
#include "splash_logo.vert.h"
#include "splash_logo.frag.h"
struct EGL_Splash
{
EGL_Shader * bgShader;
EGL_Model * bg;
EGL_Shader * logoShader;
EGL_Model * logo;
// uniforms
GLint uScale;
};
bool egl_splashInit(EGL_Splash ** splash)
{
*splash = malloc(sizeof(**splash));
if (!*splash)
{
DEBUG_ERROR("Failed to malloc EGL_Splash");
return false;
}
memset(*splash, 0, sizeof(**splash));
if (!egl_shaderInit(&(*splash)->bgShader))
{
DEBUG_ERROR("Failed to initialize the splash bgShader");
return false;
}
if (!egl_shaderCompile((*splash)->bgShader,
b_shader_splash_bg_vert, b_shader_splash_bg_vert_size,
b_shader_splash_bg_frag, b_shader_splash_bg_frag_size))
{
DEBUG_ERROR("Failed to compile the splash bgShader");
return false;
}
if (!egl_modelInit(&(*splash)->bg))
{
DEBUG_ERROR("Failed to intiailize the splash bg model");
return false;
}
egl_modelSetDefault((*splash)->bg, false);
if (!egl_shaderInit(&(*splash)->logoShader))
{
DEBUG_ERROR("Failed to initialize the splash logoShader");
return false;
}
if (!egl_shaderCompile((*splash)->logoShader,
b_shader_splash_logo_vert, b_shader_splash_logo_vert_size,
b_shader_splash_logo_frag, b_shader_splash_logo_frag_size))
{
DEBUG_ERROR("Failed to compile the splash logoShader");
return false;
}
(*splash)->uScale = egl_shaderGetUniform((*splash)->logoShader, "scale");
if (!egl_modelInit(&(*splash)->logo))
{
DEBUG_ERROR("Failed to intiailize the splash model");
return false;
}
/* build the splash model */
#define P(x) ((1.0f/800.0f)*(float)(x))
egl_drawTorusArc((*splash)->logo, 30, P( 0 ), P(0), P(102), P(98), 0.0f, -M_PI);
egl_drawTorus ((*splash)->logo, 30, P(-100), P(8), P(8 ), P(4 ));
egl_drawTorus ((*splash)->logo, 30, P( 100), P(8), P(8 ), P(4 ));
egl_drawTorus ((*splash)->logo, 60, P(0), P(0), P(83), P(79));
egl_drawTorus ((*splash)->logo, 60, P(0), P(0), P(67), P(63));
static const GLfloat lines[][12] =
{
{
P( -2), P(-140), 0.0f,
P( -2), P(-100), 0.0f,
P( 2), P(-140), 0.0f,
P( 2), P(-100), 0.0f
},
{
P(-26), P(-144), 0.0f,
P(-26), P(-140), 0.0f,
P( 26), P(-144), 0.0f,
P( 26), P(-140), 0.0f
},
{
P(-40), P(-156), 0.0f,
P(-40), P(-152), 0.0f,
P( 40), P(-156), 0.0f,
P( 40), P(-152), 0.0f
}
};
egl_modelAddVerts((*splash)->logo, lines[0], NULL, 4);
egl_modelAddVerts((*splash)->logo, lines[1], NULL, 4);
egl_modelAddVerts((*splash)->logo, lines[2], NULL, 4);
egl_drawTorusArc((*splash)->logo, 10, P(-26), P(-154), P(10), P(14), M_PI , -M_PI / 2.0);
egl_drawTorusArc((*splash)->logo, 10, P( 26), P(-154), P(10), P(14), M_PI / 2.0f, -M_PI / 2.0);
#undef P
return true;
}
void egl_splashFree(EGL_Splash ** splash)
{
if (!*splash)
return;
egl_modelFree(&(*splash)->bg );
egl_modelFree(&(*splash)->logo);
egl_shaderFree(&(*splash)->bgShader );
egl_shaderFree(&(*splash)->logoShader);
free(*splash);
*splash = NULL;
}
void egl_splashRender(EGL_Splash * splash, float alpha, float scaleY)
{
glEnable(GL_BLEND);
glBlendColor(0, 0, 0, alpha);
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
egl_shaderUse(splash->bgShader);
egl_modelRender(splash->bg);
egl_shaderUse(splash->logoShader);
glUniform1f(splash->uScale, scaleY);
egl_modelRender(splash->logo);
glDisable(GL_BLEND);
}

View File

@@ -1,30 +0,0 @@
/**
* Looking Glass
* Copyright © 2017-2022 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
*/
#pragma once
#include <stdbool.h>
typedef struct EGL_Splash EGL_Splash;
bool egl_splashInit(EGL_Splash ** splash);
void egl_splashFree(EGL_Splash ** splash);
void egl_splashRender(EGL_Splash * splash, float alpha, float scaleY);

View File

@@ -45,8 +45,6 @@
#define SPICE_TEXTURE 2
#define TEXTURE_COUNT 3
#define FADE_TIME 1000000
static struct Option opengl_options[] =
{
{
@@ -147,11 +145,6 @@ struct Inst
GLsync fences[BUFFER_COUNT];
GLuint textures[TEXTURE_COUNT];
bool start;
bool waiting;
uint64_t waitFadeTime;
bool waitDone;
LG_Lock mouseLock;
LG_RendererCursor mouseCursor;
int mouseWidth;
@@ -182,7 +175,6 @@ static enum ConfigStatus configure(struct Inst * this);
static void updateMouseShape(struct Inst * this);
static bool drawFrame(struct Inst * this);
static void drawMouse(struct Inst * this);
static void renderWait(struct Inst * this);
const char * opengl_getName(void)
{
@@ -222,10 +214,7 @@ bool opengl_create(LG_Renderer ** renderer, const LG_RendererParams params,
bool opengl_initialize(LG_Renderer * renderer)
{
struct Inst * this = UPCAST(struct Inst, renderer);
this->waiting = true;
this->waitDone = false;
// struct Inst * this = UPCAST(struct Inst, renderer);
return true;
}
@@ -268,10 +257,7 @@ void opengl_deinitialize(LG_Renderer * renderer)
void opengl_onRestart(LG_Renderer * renderer)
{
struct Inst * this = UPCAST(struct Inst, renderer);
this->waiting = true;
this->start = false;
// struct Inst * this = UPCAST(struct Inst, renderer);
}
static void setupModelView(struct Inst * this)
@@ -401,7 +387,6 @@ bool opengl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, int dmaFd
atomic_store_explicit(&this->frameUpdate, true, memory_order_release);
LG_UNLOCK(this->frameLock);
this->start = true;
return true;
}
@@ -490,8 +475,8 @@ bool opengl_renderStartup(LG_Renderer * renderer, bool useDMA)
static bool opengl_needsRender(LG_Renderer * renderer)
{
struct Inst * this = UPCAST(struct Inst, renderer);
return !this->waitDone;
// struct Inst * this = UPCAST(struct Inst, renderer);
return false;
}
bool opengl_render(LG_Renderer * renderer, LG_RendererRotate rotate, const bool newFrame,
@@ -501,18 +486,6 @@ bool opengl_render(LG_Renderer * renderer, LG_RendererRotate rotate, const bool
setupModelView(this);
if (this->start && this->waiting)
{
this->waiting = false;
if (!this->params.quickSplash)
this->waitFadeTime = microtime() + FADE_TIME;
else
{
glDisable(GL_MULTISAMPLE);
this->waitDone = true;
}
}
switch(configure(this))
{
case CONFIG_STATUS_ERROR:
@@ -528,21 +501,13 @@ bool opengl_render(LG_Renderer * renderer, LG_RendererRotate rotate, const bool
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (this->waiting)
renderWait(this);
if (this->spiceShow)
glCallList(this->spiceList);
else
{
if (this->spiceShow)
glCallList(this->spiceList);
else
{
updateMouseShape(this);
glCallList(this->texList + this->texRIndex);
drawMouse(this);
}
if (!this->waitDone)
renderWait(this);
updateMouseShape(this);
glCallList(this->texList + this->texRIndex);
drawMouse(this);
}
if (app_renderOverlay(NULL, 0) != 0)
@@ -564,105 +529,6 @@ bool opengl_render(LG_Renderer * renderer, LG_RendererRotate rotate, const bool
return true;
}
static void drawTorus(float x, float y, float inner, float outer,
unsigned int pts)
{
glBegin(GL_QUAD_STRIP);
for (unsigned int i = 0; i <= pts; ++i)
{
float angle = (i / (float)pts) * M_PI * 2.0f;
glVertex2f(x + (inner * cos(angle)), y + (inner * sin(angle)));
glVertex2f(x + (outer * cos(angle)), y + (outer * sin(angle)));
}
glEnd();
}
static void drawTorusArc(float x, float y, float inner, float outer,
unsigned int pts, float s, float e)
{
glBegin(GL_QUAD_STRIP);
for (unsigned int i = 0; i <= pts; ++i)
{
float angle = s + ((i / (float)pts) * e);
glVertex2f(x + (inner * cos(angle)), y + (inner * sin(angle)));
glVertex2f(x + (outer * cos(angle)), y + (outer * sin(angle)));
}
glEnd();
}
static void renderWait(struct Inst * this)
{
float a;
if (this->waiting)
a = 1.0f;
else
{
if (this->waitDone)
return;
uint64_t t = microtime();
if (t > this->waitFadeTime)
{
glDisable(GL_MULTISAMPLE);
this->waitDone = true;
return;
}
uint64_t delta = this->waitFadeTime - t;
a = 1.0f / FADE_TIME * delta;
}
glEnable(GL_BLEND);
glPushMatrix();
glLoadIdentity();
glTranslatef(this->window.x / 2.0f, this->window.y / 2.0f, 0.0f);
//draw the background gradient
glBegin(GL_TRIANGLE_FAN);
glColor4f(0.234375f, 0.015625f, 0.425781f, a);
glVertex2f(0, 0);
glColor4f(0, 0, 0, a);
for (unsigned int i = 0; i <= 100; ++i)
{
float angle = (i / (float)100) * M_PI * 2.0f;
glVertex2f(cos(angle) * this->window.x, sin(angle) * this->window.y);
}
glEnd();
// draw the logo
glColor4f(1.0f, 1.0f, 1.0f, a);
glScalef (2.0f, 2.0f, 1.0f);
drawTorus ( 0, 0, 40, 42, 60);
drawTorus ( 0, 0, 32, 34, 60);
drawTorus (-50, -3, 2, 4, 30);
drawTorus ( 50, -3, 2, 4, 30);
drawTorusArc( 0, 0, 51, 49, 60, 0.0f, M_PI);
glBegin(GL_QUADS);
glVertex2f(-1 , 50);
glVertex2f(-1 , 76);
glVertex2f( 1 , 76);
glVertex2f( 1 , 50);
glVertex2f(-14, 76);
glVertex2f(-14, 78);
glVertex2f( 14, 78);
glVertex2f( 14, 76);
glVertex2f(-21, 83);
glVertex2f(-21, 85);
glVertex2f( 21, 85);
glVertex2f( 21, 83);
glEnd();
drawTorusArc(-14, 83, 5, 7, 10, M_PI , M_PI / 2.0f);
drawTorusArc( 14, 83, 5, 7, 10, M_PI * 1.5f, M_PI / 2.0f);
//FIXME: draw the diagonal marks on the circle
glPopMatrix();
glDisable(GL_BLEND);
}
static void * opengl_createTexture(LG_Renderer * renderer,
int width, int height, uint8_t * data)
{
@@ -811,8 +677,6 @@ static void opengl_spiceShow(LG_Renderer * renderer, bool show)
{
struct Inst * this = UPCAST(struct Inst, renderer);
this->spiceShow = show;
if (show)
this->start = true;
}
const LG_RendererOps LGR_OpenGL =