mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 15:11:31 +00:00
[client] render: optimize software surface fills
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
#include "texture_buffer.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "desktop_rects.h"
|
#include "desktop_rects.h"
|
||||||
#include "cimgui.h"
|
#include "cimgui.h"
|
||||||
@@ -705,25 +706,8 @@ void egl_desktopSwSurfaceDrawFill(EGL_Desktop * desktop,
|
|||||||
height = (bottom > desktop->swSurfaceHeight ?
|
height = (bottom > desktop->swSurfaceHeight ?
|
||||||
desktop->swSurfaceHeight : (int)bottom) - y;
|
desktop->swSurfaceHeight : (int)bottom) - y;
|
||||||
|
|
||||||
/* This is a fairly hacky way to update a software surface, but it preserves
|
if (egl_texBufferStreamFill(
|
||||||
* the existing incremental fill behavior. */
|
desktop->swSurfaceTexture, x, y, width, height, color))
|
||||||
|
|
||||||
uint32_t * line = malloc((size_t)width * sizeof(*line));
|
|
||||||
if (!line)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to allocate software surface fill row");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < width; ++i)
|
|
||||||
line[i] = color;
|
|
||||||
|
|
||||||
for(int dy = 0; dy < height; ++dy)
|
|
||||||
egl_textureUpdateRect(desktop->swSurfaceTexture,
|
|
||||||
x, y + dy, width, 1, width, width * sizeof(*line),
|
|
||||||
(uint8_t *)line, false);
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
atomic_store(&desktop->processFrame, true);
|
atomic_store(&desktop->processFrame, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -390,6 +390,44 @@ static bool egl_texBufferStreamUpdate(EGL_Texture * texture,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool egl_texBufferStreamFill(EGL_Texture * texture,
|
||||||
|
int x, int y, int width, int height, uint32_t color)
|
||||||
|
{
|
||||||
|
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
||||||
|
|
||||||
|
DEBUG_ASSERT(texture->format.bpp == sizeof(color));
|
||||||
|
if (texture->format.bpp != sizeof(color))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!egl_texBufferStreamLock(this))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t * row = this->buf[this->bufIndex].map +
|
||||||
|
texture->format.pitch * y + x * texture->format.bpp;
|
||||||
|
for (int dy = 0; dy < height; ++dy)
|
||||||
|
{
|
||||||
|
uint32_t * dst = (uint32_t *)row;
|
||||||
|
for (int dx = 0; dx < width; ++dx)
|
||||||
|
dst[dx] = color;
|
||||||
|
row += texture->format.pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EGL_TexUpdate update =
|
||||||
|
{
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
};
|
||||||
|
|
||||||
|
this->slotToken[this->bufIndex] = LG_RENDERER_FRAME_TOKEN_NONE;
|
||||||
|
this->buf[this->bufIndex].updated = true;
|
||||||
|
egl_texBufferDamageAdd(this, this->bufIndex, &update);
|
||||||
|
LG_UNLOCK(this->copyLock);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture,
|
EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture,
|
||||||
LG_RendererFrameToken frameTokenLimit)
|
LG_RendererFrameToken frameTokenLimit)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ bool egl_texBufferStreamSetup(EGL_Texture * texture_,
|
|||||||
const EGL_TexSetup * setup);
|
const EGL_TexSetup * setup);
|
||||||
/* Returns with copyLock held when the current upload buffer is safe to write. */
|
/* Returns with copyLock held when the current upload buffer is safe to write. */
|
||||||
bool egl_texBufferStreamLock(TextureBuffer * texture);
|
bool egl_texBufferStreamLock(TextureBuffer * texture);
|
||||||
|
bool egl_texBufferStreamFill(EGL_Texture * texture,
|
||||||
|
int x, int y, int width, int height, uint32_t color);
|
||||||
EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture_,
|
EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture_,
|
||||||
LG_RendererFrameToken frameTokenLimit);
|
LG_RendererFrameToken frameTokenLimit);
|
||||||
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture_, GLuint * tex,
|
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture_, GLuint * tex,
|
||||||
|
|||||||
@@ -721,11 +721,11 @@ static void testSurfaceEvents(void)
|
|||||||
CHECK(f.log.configN == 1);
|
CHECK(f.log.configN == 1);
|
||||||
CHECK(f.log.width == 2);
|
CHECK(f.log.width == 2);
|
||||||
CHECK(f.log.height == 1);
|
CHECK(f.log.height == 1);
|
||||||
CHECK(f.log.fillN == 1);
|
CHECK(f.log.fillN == 0);
|
||||||
|
|
||||||
spiceSurface_drawFill(
|
spiceSurface_drawFill(
|
||||||
f.transport.surface, 0, 1, 2, 3, 4, 0xaabbccdd);
|
f.transport.surface, 0, 1, 2, 3, 4, 0xaabbccdd);
|
||||||
CHECK(f.log.fillN == 2);
|
CHECK(f.log.fillN == 1);
|
||||||
CHECK(f.log.x == 1);
|
CHECK(f.log.x == 1);
|
||||||
CHECK(f.log.y == 2);
|
CHECK(f.log.y == 2);
|
||||||
CHECK(f.log.w == 3);
|
CHECK(f.log.w == 3);
|
||||||
@@ -776,7 +776,7 @@ static void testSurfaceEvents(void)
|
|||||||
spiceSurface_destroy(f.transport.surface, 0);
|
spiceSurface_destroy(f.transport.surface, 0);
|
||||||
CHECK(f.log.destroyN == 1);
|
CHECK(f.log.destroyN == 1);
|
||||||
spiceSurface_drawFill(f.transport.surface, 0, 0, 0, 1, 1, 0);
|
spiceSurface_drawFill(f.transport.surface, 0, 0, 0, 1, 1, 0);
|
||||||
CHECK(f.log.fillN == 2);
|
CHECK(f.log.fillN == 1);
|
||||||
sw->detach(&f.transport);
|
sw->detach(&f.transport);
|
||||||
freeFixture(&f);
|
freeFixture(&f);
|
||||||
}
|
}
|
||||||
@@ -844,9 +844,9 @@ static void testSurfaceDetach(void)
|
|||||||
CHECK(pthread_join(detachThread, NULL) == 0);
|
CHECK(pthread_join(detachThread, NULL) == 0);
|
||||||
CHECK(atomic_load(&detach.done));
|
CHECK(atomic_load(&detach.done));
|
||||||
CHECK(f.log.configN == 1);
|
CHECK(f.log.configN == 1);
|
||||||
CHECK(f.log.fillN == 1);
|
CHECK(f.log.fillN == 0);
|
||||||
spiceSurface_drawFill(f.transport.surface, 0, 0, 0, 1, 1, 0);
|
spiceSurface_drawFill(f.transport.surface, 0, 0, 0, 1, 1, 0);
|
||||||
CHECK(f.log.fillN == 1);
|
CHECK(f.log.fillN == 0);
|
||||||
freeFixture(&f);
|
freeFixture(&f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -199,11 +199,7 @@ void spiceSurface_create(SpiceSurface * surface, unsigned int surfaceId,
|
|||||||
|
|
||||||
LG_LOCK_SHARED(surface->eventsLock);
|
LG_LOCK_SHARED(surface->eventsLock);
|
||||||
if (surface->events)
|
if (surface->events)
|
||||||
{
|
|
||||||
surface->events->configure(surface->eventOpaque, width, height);
|
surface->events->configure(surface->eventOpaque, width, height);
|
||||||
surface->events->drawFill(
|
|
||||||
surface->eventOpaque, 0, 0, width, height, 0);
|
|
||||||
}
|
|
||||||
LG_UNLOCK_SHARED(surface->eventsLock);
|
LG_UNLOCK_SHARED(surface->eventsLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user