mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-04 14:22:02 +00:00
Correlate received frames with the texture update actually consumed by the renderer and retain damage until its token becomes renderable. Split client latency into dispatch, import, queue, preparation, setup, effects, desktop, composition, and swap stages in FRAME LATENCY. Exclude diagnostic overlay work from composition and preserve client wait time when producer timing is unavailable. Publish joined samples through a bounded token queue, avoid sleeping while producer timing is finalized, and correct Wayland photon units.
181 lines
5.1 KiB
C
181 lines
5.1 KiB
C
/**
|
|
* Looking Glass
|
|
* Copyright © 2017-2026 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>
|
|
#include "egl.h"
|
|
#include "egltypes.h"
|
|
#include "shader.h"
|
|
#include "model.h"
|
|
#include "common/framebuffer.h"
|
|
#include "common/types.h"
|
|
#include "interface/renderer.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include <EGL/egl.h>
|
|
#include <EGL/eglext.h>
|
|
|
|
#include "texture_util.h"
|
|
|
|
typedef struct EGL_Model EGL_Model;
|
|
|
|
typedef struct EGL_TexUpdate
|
|
{
|
|
/* the type of this update */
|
|
EGL_TexType type;
|
|
LG_RendererFrameToken frameToken;
|
|
uint64_t * waitTimeNs;
|
|
|
|
int x, y, width, height;
|
|
|
|
//pitch = row length in pixels
|
|
//stride = row length in bytes
|
|
int pitch, stride;
|
|
|
|
union
|
|
{
|
|
/* EGL_TEXTYPE_BUFFER */
|
|
struct
|
|
{
|
|
// true if row 0 is the top of the image
|
|
bool topDown;
|
|
const uint8_t * buffer;
|
|
};
|
|
|
|
/* EGL_TEXTYPE_FRAMEBUFFER */
|
|
struct
|
|
{
|
|
const FrameBuffer * frame;
|
|
const FrameDamageRect * rects;
|
|
int rectCount;
|
|
};
|
|
|
|
/* EGL_TEXTYPE_DMABUF */
|
|
int dmaFD;
|
|
};
|
|
}
|
|
EGL_TexUpdate;
|
|
|
|
typedef struct EGL_Texture EGL_Texture;
|
|
|
|
typedef struct EGL_TextureOps
|
|
{
|
|
/* allocate & initialize an EGL_Texture */
|
|
bool (*init)(EGL_Texture ** texture, EGL_TexType type, EGLDisplay * display);
|
|
|
|
/* free the EGL_Texture */
|
|
void (*free)(EGL_Texture * texture);
|
|
|
|
/* setup/reconfigure the texture format */
|
|
bool (*setup)(EGL_Texture * texture, const EGL_TexSetup * setup);
|
|
|
|
/* update the texture */
|
|
bool (*update)(EGL_Texture * texture, const EGL_TexUpdate * update);
|
|
|
|
/* called from a background job to prepare the texture for use before bind */
|
|
enum EGL_TexStatus (*process)(EGL_Texture * texture,
|
|
LG_RendererFrameToken frameTokenLimit);
|
|
|
|
/* get the texture for use */
|
|
enum EGL_TexStatus (*get)(EGL_Texture * texture, GLuint * tex,
|
|
EGL_PixelFormat * fmt);
|
|
|
|
/* bind the texture for use */
|
|
enum EGL_TexStatus (*bind)(EGL_Texture * texture, GLuint unit);
|
|
}
|
|
EGL_TextureOps;
|
|
|
|
struct EGL_Texture
|
|
{
|
|
struct EGL_TextureOps ops;
|
|
EGL_TexType type;
|
|
GLuint sampler;
|
|
LG_RendererFrameToken frameToken;
|
|
|
|
EGL_TexFormat format;
|
|
};
|
|
|
|
bool egl_textureInit(EGL_Texture ** texture, EGLDisplay * display,
|
|
EGL_TexType type);
|
|
void egl_textureFree(EGL_Texture ** tex);
|
|
|
|
bool egl_textureSetup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt,
|
|
size_t width, size_t height, size_t stride, size_t pitch);
|
|
|
|
bool egl_textureUpdate(EGL_Texture * texture, const uint8_t * buffer,
|
|
bool topDown);
|
|
|
|
bool egl_textureUpdateRect(EGL_Texture * texture,
|
|
int x, int y, int width, int height, int stride, int pitch,
|
|
const uint8_t * buffer, bool topDown);
|
|
|
|
bool egl_textureUpdateFromFrame(EGL_Texture * texture,
|
|
const FrameBuffer * frame, LG_RendererFrameToken frameToken,
|
|
const FrameDamageRect * damageRects, int damageRectsCount,
|
|
uint64_t * waitTimeNs);
|
|
|
|
bool egl_textureUpdateFromDMA(EGL_Texture * texture,
|
|
const FrameBuffer * frame, LG_RendererFrameToken frameToken,
|
|
const int dmaFd, uint64_t * waitTimeNs);
|
|
|
|
enum EGL_TexStatus egl_textureProcess(EGL_Texture * texture,
|
|
LG_RendererFrameToken frameTokenLimit,
|
|
LG_RendererFrameToken * consumedFrameToken);
|
|
|
|
static inline bool egl_textureFrameAllowed(LG_RendererFrameToken frameToken,
|
|
LG_RendererFrameToken frameTokenLimit)
|
|
{
|
|
return frameToken == LG_RENDERER_FRAME_TOKEN_NONE ||
|
|
frameToken <= frameTokenLimit;
|
|
}
|
|
|
|
static inline EGL_TexStatus egl_textureGet(EGL_Texture * texture, GLuint * tex,
|
|
unsigned int * sizeX, unsigned int * sizeY, EGL_PixelFormat * fmt)
|
|
{
|
|
if (sizeX)
|
|
*sizeX = texture->format.width;
|
|
if (sizeY)
|
|
*sizeY = texture->format.height;
|
|
if (fmt)
|
|
*fmt = texture->format.pixFmt;
|
|
return texture->ops.get(texture, tex, fmt);
|
|
}
|
|
|
|
enum EGL_TexStatus egl_textureBind(EGL_Texture * texture);
|
|
enum EGL_TexStatus egl_textureBindWithSampler(EGL_Texture * texture,
|
|
GLuint sampler);
|
|
enum EGL_TexStatus egl_textureBindUnitWithSampler(EGL_Texture * texture,
|
|
GLuint unit, GLuint sampler);
|
|
|
|
typedef void * PostProcessHandle;
|
|
PostProcessHandle egl_textureAddFilter(EGL_Texture * texture,
|
|
EGL_Shader * shader, bool enabled);
|
|
|
|
void egl_textureEnableFilter(PostProcessHandle * handle, bool enable);
|
|
|
|
void egl_textureSetFilterRes(PostProcessHandle * handle,
|
|
unsigned int x, unsigned int y);
|
|
|
|
void egl_textureInvalidate(EGL_Texture * texture);
|
|
|
|
void egl_textureGetFinalSize(EGL_Texture * texture, struct Rect * rect);
|