mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-01-10 23:07:04 +00:00
[client] egl: only copy damaged areas when using dmabuf
This speeds up the copy significantly when the frame only has small amount of damage.
This commit is contained in:
parent
09893fd728
commit
a14de25661
@ -37,7 +37,7 @@ bool util_guestCurToLocal(struct DoublePoint *local);
|
|||||||
void util_localCurToGuest(struct DoublePoint *guest);
|
void util_localCurToGuest(struct DoublePoint *guest);
|
||||||
void util_rotatePoint(struct DoublePoint *point);
|
void util_rotatePoint(struct DoublePoint *point);
|
||||||
bool util_hasGLExt(const char * exts, const char * ext);
|
bool util_hasGLExt(const char * exts, const char * ext);
|
||||||
int util_mergeOverlappingRects(FrameDamageRect * out, const FrameDamageRect * rects, int count);
|
int util_mergeOverlappingRects(FrameDamageRect * rects, int count);
|
||||||
|
|
||||||
static inline double util_clamp(double x, double min, double max)
|
static inline double util_clamp(double x, double min, double max)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -259,11 +260,16 @@ bool egl_desktop_setup(EGL_Desktop * desktop, const LG_RendererFormat format, bo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd)
|
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd,
|
||||||
|
const FrameDamageRect * origRects, int rectsCount)
|
||||||
{
|
{
|
||||||
|
FrameDamageRect rects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
|
memcpy(rects, origRects, rectsCount * sizeof(FrameDamageRect));
|
||||||
|
rectsCount = util_mergeOverlappingRects(rects, rectsCount);
|
||||||
|
|
||||||
if (dmaFd >= 0)
|
if (dmaFd >= 0)
|
||||||
{
|
{
|
||||||
if (!egl_texture_update_from_dma(desktop->texture, frame, dmaFd))
|
if (!egl_texture_update_from_dma(desktop->texture, frame, dmaFd, rects, rectsCount))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "common/types.h"
|
||||||
#include "interface/renderer.h"
|
#include "interface/renderer.h"
|
||||||
|
|
||||||
typedef struct EGL_Desktop EGL_Desktop;
|
typedef struct EGL_Desktop EGL_Desktop;
|
||||||
@ -40,7 +41,8 @@ bool egl_desktop_init(EGL_Desktop ** desktop, EGLDisplay * display);
|
|||||||
void egl_desktop_free(EGL_Desktop ** desktop);
|
void egl_desktop_free(EGL_Desktop ** desktop);
|
||||||
|
|
||||||
bool egl_desktop_setup (EGL_Desktop * desktop, const LG_RendererFormat format, bool useDMA);
|
bool egl_desktop_setup (EGL_Desktop * desktop, const LG_RendererFormat format, bool useDMA);
|
||||||
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd);
|
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd,
|
||||||
|
const FrameDamageRect * rects, int rectsCount);
|
||||||
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y,
|
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y,
|
||||||
const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType,
|
const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType,
|
||||||
LG_RendererRotate rotate);
|
LG_RendererRotate rotate);
|
||||||
|
@ -583,7 +583,7 @@ bool egl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd,
|
|||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
if (!egl_desktop_update(this->desktop, frame, dmaFd))
|
if (!egl_desktop_update(this->desktop, frame, dmaFd, damageRects, damageRectsCount))
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Failed to to update the desktop");
|
DEBUG_INFO("Failed to to update the desktop");
|
||||||
return false;
|
return false;
|
||||||
|
@ -388,7 +388,8 @@ bool egl_texture_update_from_frame(EGL_Texture * texture, const FrameBuffer * fr
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_texture_update_from_dma(EGL_Texture * texture, const FrameBuffer * frame, const int dmaFd)
|
bool egl_texture_update_from_dma(EGL_Texture * texture, const FrameBuffer * frame, const int dmaFd,
|
||||||
|
const FrameDamageRect * rects, int rectsCount)
|
||||||
{
|
{
|
||||||
if (!texture->streaming)
|
if (!texture->streaming)
|
||||||
return false;
|
return false;
|
||||||
@ -470,7 +471,15 @@ bool egl_texture_update_from_dma(EGL_Texture * texture, const FrameBuffer * fram
|
|||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->dmaTex, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->dmaTex, 0);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->tex[0]);
|
glBindTexture(GL_TEXTURE_2D, texture->tex[0]);
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texture->width, texture->height);
|
|
||||||
|
if (!texture->ready || rectsCount == 0)
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texture->width, texture->height);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < rectsCount; ++i)
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, rects[i].x, rects[i].y, rects[i].x, rects[i].y,
|
||||||
|
rects[i].width, rects[i].height);
|
||||||
|
}
|
||||||
|
|
||||||
GLsync fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
GLsync fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
glFlush();
|
glFlush();
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "common/framebuffer.h"
|
#include "common/framebuffer.h"
|
||||||
|
#include "common/types.h"
|
||||||
|
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
@ -52,7 +53,7 @@ void egl_texture_free(EGL_Texture ** tex);
|
|||||||
bool egl_texture_setup (EGL_Texture * texture, enum EGL_PixelFormat pixfmt, size_t width, size_t height, size_t stride, bool streaming, bool useDMA);
|
bool egl_texture_setup (EGL_Texture * texture, enum EGL_PixelFormat pixfmt, size_t width, size_t height, size_t stride, bool streaming, bool useDMA);
|
||||||
bool egl_texture_update (EGL_Texture * texture, const uint8_t * buffer);
|
bool egl_texture_update (EGL_Texture * texture, const uint8_t * buffer);
|
||||||
bool egl_texture_update_from_frame(EGL_Texture * texture, const FrameBuffer * frame);
|
bool egl_texture_update_from_frame(EGL_Texture * texture, const FrameBuffer * frame);
|
||||||
bool egl_texture_update_from_dma (EGL_Texture * texture, const FrameBuffer * frmame, const int dmaFd);
|
bool egl_texture_update_from_dma (EGL_Texture * texture, const FrameBuffer * frmame, const int dmaFd, const FrameDamageRect * rects, int rectsCount);
|
||||||
enum EGL_TexStatus egl_texture_process(EGL_Texture * texture);
|
enum EGL_TexStatus egl_texture_process(EGL_Texture * texture);
|
||||||
enum EGL_TexStatus egl_texture_bind (EGL_Texture * texture);
|
enum EGL_TexStatus egl_texture_bind (EGL_Texture * texture);
|
||||||
int egl_texture_count (EGL_Texture * texture);
|
int egl_texture_count (EGL_Texture * texture);
|
||||||
|
@ -224,13 +224,12 @@ static bool rectIntersects(const FrameDamageRect * r1, const FrameDamageRect * r
|
|||||||
r2->y + r1->height > r2->y;
|
r2->y + r1->height > r2->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int util_mergeOverlappingRects(FrameDamageRect * out, const FrameDamageRect * rects, int count)
|
int util_mergeOverlappingRects(FrameDamageRect * rects, int count)
|
||||||
{
|
{
|
||||||
bool removed[count];
|
bool removed[count];
|
||||||
bool changed;
|
bool changed;
|
||||||
|
|
||||||
memset(removed, 0, sizeof(removed));
|
memset(removed, 0, sizeof(removed));
|
||||||
memcpy(out, rects, count * sizeof(FrameDamageRect));
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -238,14 +237,14 @@ int util_mergeOverlappingRects(FrameDamageRect * out, const FrameDamageRect * re
|
|||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
if (!removed[i])
|
if (!removed[i])
|
||||||
for (int j = i + 1; j < count; ++j)
|
for (int j = i + 1; j < count; ++j)
|
||||||
if (!removed[j] && rectIntersects(out + i, out + j))
|
if (!removed[j] && rectIntersects(rects + i, rects + j))
|
||||||
{
|
{
|
||||||
uint32_t x2 = max(out[i].x + out[i].width, out[j].x + out[j].width);
|
uint32_t x2 = max(rects[i].x + rects[i].width, rects[j].x + rects[j].width);
|
||||||
uint32_t y2 = max(out[i].y + out[i].height, out[j].y + out[j].height);
|
uint32_t y2 = max(rects[i].y + rects[i].height, rects[j].y + rects[j].height);
|
||||||
out[i].x = min(out[i].x, out[j].x);
|
rects[i].x = min(rects[i].x, rects[j].x);
|
||||||
out[i].y = min(out[i].y, out[j].y);
|
rects[i].y = min(rects[i].y, rects[j].y);
|
||||||
out[i].width = x2 - out[i].x;
|
rects[i].width = x2 - rects[i].x;
|
||||||
out[i].height = y2 - out[i].y;
|
rects[i].height = y2 - rects[i].y;
|
||||||
removed[j] = true;
|
removed[j] = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
@ -255,6 +254,6 @@ int util_mergeOverlappingRects(FrameDamageRect * out, const FrameDamageRect * re
|
|||||||
int o = 0;
|
int o = 0;
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
if (!removed[i])
|
if (!removed[i])
|
||||||
out[o++] = out[i];
|
rects[o++] = rects[i];
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user