mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 15:11:31 +00:00
[client] tests: cover render source queue
This commit is contained in:
@@ -144,6 +144,40 @@ foreach(name IN LISTS MOUSE_CASES)
|
||||
)
|
||||
endforeach()
|
||||
|
||||
add_executable(render-queue-tests
|
||||
render_queue_test.c
|
||||
../src/render_queue.c
|
||||
)
|
||||
target_compile_definitions(render-queue-tests PRIVATE
|
||||
CIMGUI_DEFINE_ENUMS_AND_STRUCTS=1
|
||||
)
|
||||
target_include_directories(render-queue-tests PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src"
|
||||
"${PROJECT_TOP}/repos/gui/cimgui"
|
||||
"${PROJECT_TOP}/repos/gui/cimgui/imgui"
|
||||
)
|
||||
target_link_libraries(render-queue-tests
|
||||
${EXE_FLAGS}
|
||||
lg_common
|
||||
)
|
||||
set(RENDER_QUEUE_CASES
|
||||
generation
|
||||
latest
|
||||
prepare
|
||||
presented
|
||||
payload
|
||||
validation
|
||||
cache
|
||||
)
|
||||
foreach(name IN LISTS RENDER_QUEUE_CASES)
|
||||
add_test(NAME render-queue-${name}
|
||||
COMMAND render-queue-tests ${name}
|
||||
)
|
||||
set_tests_properties(render-queue-${name} PROPERTIES
|
||||
TIMEOUT 10
|
||||
)
|
||||
endforeach()
|
||||
|
||||
find_package(GTest REQUIRED)
|
||||
find_program(WESTON_EXECUTABLE NAMES weston)
|
||||
if(NOT WESTON_EXECUTABLE)
|
||||
|
||||
647
client/tests/render_queue_test.c
Normal file
647
client/tests/render_queue_test.c
Normal file
@@ -0,0 +1,647 @@
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "render_queue.h"
|
||||
#include "test.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
struct AppState g_state;
|
||||
|
||||
struct Fake
|
||||
{
|
||||
LG_Renderer renderer;
|
||||
struct LG_DisplayServerOps ds;
|
||||
|
||||
bool prepResult;
|
||||
unsigned int prepCount;
|
||||
RenderQueueSource prepSource;
|
||||
uint64_t prepGeneration;
|
||||
uint64_t prepSerial;
|
||||
|
||||
unsigned int appliedCount;
|
||||
RenderQueueSource appliedSource;
|
||||
uint64_t appliedGeneration;
|
||||
uint64_t appliedSerial;
|
||||
bool appliedSwSurface;
|
||||
|
||||
unsigned int invalidates;
|
||||
unsigned int showCount;
|
||||
bool show;
|
||||
unsigned int configCount;
|
||||
int configWidth;
|
||||
int configHeight;
|
||||
unsigned int fillCount;
|
||||
int fillX;
|
||||
int fillY;
|
||||
int fillWidth;
|
||||
int fillHeight;
|
||||
uint32_t fillColor;
|
||||
unsigned int bitmapCount;
|
||||
int bitmapX;
|
||||
int bitmapY;
|
||||
int bitmapWidth;
|
||||
int bitmapHeight;
|
||||
int bitmapStride;
|
||||
bool bitmapTopDown;
|
||||
uint8_t bitmap[64];
|
||||
size_t bitmapSize;
|
||||
|
||||
unsigned int shapeCount;
|
||||
LG_RendererCursor shapeType;
|
||||
int shapeWidth;
|
||||
int shapeHeight;
|
||||
int shapePitch;
|
||||
uint8_t shape[64];
|
||||
size_t shapeSize;
|
||||
unsigned int cursorCount;
|
||||
bool cursorVisible;
|
||||
int cursorX;
|
||||
int cursorY;
|
||||
int cursorHX;
|
||||
int cursorHY;
|
||||
unsigned int colorCount;
|
||||
LGColorTransformFlags colorFlags;
|
||||
float colorScalar;
|
||||
float colorMatrix;
|
||||
float colorLut;
|
||||
unsigned int whiteCount;
|
||||
uint32_t whiteLevel;
|
||||
|
||||
unsigned int hdrCount;
|
||||
LG_RendererFormat hdr[8];
|
||||
};
|
||||
|
||||
static struct Fake f;
|
||||
|
||||
void app_invalidateWindow(bool full)
|
||||
{
|
||||
(void)full;
|
||||
++f.invalidates;
|
||||
}
|
||||
|
||||
static bool prep(void * opaque, RenderQueueSource source,
|
||||
uint64_t generation, uint64_t serial)
|
||||
{
|
||||
struct Fake * fake = opaque;
|
||||
fake->prepCount++;
|
||||
fake->prepSource = source;
|
||||
fake->prepGeneration = generation;
|
||||
fake->prepSerial = serial;
|
||||
return fake->prepResult;
|
||||
}
|
||||
|
||||
static void applied(void * opaque, RenderQueueSource source,
|
||||
uint64_t generation, uint64_t serial, bool swSurface)
|
||||
{
|
||||
struct Fake * fake = opaque;
|
||||
fake->appliedCount++;
|
||||
fake->appliedSource = source;
|
||||
fake->appliedGeneration = generation;
|
||||
fake->appliedSerial = serial;
|
||||
fake->appliedSwSurface = swSurface;
|
||||
}
|
||||
|
||||
static void swShow(LG_Renderer * renderer, bool show)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.showCount;
|
||||
f.show = show;
|
||||
}
|
||||
|
||||
static void swConfig(LG_Renderer * renderer, int width, int height)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.configCount;
|
||||
f.configWidth = width;
|
||||
f.configHeight = height;
|
||||
}
|
||||
|
||||
static void swFill(LG_Renderer * renderer, int x, int y,
|
||||
int width, int height, uint32_t color)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.fillCount;
|
||||
f.fillX = x;
|
||||
f.fillY = y;
|
||||
f.fillWidth = width;
|
||||
f.fillHeight = height;
|
||||
f.fillColor = color;
|
||||
}
|
||||
|
||||
static void swBitmap(LG_Renderer * renderer, int x, int y,
|
||||
int width, int height, int stride, uint8_t * data, bool topDown)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.bitmapCount;
|
||||
f.bitmapX = x;
|
||||
f.bitmapY = y;
|
||||
f.bitmapWidth = width;
|
||||
f.bitmapHeight = height;
|
||||
f.bitmapStride = stride;
|
||||
f.bitmapTopDown = topDown;
|
||||
f.bitmapSize = (size_t)height * (size_t)stride;
|
||||
CHECK(f.bitmapSize <= sizeof(f.bitmap));
|
||||
memcpy(f.bitmap, data, f.bitmapSize);
|
||||
}
|
||||
|
||||
static bool mouseShape(LG_Renderer * renderer, LG_RendererCursor type,
|
||||
int width, int height, int pitch, const uint8_t * data)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.shapeCount;
|
||||
f.shapeType = type;
|
||||
f.shapeWidth = width;
|
||||
f.shapeHeight = height;
|
||||
f.shapePitch = pitch;
|
||||
f.shapeSize = (size_t)height * (size_t)pitch;
|
||||
CHECK(f.shapeSize <= sizeof(f.shape));
|
||||
memcpy(f.shape, data, f.shapeSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mouseEvent(LG_Renderer * renderer, bool visible,
|
||||
int x, int y, int hx, int hy)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.cursorCount;
|
||||
f.cursorVisible = visible;
|
||||
f.cursorX = x;
|
||||
f.cursorY = y;
|
||||
f.cursorHX = hx;
|
||||
f.cursorHY = hy;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void mouseColor(LG_Renderer * renderer,
|
||||
const LGColorTransform * color)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.colorCount;
|
||||
f.colorFlags = color->flags;
|
||||
f.colorScalar = color->scalar;
|
||||
f.colorMatrix = color->matrix[0][0];
|
||||
f.colorLut = color->lut[0][0];
|
||||
}
|
||||
|
||||
static void mouseWhite(LG_Renderer * renderer, uint32_t level)
|
||||
{
|
||||
(void)renderer;
|
||||
++f.whiteCount;
|
||||
f.whiteLevel = level;
|
||||
}
|
||||
|
||||
static bool setHDR(const void * data)
|
||||
{
|
||||
CHECK(f.hdrCount < ARRAY_LENGTH(f.hdr));
|
||||
f.hdr[f.hdrCount++] = *(const LG_RendererFormat *)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void start(void)
|
||||
{
|
||||
memset(&f, 0, sizeof(f));
|
||||
memset(&g_state, 0, sizeof(g_state));
|
||||
|
||||
f.prepResult = true;
|
||||
f.renderer.ops.onMouseShape = mouseShape;
|
||||
f.renderer.ops.onMouseEvent = mouseEvent;
|
||||
f.renderer.ops.onMouseColorTransform = mouseColor;
|
||||
f.renderer.ops.onMouseWhiteLevel = mouseWhite;
|
||||
f.renderer.ops.swSurfaceConfigure = swConfig;
|
||||
f.renderer.ops.swSurfaceDrawFill = swFill;
|
||||
f.renderer.ops.swSurfaceDrawBitmap = swBitmap;
|
||||
f.renderer.ops.swSurfaceShow = swShow;
|
||||
f.ds.setHDRImageDesc = setHDR;
|
||||
g_state.lgr = &f.renderer;
|
||||
g_state.ds = &f.ds;
|
||||
|
||||
renderQueue_init();
|
||||
renderQueue_setSourceFns(prep, applied, &f);
|
||||
}
|
||||
|
||||
static void stop(void)
|
||||
{
|
||||
renderQueue_setSourceFns(NULL, NULL, NULL);
|
||||
renderQueue_free();
|
||||
}
|
||||
|
||||
static void testGeneration(void)
|
||||
{
|
||||
start();
|
||||
|
||||
const uint64_t generation =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
CHECK(generation != 0);
|
||||
|
||||
renderQueue_sourceSwSurfaceDrawFill(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, 1, 2, 3, 4, 5);
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, true, NULL) != 0);
|
||||
renderQueue_sourceInvalidate(RENDER_QUEUE_SOURCE_PRIMARY, generation);
|
||||
renderQueue_process();
|
||||
renderQueue_presented();
|
||||
|
||||
CHECK(f.fillCount == 0);
|
||||
CHECK(f.prepCount == 0);
|
||||
CHECK(f.appliedCount == 0);
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, false, NULL) == 0);
|
||||
|
||||
const uint64_t current =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
CHECK(current != 0);
|
||||
CHECK(current != generation);
|
||||
renderQueue_sourceInvalidate(RENDER_QUEUE_SOURCE_PRIMARY, generation);
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
current, false, NULL) != 0);
|
||||
renderQueue_process();
|
||||
CHECK(f.prepCount == 1);
|
||||
CHECK(f.prepGeneration == current);
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
static void testLatest(void)
|
||||
{
|
||||
start();
|
||||
|
||||
const uint64_t primary =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
const uint64_t fallback =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_FALLBACK);
|
||||
atomic_uint_least64_t published;
|
||||
atomic_init(&published, 0);
|
||||
|
||||
const uint64_t old = renderQueue_sourceTransition(
|
||||
RENDER_QUEUE_SOURCE_PRIMARY, primary, false, &published);
|
||||
CHECK(old != 0);
|
||||
CHECK(atomic_load(&published) == old);
|
||||
const uint64_t latest = renderQueue_sourceTransition(
|
||||
RENDER_QUEUE_SOURCE_FALLBACK, fallback, true, &published);
|
||||
CHECK(latest > old);
|
||||
CHECK(atomic_load(&published) == latest);
|
||||
|
||||
renderQueue_process();
|
||||
CHECK(f.prepCount == 1);
|
||||
CHECK(f.prepSource == RENDER_QUEUE_SOURCE_FALLBACK);
|
||||
CHECK(f.prepGeneration == fallback);
|
||||
CHECK(f.prepSerial == latest);
|
||||
CHECK(f.showCount == 1);
|
||||
CHECK(f.show);
|
||||
|
||||
renderQueue_presented();
|
||||
CHECK(f.appliedCount == 1);
|
||||
CHECK(f.appliedSource == RENDER_QUEUE_SOURCE_FALLBACK);
|
||||
CHECK(f.appliedGeneration == fallback);
|
||||
CHECK(f.appliedSerial == latest);
|
||||
CHECK(f.appliedSwSurface);
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
static void testPrepare(void)
|
||||
{
|
||||
start();
|
||||
|
||||
const uint64_t generation =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
f.prepResult = false;
|
||||
CHECK(renderQueue_sourceSwSurfaceConfigureTransition(
|
||||
RENDER_QUEUE_SOURCE_PRIMARY, generation, 640, 480, NULL) != 0);
|
||||
renderQueue_process();
|
||||
renderQueue_presented();
|
||||
|
||||
CHECK(f.prepCount == 1);
|
||||
CHECK(f.configCount == 0);
|
||||
CHECK(f.fillCount == 0);
|
||||
CHECK(f.showCount == 0);
|
||||
CHECK(f.appliedCount == 0);
|
||||
|
||||
f.prepResult = true;
|
||||
const uint64_t serial = renderQueue_sourceSwSurfaceConfigureTransition(
|
||||
RENDER_QUEUE_SOURCE_PRIMARY, generation, 320, 200, NULL);
|
||||
CHECK(serial != 0);
|
||||
renderQueue_process();
|
||||
CHECK(f.configCount == 1);
|
||||
CHECK(f.configWidth == 320);
|
||||
CHECK(f.configHeight == 200);
|
||||
CHECK(f.fillCount == 1);
|
||||
CHECK(f.fillX == 0);
|
||||
CHECK(f.fillY == 0);
|
||||
CHECK(f.fillWidth == 320);
|
||||
CHECK(f.fillHeight == 200);
|
||||
CHECK(f.fillColor == 0);
|
||||
CHECK(f.showCount == 1);
|
||||
CHECK(f.show);
|
||||
|
||||
renderQueue_presented();
|
||||
CHECK(f.appliedCount == 1);
|
||||
CHECK(f.appliedSerial == serial);
|
||||
CHECK(f.appliedSwSurface);
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
static void testPresented(void)
|
||||
{
|
||||
start();
|
||||
|
||||
const uint64_t primary =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
const uint64_t fallback =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_FALLBACK);
|
||||
const uint64_t first = renderQueue_sourceTransition(
|
||||
RENDER_QUEUE_SOURCE_PRIMARY, primary, false, NULL);
|
||||
CHECK(first != 0);
|
||||
renderQueue_process();
|
||||
CHECK(f.appliedCount == 0);
|
||||
|
||||
const uint64_t latest = renderQueue_sourceTransition(
|
||||
RENDER_QUEUE_SOURCE_FALLBACK, fallback, false, NULL);
|
||||
CHECK(latest > first);
|
||||
renderQueue_process();
|
||||
CHECK(f.appliedCount == 0);
|
||||
|
||||
renderQueue_presented();
|
||||
CHECK(f.appliedCount == 1);
|
||||
CHECK(f.appliedSource == RENDER_QUEUE_SOURCE_FALLBACK);
|
||||
CHECK(f.appliedGeneration == fallback);
|
||||
CHECK(f.appliedSerial == latest);
|
||||
renderQueue_presented();
|
||||
CHECK(f.appliedCount == 1);
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
static void testPayload(void)
|
||||
{
|
||||
start();
|
||||
|
||||
const uint64_t generation =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
uint8_t bitmap[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
const uint8_t bitmapExpected[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
uint8_t shape[] = { 11, 12, 13, 14, 15, 16, 17, 18 };
|
||||
const uint8_t shapeExpected[] = { 11, 12, 13, 14, 15, 16, 17, 18 };
|
||||
LGColorTransform color =
|
||||
{
|
||||
.flags = LG_COLOR_TRANSFORM_MATRIX | LG_COLOR_TRANSFORM_LUT,
|
||||
.matrix[0][0] = 2.0f,
|
||||
.scalar = 3.0f,
|
||||
.lut[0][0] = 4.0f,
|
||||
};
|
||||
|
||||
renderQueue_sourceSwSurfaceDrawBitmap(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, 5, 6, 2, 2, 4, bitmap, true);
|
||||
renderQueue_sourceCursorImage(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
LG_CURSOR_COLOR, 2, 2, 4, shape);
|
||||
renderQueue_sourceCursorColorTransform(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, &color);
|
||||
renderQueue_sourceCursorState(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
true, 20, 21, 1, 2);
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, false, NULL) != 0);
|
||||
|
||||
memset(bitmap, 0, sizeof(bitmap));
|
||||
memset(shape, 0, sizeof(shape));
|
||||
color.flags = 0;
|
||||
color.matrix[0][0] = 0.0f;
|
||||
color.scalar = 0.0f;
|
||||
color.lut[0][0] = 0.0f;
|
||||
renderQueue_process();
|
||||
|
||||
CHECK(f.bitmapCount == 1);
|
||||
CHECK(f.bitmapX == 5);
|
||||
CHECK(f.bitmapY == 6);
|
||||
CHECK(f.bitmapWidth == 2);
|
||||
CHECK(f.bitmapHeight == 2);
|
||||
CHECK(f.bitmapStride == 4);
|
||||
CHECK(f.bitmapTopDown);
|
||||
CHECK(f.bitmapSize == sizeof(bitmapExpected));
|
||||
CHECK(memcmp(f.bitmap, bitmapExpected, sizeof(bitmapExpected)) == 0);
|
||||
CHECK(f.shapeCount == 1);
|
||||
CHECK(f.shapeType == LG_CURSOR_COLOR);
|
||||
CHECK(f.shapeWidth == 2);
|
||||
CHECK(f.shapeHeight == 2);
|
||||
CHECK(f.shapePitch == 4);
|
||||
CHECK(f.shapeSize == sizeof(shapeExpected));
|
||||
CHECK(memcmp(f.shape, shapeExpected, sizeof(shapeExpected)) == 0);
|
||||
CHECK(f.colorCount == 1);
|
||||
CHECK(f.colorFlags ==
|
||||
(LG_COLOR_TRANSFORM_MATRIX | LG_COLOR_TRANSFORM_LUT));
|
||||
CHECK(f.colorMatrix == 2.0f);
|
||||
CHECK(f.colorScalar == 3.0f);
|
||||
CHECK(f.colorLut == 4.0f);
|
||||
CHECK(f.cursorCount == 1);
|
||||
CHECK(f.cursorVisible);
|
||||
CHECK(f.cursorX == 20);
|
||||
CHECK(f.cursorY == 21);
|
||||
CHECK(f.cursorHX == 1);
|
||||
CHECK(f.cursorHY == 2);
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
static void testValidation(void)
|
||||
{
|
||||
start();
|
||||
|
||||
const uint64_t generation =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
uint8_t data[16] = { 0 };
|
||||
|
||||
renderQueue_sourceSwSurfaceDrawBitmap(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, 0, 0, 0, 1, 4, data, false);
|
||||
renderQueue_sourceSwSurfaceDrawBitmap(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, 0, 0, 1, 0, 4, data, false);
|
||||
renderQueue_sourceSwSurfaceDrawBitmap(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, 0, 0, 1, 1, 0, data, false);
|
||||
renderQueue_sourceSwSurfaceDrawBitmap(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, 0, 0, 1, 1, 4, NULL, false);
|
||||
renderQueue_sourceCursorImage(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
LG_CURSOR_COLOR, 0, 1, 4, data);
|
||||
renderQueue_sourceCursorImage(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
LG_CURSOR_COLOR, 1, 0, 4, data);
|
||||
renderQueue_sourceCursorImage(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
LG_CURSOR_COLOR, 1, 1, 0, data);
|
||||
renderQueue_sourceCursorImage(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
LG_CURSOR_COLOR, 1, 1, 4, NULL);
|
||||
renderQueue_sourceCursorState(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
true, 1, 2, 3, 4);
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, false, NULL) != 0);
|
||||
renderQueue_process();
|
||||
|
||||
CHECK(f.bitmapCount == 0);
|
||||
CHECK(f.shapeCount == 0);
|
||||
CHECK(f.cursorCount == 1);
|
||||
CHECK(!f.cursorVisible);
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
static void testCache(void)
|
||||
{
|
||||
start();
|
||||
|
||||
const uint64_t generation =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
const uint8_t shape[] = { 1, 2, 3, 4 };
|
||||
LGColorTransform color =
|
||||
{
|
||||
.flags = LG_COLOR_TRANSFORM_MATRIX,
|
||||
.matrix[0][0] = 1.5f,
|
||||
.scalar = 2.5f,
|
||||
};
|
||||
LG_RendererFormat format =
|
||||
{
|
||||
.type = FRAME_TYPE_RGBA,
|
||||
.hdr = true,
|
||||
.hdrPQ = true,
|
||||
.hdrMetadata = true,
|
||||
.screenWidth = 1920,
|
||||
.screenHeight = 1080,
|
||||
.sdrWhiteLevel = 250,
|
||||
};
|
||||
|
||||
renderQueue_sourceCursorImage(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
LG_CURSOR_COLOR, 1, 1, 4, shape);
|
||||
renderQueue_sourceCursorState(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
true, 30, 31, 2, 3);
|
||||
renderQueue_sourceCursorColorTransform(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, &color);
|
||||
renderQueue_sourceCursorWhiteLevel(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, 250);
|
||||
renderQueue_sourceSurfaceFormat(RENDER_QUEUE_SOURCE_PRIMARY, generation,
|
||||
format, true);
|
||||
renderQueue_process();
|
||||
CHECK(f.shapeCount == 0);
|
||||
CHECK(f.cursorCount == 0);
|
||||
CHECK(f.colorCount == 0);
|
||||
CHECK(f.whiteCount == 0);
|
||||
CHECK(f.hdrCount == 0);
|
||||
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
generation, false, NULL) != 0);
|
||||
renderQueue_process();
|
||||
CHECK(f.shapeCount == 1);
|
||||
CHECK(f.cursorCount == 1);
|
||||
CHECK(f.cursorVisible);
|
||||
CHECK(f.colorCount == 1);
|
||||
CHECK(f.colorScalar == 2.5f);
|
||||
CHECK(f.whiteCount == 1);
|
||||
CHECK(f.whiteLevel == 250);
|
||||
CHECK(f.hdrCount == 1);
|
||||
CHECK(f.hdr[0].type == FRAME_TYPE_RGBA);
|
||||
CHECK(f.hdr[0].hdr);
|
||||
CHECK(f.hdr[0].hdrPQ);
|
||||
CHECK(f.hdr[0].screenWidth == 1920);
|
||||
|
||||
renderQueue_sourceInvalidate(RENDER_QUEUE_SOURCE_PRIMARY, generation);
|
||||
const uint64_t current =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
CHECK(current != generation);
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
current, false, NULL) != 0);
|
||||
renderQueue_process();
|
||||
CHECK(f.shapeCount == 2);
|
||||
CHECK(f.cursorCount == 2);
|
||||
CHECK(f.cursorVisible);
|
||||
CHECK(f.cursorX == 30);
|
||||
CHECK(f.cursorY == 31);
|
||||
CHECK(f.cursorHX == 2);
|
||||
CHECK(f.cursorHY == 3);
|
||||
CHECK(f.colorCount == 2);
|
||||
CHECK(f.colorScalar == 2.5f);
|
||||
CHECK(f.whiteCount == 2);
|
||||
CHECK(f.whiteLevel == 250);
|
||||
CHECK(f.hdrCount == 2);
|
||||
CHECK(f.hdr[1].type == 0);
|
||||
CHECK(!f.hdr[1].hdr);
|
||||
|
||||
renderQueue_sourceClearCursor(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
const uint64_t clear =
|
||||
renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY);
|
||||
CHECK(renderQueue_sourceTransition(RENDER_QUEUE_SOURCE_PRIMARY,
|
||||
clear, false, NULL) != 0);
|
||||
renderQueue_process();
|
||||
CHECK(f.shapeCount == 2);
|
||||
CHECK(f.cursorCount == 3);
|
||||
CHECK(!f.cursorVisible);
|
||||
CHECK(f.colorCount == 3);
|
||||
CHECK(f.colorFlags == 0);
|
||||
CHECK(f.colorScalar == 0.0f);
|
||||
CHECK(f.whiteCount == 3);
|
||||
CHECK(f.whiteLevel == LG_SDR_WHITE_LEVEL_DEFAULT);
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
struct Test
|
||||
{
|
||||
const char * name;
|
||||
void (*run)(void);
|
||||
};
|
||||
|
||||
static const struct Test tests[] =
|
||||
{
|
||||
{ "generation", testGeneration },
|
||||
{ "latest" , testLatest },
|
||||
{ "prepare" , testPrepare },
|
||||
{ "presented" , testPresented },
|
||||
{ "payload" , testPayload },
|
||||
{ "validation", testValidation },
|
||||
{ "cache" , testCache },
|
||||
};
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
debug_init();
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(tests); ++i)
|
||||
if (strcmp(argv[1], tests[i].name) == 0)
|
||||
{
|
||||
tests[i].run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "unknown test: %s\n", argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc != 1)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(tests); ++i)
|
||||
tests[i].run();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user