mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-04-29 10:06:28 +00:00
[client] egl: use desktop frame damage information
This commit is contained in:
parent
6b16bb3ea1
commit
442ab318fd
@ -114,7 +114,7 @@ typedef void (* LG_RendererOnResize )(void * opaque, const int width
|
|||||||
typedef bool (* LG_RendererOnMouseShape )(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data);
|
typedef bool (* LG_RendererOnMouseShape )(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data);
|
||||||
typedef bool (* LG_RendererOnMouseEvent )(void * opaque, const bool visible , const int x, const int y);
|
typedef bool (* LG_RendererOnMouseEvent )(void * opaque, const bool visible , const int x, const int y);
|
||||||
typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format, bool useDMA);
|
typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format, bool useDMA);
|
||||||
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame, int dmaFD);
|
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame, int dmaFD, const FrameDamageRect * damage, int damageCount);
|
||||||
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
||||||
typedef void (* LG_RendererOnHelp )(void * opaque, const char * message);
|
typedef void (* LG_RendererOnHelp )(void * opaque, const char * message);
|
||||||
typedef void (* LG_RendererOnShowFPS )(void * opaque, bool showFPS);
|
typedef void (* LG_RendererOnShowFPS )(void * opaque, bool showFPS);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "interface/renderer.h"
|
#include "interface/renderer.h"
|
||||||
|
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
|
#include "common/KVMFR.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
#include "common/sysinfo.h"
|
#include "common/sysinfo.h"
|
||||||
#include "common/time.h"
|
#include "common/time.h"
|
||||||
@ -59,6 +60,12 @@ struct Options
|
|||||||
bool doubleBuffer;
|
bool doubleBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DesktopDamage
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
FrameDamageRect rects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
|
};
|
||||||
|
|
||||||
struct Inst
|
struct Inst
|
||||||
{
|
{
|
||||||
bool dmaSupport;
|
bool dmaSupport;
|
||||||
@ -116,6 +123,8 @@ struct Inst
|
|||||||
|
|
||||||
bool cursorLastValid;
|
bool cursorLastValid;
|
||||||
struct CursorState cursorLast;
|
struct CursorState cursorLast;
|
||||||
|
|
||||||
|
_Atomic(struct DesktopDamage *) desktopDamage;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct Option egl_options[] =
|
static struct Option egl_options[] =
|
||||||
@ -263,6 +272,8 @@ bool egl_create(void ** opaque, const LG_RendererParams params, bool * needsOpen
|
|||||||
this->screenScaleY = 1.0f;
|
this->screenScaleY = 1.0f;
|
||||||
this->uiScale = 1.0;
|
this->uiScale = 1.0;
|
||||||
|
|
||||||
|
atomic_init(&this->desktopDamage, NULL);
|
||||||
|
|
||||||
this->font = LG_Fonts[0];
|
this->font = LG_Fonts[0];
|
||||||
if (!egl_update_font(this))
|
if (!egl_update_font(this))
|
||||||
return false;
|
return false;
|
||||||
@ -486,6 +497,15 @@ void egl_on_resize(void * opaque, const int width, const int height, const doubl
|
|||||||
egl_update_help_font(this);
|
egl_update_help_font(this);
|
||||||
|
|
||||||
this->cursorLastValid = false;
|
this->cursorLastValid = false;
|
||||||
|
|
||||||
|
struct DesktopDamage * damage = malloc(sizeof(struct DesktopDamage));
|
||||||
|
if (!damage)
|
||||||
|
{
|
||||||
|
DEBUG_FATAL("Out of memory");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
damage->count = 0;
|
||||||
|
free(atomic_exchange(&this->desktopDamage, damage));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor,
|
bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor,
|
||||||
@ -548,7 +568,8 @@ bool egl_on_frame_format(void * opaque, const LG_RendererFormat format, bool use
|
|||||||
return egl_desktop_setup(this->desktop, format, useDMA);
|
return egl_desktop_setup(this->desktop, format, useDMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd)
|
bool egl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd,
|
||||||
|
const FrameDamageRect * damageRects, int damageRectsCount)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
@ -560,6 +581,17 @@ bool egl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd)
|
|||||||
|
|
||||||
this->start = true;
|
this->start = true;
|
||||||
this->cursorLastValid = false;
|
this->cursorLastValid = false;
|
||||||
|
|
||||||
|
struct DesktopDamage * damage = malloc(sizeof(struct DesktopDamage));
|
||||||
|
if (!damage)
|
||||||
|
{
|
||||||
|
DEBUG_FATAL("Out of memory");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
damage->count = damageRectsCount;
|
||||||
|
memcpy(damage->rects, damageRects, damageRectsCount * sizeof(FrameDamageRect));
|
||||||
|
free(atomic_exchange(&this->desktopDamage, damage));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,8 +833,12 @@ bool egl_render(void * opaque, LG_RendererRotate rotate)
|
|||||||
bool hasLastCursor = this->cursorLastValid;
|
bool hasLastCursor = this->cursorLastValid;
|
||||||
bool cursorRendered = false;
|
bool cursorRendered = false;
|
||||||
struct CursorState cursorState;
|
struct CursorState cursorState;
|
||||||
|
struct DesktopDamage * desktopDamage = NULL;
|
||||||
|
|
||||||
if (this->start && egl_desktop_render(this->desktop,
|
if (this->start)
|
||||||
|
{
|
||||||
|
desktopDamage = atomic_exchange(&this->desktopDamage, NULL);
|
||||||
|
if (egl_desktop_render(this->desktop,
|
||||||
this->translateX, this->translateY,
|
this->translateX, this->translateY,
|
||||||
this->scaleX , this->scaleY ,
|
this->scaleX , this->scaleY ,
|
||||||
this->scaleType , rotate))
|
this->scaleType , rotate))
|
||||||
@ -820,6 +856,9 @@ bool egl_render(void * opaque, LG_RendererRotate rotate)
|
|||||||
egl_cursor_render(this->cursor,
|
egl_cursor_render(this->cursor,
|
||||||
(this->format.rotate + rotate) % LG_ROTATE_MAX);
|
(this->format.rotate + rotate) % LG_ROTATE_MAX);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
desktopDamage->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->waitDone)
|
if (!this->waitDone)
|
||||||
{
|
{
|
||||||
@ -864,7 +903,7 @@ bool egl_render(void * opaque, LG_RendererRotate rotate)
|
|||||||
egl_alert_render(this->alert, this->screenScaleX, this->screenScaleY);
|
egl_alert_render(this->alert, this->screenScaleX, this->screenScaleY);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Rect damage[2];
|
struct Rect damage[KVMFR_MAX_DAMAGE_RECTS + 2];
|
||||||
int damageIdx = 0;
|
int damageIdx = 0;
|
||||||
|
|
||||||
if (this->waitDone)
|
if (this->waitDone)
|
||||||
@ -883,6 +922,35 @@ bool egl_render(void * opaque, LG_RendererRotate rotate)
|
|||||||
{
|
{
|
||||||
this->cursorLast = cursorState;
|
this->cursorLast = cursorState;
|
||||||
this->cursorLastValid = true;
|
this->cursorLastValid = true;
|
||||||
|
|
||||||
|
if (cursorState.visible)
|
||||||
|
damage[damageIdx++] = cursorState.rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desktopDamage)
|
||||||
|
{
|
||||||
|
if (desktopDamage->count == 0)
|
||||||
|
// Zero damage count means invalidating entire window.
|
||||||
|
damageIdx = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double scaleX = (double) this->destRect.w / this->format.width;
|
||||||
|
double scaleY = (double) this->destRect.h / this->format.height;
|
||||||
|
for (int i = 0; i < desktopDamage->count; ++i)
|
||||||
|
{
|
||||||
|
FrameDamageRect rect = desktopDamage->rects[i];
|
||||||
|
int x1 = (int) (rect.x * scaleX);
|
||||||
|
int y1 = (int) (rect.y * scaleY);
|
||||||
|
int x2 = (int) ceil((rect.x + rect.width) * scaleX);
|
||||||
|
int y2 = (int) ceil((rect.y + rect.height) * scaleY);
|
||||||
|
damage[damageIdx++] = (struct Rect) {
|
||||||
|
.x = this->destRect.x + x1,
|
||||||
|
.y = this->height - (this->destRect.y + y2),
|
||||||
|
.w = x2 - x1,
|
||||||
|
.h = y2 - y1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +419,8 @@ bool opengl_on_frame_format(void * opaque, const LG_RendererFormat format, bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opengl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd)
|
bool opengl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd,
|
||||||
|
const FrameDamageRect * damage, int damageCount)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
|
@ -589,7 +589,8 @@ int main_frameThread(void * unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
|
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
|
||||||
if (!g_state.lgr->on_frame(g_state.lgrData, fb, useDMA ? dma->fd : -1))
|
if (!g_state.lgr->on_frame(g_state.lgrData, fb, useDMA ? dma->fd : -1,
|
||||||
|
frame->damageRects, frame->damageRectsCount))
|
||||||
{
|
{
|
||||||
lgmpClientMessageDone(queue);
|
lgmpClientMessageDone(queue);
|
||||||
DEBUG_ERROR("renderer on frame returned failure");
|
DEBUG_ERROR("renderer on frame returned failure");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user