mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-20 22:32:01 +00:00
[client] egl: correct surface damage reporting
Apply the same sampling margin to swap damage as buffer-age repair and clip reported rectangles to the EGL surface. This ensures compositors update every pixel affected by scaling or filtering.
This commit is contained in:
@@ -51,8 +51,9 @@
|
|||||||
#include "postprocess.h"
|
#include "postprocess.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define MAX_BUFFER_AGE 3
|
#define MAX_BUFFER_AGE 3
|
||||||
#define DESKTOP_DAMAGE_COUNT 4
|
#define DESKTOP_DAMAGE_COUNT 4
|
||||||
|
#define DESKTOP_DAMAGE_MARGIN 1
|
||||||
#define MAX_ACCUMULATED_DAMAGE ((KVMFR_MAX_DAMAGE_RECTS + MAX_OVERLAY_RECTS + 2) * MAX_BUFFER_AGE)
|
#define MAX_ACCUMULATED_DAMAGE ((KVMFR_MAX_DAMAGE_RECTS + MAX_OVERLAY_RECTS + 2) * MAX_BUFFER_AGE)
|
||||||
#define IDX_AGO(counter, i, total) (((counter) + (total) - (i)) % (total))
|
#define IDX_AGO(counter, i, total) (((counter) + (total) - (i)) % (total))
|
||||||
|
|
||||||
@@ -1094,6 +1095,52 @@ inline static EGLint egl_bufferAge(struct Inst * this)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FrameDamageRect egl_expandDesktopDamage(
|
||||||
|
const struct Inst * this, const FrameDamageRect * rect)
|
||||||
|
{
|
||||||
|
const uint32_t x = rect->x > DESKTOP_DAMAGE_MARGIN ?
|
||||||
|
rect->x - DESKTOP_DAMAGE_MARGIN : 0;
|
||||||
|
const uint32_t y = rect->y > DESKTOP_DAMAGE_MARGIN ?
|
||||||
|
rect->y - DESKTOP_DAMAGE_MARGIN : 0;
|
||||||
|
const uint32_t right = (uint32_t)min((uint64_t)this->format.frameWidth,
|
||||||
|
(uint64_t)rect->x + rect->width + DESKTOP_DAMAGE_MARGIN);
|
||||||
|
const uint32_t bottom = (uint32_t)min((uint64_t)this->format.frameHeight,
|
||||||
|
(uint64_t)rect->y + rect->height + DESKTOP_DAMAGE_MARGIN);
|
||||||
|
|
||||||
|
return (FrameDamageRect) {
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = right > x ? right - x : 0,
|
||||||
|
.height = bottom > y ? bottom - y : 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static int egl_clipSurfaceDamage(
|
||||||
|
struct Rect * damage, int count, int width, int height)
|
||||||
|
{
|
||||||
|
int out = 0;
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
const int64_t x2 = (int64_t)damage[i].x + damage[i].w;
|
||||||
|
const int64_t y2 = (int64_t)damage[i].y + damage[i].h;
|
||||||
|
const int x1 = clamp(damage[i].x, 0, width);
|
||||||
|
const int y1 = clamp(damage[i].y, 0, height);
|
||||||
|
const int right = (int)clamp(x2, 0, width);
|
||||||
|
const int bottom = (int)clamp(y2, 0, height);
|
||||||
|
if (right <= x1 || bottom <= y1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
damage[out++] = (struct Rect) {
|
||||||
|
.x = x1,
|
||||||
|
.y = y1,
|
||||||
|
.w = right - x1,
|
||||||
|
.h = bottom - y1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
inline static void renderLetterBox(struct Inst * this)
|
inline static void renderLetterBox(struct Inst * this)
|
||||||
{
|
{
|
||||||
bool hLB = this->destRect.x > 0;
|
bool hLB = this->destRect.x > 0;
|
||||||
@@ -1170,14 +1217,10 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
|
|||||||
|
|
||||||
for (int j = 0; j < damage->count; ++j)
|
for (int j = 0; j < damage->count; ++j)
|
||||||
{
|
{
|
||||||
struct FrameDamageRect * rect = damage->rects + j;
|
const FrameDamageRect rect =
|
||||||
int x = rect->x > 0 ? rect->x - 1 : 0;
|
egl_expandDesktopDamage(this, damage->rects + j);
|
||||||
int y = rect->y > 0 ? rect->y - 1 : 0;
|
if (rect.width && rect.height)
|
||||||
accumulated->rects[accumulated->count++] = (struct FrameDamageRect) {
|
accumulated->rects[accumulated->count++] = rect;
|
||||||
.x = x, .y = y,
|
|
||||||
.width = min(this->format.frameWidth - x, rect->width + 2),
|
|
||||||
.height = min(this->format.frameHeight - y, rect->height + 2),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1297,12 +1340,21 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
|
|||||||
this->width, this->height);
|
this->width, this->height);
|
||||||
|
|
||||||
for (int i = 0; i < desktopDamage->count; ++i)
|
for (int i = 0; i < desktopDamage->count; ++i)
|
||||||
damage[damageIdx++] = egl_desktopToScreen(matrix, desktopDamage->rects + i);
|
{
|
||||||
|
const FrameDamageRect rect =
|
||||||
|
egl_expandDesktopDamage(this, desktopDamage->rects + i);
|
||||||
|
if (rect.width && rect.height)
|
||||||
|
damage[damageIdx++] = egl_desktopToScreen(matrix, &rect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
damageIdx = 0;
|
damageIdx = 0;
|
||||||
|
|
||||||
|
if (damageIdx > 0)
|
||||||
|
damageIdx = egl_clipSurfaceDamage(
|
||||||
|
damage, damageIdx, this->width, this->height);
|
||||||
|
|
||||||
this->hadOverlay = hasOverlay;
|
this->hadOverlay = hasOverlay;
|
||||||
this->cursorLast = cursorState;
|
this->cursorLast = cursorState;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user