Skip to content

Commit 0b9e086

Browse files
committed
Significantly expand backend tests.
1 parent 695c3f3 commit 0b9e086

6 files changed

Lines changed: 2864 additions & 5 deletions

File tree

demo/demo.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,48 @@ static void clear_backend_test_surfaces()
850850
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
851851
}
852852

853+
static void backend_test_reset_surfaces()
854+
{
855+
clear_backend_test_surfaces();
856+
glFinish();
857+
}
858+
859+
static bool backend_test_write_surface( const char* name, int x, int y, int w, int h, const uint8_t* pixels )
860+
{
861+
if ( !name || !pixels || x < 0 || y < 0 || w <= 0 || h <= 0 ) {
862+
return false;
863+
}
864+
865+
GLuint texture = 0;
866+
int texture_width = 0;
867+
int texture_height = 0;
868+
if ( std::strcmp( name, "glyph_buffer" ) == 0 ) {
869+
texture = fontcache_fbo_texture[ 0 ];
870+
texture_width = VE_FONTCACHE_GLYPHDRAW_BUFFER_WIDTH;
871+
texture_height = VE_FONTCACHE_GLYPHDRAW_BUFFER_HEIGHT;
872+
} else if ( std::strcmp( name, "atlas" ) == 0 ) {
873+
texture = fontcache_fbo_texture[ 1 ];
874+
texture_width = VE_FONTCACHE_ATLAS_WIDTH;
875+
texture_height = VE_FONTCACHE_ATLAS_HEIGHT;
876+
} else {
877+
return false;
878+
}
879+
880+
if ( x + w > texture_width || y + h > texture_height ) {
881+
return false;
882+
}
883+
884+
GLint previous_texture = 0;
885+
glGetIntegerv( GL_TEXTURE_BINDING_2D, &previous_texture );
886+
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
887+
glBindTexture( GL_TEXTURE_2D, texture );
888+
glTexSubImage2D( GL_TEXTURE_2D, 0, x, y, w, h, GL_RED, GL_UNSIGNED_BYTE, pixels );
889+
glBindTexture( GL_TEXTURE_2D, static_cast< GLuint >( previous_texture ) );
890+
glFinish();
891+
check_error( __LINE__ );
892+
return true;
893+
}
894+
853895
static bool backend_test_readback( const char* name, int x, int y, int w, int h, uint8_t* out_pixels )
854896
{
855897
GLint previous_read_framebuffer = 0;
@@ -933,6 +975,8 @@ static int run_backend_test_mode()
933975
options.huge_font = huge_test_font;
934976
options.execute = backend_test_execute;
935977
options.readback = backend_test_readback;
978+
options.reset_surfaces = backend_test_reset_surfaces;
979+
options.write_surface = backend_test_write_surface;
936980
options.reload_font = [ &reload_buffers ]() -> ve_font_id {
937981
reload_buffers.emplace_back();
938982
return load_demo_font( &cache, "fonts/NotoSansJP-Light.otf", reload_buffers.back(), 19.0f );

demo/demo_dx11.cpp

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -560,12 +560,12 @@ DX_CHECK( g_context->Map( staging, 0, D3D11_MAP_READ, 0, &mapped ) );
560560
if ( source_desc.Format == DXGI_FORMAT_R8_UNORM ) {
561561
for ( int row = 0; row < h; row++ ) {
562562
const uint8_t* src = static_cast< const uint8_t* >( mapped.pData ) + row * mapped.RowPitch;
563-
std::memcpy( out_pixels + row * w, src, static_cast< size_t >( w ) );
563+
std::memcpy( out_pixels + static_cast< size_t >( h - 1 - row ) * w, src, static_cast< size_t >( w ) );
564564
}
565565
} else if ( source_desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM ) {
566566
for ( int row = 0; row < h; row++ ) {
567567
const uint8_t* src = static_cast< const uint8_t* >( mapped.pData ) + row * mapped.RowPitch;
568-
uint8_t* dst = out_pixels + row * w;
568+
uint8_t* dst = out_pixels + static_cast< size_t >( h - 1 - row ) * w;
569569
for ( int col = 0; col < w; col++ ) {
570570
dst[ col ] = src[ col * 4 ];
571571
}
@@ -606,7 +606,7 @@ static void dx11_update_texture_region_from_greyscale( ID3D11Texture2D* texture,
606606
std::vector< uint8_t > rgba_pixels( static_cast< size_t >( w ) * static_cast< size_t >( h ) * 4 );
607607
for ( int row = 0; row < h; row++ ) {
608608
for ( int col = 0; col < w; col++ ) {
609-
const uint8_t value = pixels[ static_cast< size_t >( row ) * w + col ];
609+
const uint8_t value = pixels[ static_cast< size_t >( h - 1 - row ) * w + col ];
610610
const size_t dst_index = ( static_cast< size_t >( row ) * w + col ) * 4;
611611
rgba_pixels[ dst_index + 0 ] = value;
612612
rgba_pixels[ dst_index + 1 ] = value;
@@ -1509,6 +1509,53 @@ clear_framebuffer_colour( g_backbuffer_rtv );
15091509
g_context->Flush();
15101510
}
15111511

1512+
static void backend_test_reset_surfaces()
1513+
{
1514+
clear_backend_test_surfaces();
1515+
g_context->Flush();
1516+
}
1517+
1518+
static bool backend_test_write_surface( const char* name, int x, int y, int w, int h, const uint8_t* pixels )
1519+
{
1520+
if ( !name || !pixels || x < 0 || y < 0 || w <= 0 || h <= 0 ) {
1521+
return false;
1522+
}
1523+
1524+
if ( std::strcmp( name, "glyph_buffer" ) == 0 ) {
1525+
if ( x + w > VE_FONTCACHE_GLYPHDRAW_BUFFER_WIDTH || y + h > VE_FONTCACHE_GLYPHDRAW_BUFFER_HEIGHT ) {
1526+
return false;
1527+
}
1528+
dx11_update_texture_region_from_greyscale(
1529+
g_glyph_buffer.texture,
1530+
VE_FONTCACHE_GLYPHDRAW_BUFFER_HEIGHT,
1531+
x,
1532+
y,
1533+
w,
1534+
h,
1535+
pixels );
1536+
g_context->Flush();
1537+
return true;
1538+
}
1539+
1540+
if ( std::strcmp( name, "atlas" ) == 0 ) {
1541+
if ( x + w > VE_FONTCACHE_ATLAS_WIDTH || y + h > VE_FONTCACHE_ATLAS_HEIGHT ) {
1542+
return false;
1543+
}
1544+
dx11_update_texture_region_from_greyscale(
1545+
g_atlas.texture,
1546+
VE_FONTCACHE_ATLAS_HEIGHT,
1547+
x,
1548+
y,
1549+
w,
1550+
h,
1551+
pixels );
1552+
g_context->Flush();
1553+
return true;
1554+
}
1555+
1556+
return false;
1557+
}
1558+
15121559
static bool backend_test_readback( const char* name, int x, int y, int w, int h, uint8_t* out_pixels )
15131560
{
15141561
if ( std::strcmp( name, "glyph_buffer" ) == 0 ) {
@@ -1578,6 +1625,8 @@ options.cjk_font = cjk_test_font;
15781625
options.huge_font = huge_test_font;
15791626
options.execute = backend_test_execute;
15801627
options.readback = backend_test_readback;
1628+
options.reset_surfaces = backend_test_reset_surfaces;
1629+
options.write_surface = backend_test_write_surface;
15811630
options.reload_font = [ &reload_buffers ]() -> ve_font_id {
15821631
reload_buffers.emplace_back();
15831632
return load_demo_font( &cache, "fonts/NotoSansJP-Light.otf", reload_buffers.back(), 19.0f );

tests/test_backend_diagnostics.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include "test_common.h"
2+
3+
UTEST( backend_diagnostics, bbox_profiles_and_centroid )
4+
{
5+
std::vector< uint8_t > pixels = ve_fontcache_backend_test_make_image( 8, 8, 0 );
6+
ve_fontcache_backend_test_fill_rect( pixels, 8, 8, 2, 1, 3, 4, 20 );
7+
8+
ve_fontcache_backend_test_bbox bbox = ve_fontcache_backend_test_thresholded_bbox( pixels, 8, 8, 1 );
9+
std::vector< uint32_t > rows = ve_fontcache_backend_test_row_sum_profile( pixels, 8, 8 );
10+
std::vector< uint32_t > cols = ve_fontcache_backend_test_column_sum_profile( pixels, 8, 8 );
11+
ve_fontcache_backend_test_center_of_mass center = ve_fontcache_backend_test_center_of_mass_grayscale( pixels, 8, 8 );
12+
13+
EXPECT_TRUE( bbox.valid );
14+
EXPECT_EQ( 2, bbox.x );
15+
EXPECT_EQ( 1, bbox.y );
16+
EXPECT_EQ( 3, bbox.w );
17+
EXPECT_EQ( 4, bbox.h );
18+
EXPECT_EQ( 12, bbox.area );
19+
EXPECT_EQ( 60u, rows[ 1 ] );
20+
EXPECT_EQ( 60u, rows[ 4 ] );
21+
EXPECT_EQ( 80u, cols[ 2 ] );
22+
EXPECT_EQ( 80u, cols[ 4 ] );
23+
EXPECT_TRUE( std::fabs( center.x - 3.5 ) <= 0.01 );
24+
EXPECT_TRUE( std::fabs( center.y - 3.0 ) <= 0.01 );
25+
}
26+
27+
UTEST( backend_diagnostics, components_and_border_leakage )
28+
{
29+
std::vector< uint8_t > pixels = ve_fontcache_backend_test_make_image( 6, 6, 0 );
30+
ve_fontcache_backend_test_fill_rect( pixels, 6, 6, 1, 1, 2, 2, 255 );
31+
ve_fontcache_backend_test_fill_rect( pixels, 6, 6, 0, 5, 1, 1, 255 );
32+
33+
EXPECT_EQ( 2, ve_fontcache_backend_test_connected_component_count( pixels, 6, 6, 1 ) );
34+
EXPECT_EQ( 1, ve_fontcache_backend_test_border_leakage_count( pixels, 6, 6, 1, 1 ) );
35+
EXPECT_EQ( 1, ve_fontcache_backend_test_outside_rect_count( pixels, 6, 6, { 1, 1, 2, 2 }, 1 ) );
36+
}
37+
38+
UTEST( backend_diagnostics, diff_stats_and_peak_location )
39+
{
40+
std::vector< uint8_t > expected = ve_fontcache_backend_test_make_image( 4, 4, 0 );
41+
std::vector< uint8_t > actual = expected;
42+
actual[ 1 ] = 20;
43+
actual[ 14 ] = 120;
44+
45+
ve_fontcache_backend_test_diff_stats diff = ve_fontcache_backend_test_expected_vs_actual_diff( expected, actual, 4, 4 );
46+
47+
EXPECT_EQ( 140ull, diff.total_abs_error );
48+
EXPECT_TRUE( std::fabs( diff.mean_abs_error - 8.75 ) <= 0.01 );
49+
EXPECT_EQ( 120, diff.max_abs_error );
50+
EXPECT_EQ( 2, diff.peak_x );
51+
EXPECT_EQ( 3, diff.peak_y );
52+
EXPECT_EQ( 2, diff.differing_pixels );
53+
}
54+
55+
UTEST( backend_diagnostics, mirror_scores_detect_flips )
56+
{
57+
std::vector< uint8_t > expected = ve_fontcache_backend_test_make_image( 6, 6, 0 );
58+
ve_fontcache_backend_test_fill_l_shape( expected, 6, 6, 1, 1, 4, 4, 2, 255 );
59+
60+
std::vector< uint8_t > vertical = ve_fontcache_backend_test_flip_vertical( expected, 6, 6 );
61+
std::vector< uint8_t > horizontal = ve_fontcache_backend_test_flip_horizontal( expected, 6, 6 );
62+
63+
ve_fontcache_backend_test_mirror_scores vertical_scores =
64+
ve_fontcache_backend_test_mirror_scores_for_expected( expected, vertical, 6, 6 );
65+
ve_fontcache_backend_test_mirror_scores horizontal_scores =
66+
ve_fontcache_backend_test_mirror_scores_for_expected( expected, horizontal, 6, 6 );
67+
68+
EXPECT_TRUE( ve_fontcache_backend_test_is_vertical_flip( vertical_scores ) );
69+
EXPECT_FALSE( ve_fontcache_backend_test_is_horizontal_flip( vertical_scores ) );
70+
EXPECT_TRUE( ve_fontcache_backend_test_is_horizontal_flip( horizontal_scores ) );
71+
EXPECT_FALSE( ve_fontcache_backend_test_is_vertical_flip( horizontal_scores ) );
72+
}
73+
74+
UTEST( backend_diagnostics, classifier_helpers_flag_scale_aspect_and_source_binding )
75+
{
76+
ve_fontcache_backend_test_bbox expected_bbox { true, 10, 20, 40, 40, 1600 };
77+
ve_fontcache_backend_test_bbox uniform_scaled { true, 12, 22, 48, 48, 2304 };
78+
ve_fontcache_backend_test_bbox aspect_scaled { true, 12, 22, 56, 40, 2240 };
79+
80+
EXPECT_TRUE( ve_fontcache_backend_test_is_uniform_scale_error( expected_bbox, uniform_scaled ) );
81+
EXPECT_FALSE( ve_fontcache_backend_test_is_aspect_ratio_deformation( expected_bbox, uniform_scaled ) );
82+
EXPECT_TRUE( ve_fontcache_backend_test_is_aspect_ratio_deformation( expected_bbox, aspect_scaled ) );
83+
84+
std::vector< uint8_t > pattern = ve_fontcache_backend_test_make_image( 4, 4, 0 );
85+
ve_fontcache_backend_test_fill_rect( pattern, 4, 4, 0, 0, 2, 4, 255 );
86+
std::vector< uint8_t > zero = ve_fontcache_backend_test_make_image( 4, 4, 0 );
87+
88+
ve_fontcache_backend_test_diff_stats expected_diff =
89+
ve_fontcache_backend_test_expected_vs_actual_diff( pattern, zero, 4, 4 );
90+
ve_fontcache_backend_test_diff_stats alternate_diff =
91+
ve_fontcache_backend_test_expected_vs_actual_diff( zero, zero, 4, 4 );
92+
93+
EXPECT_TRUE( ve_fontcache_backend_test_is_wrong_source_texture_bound( expected_diff, alternate_diff ) );
94+
}

tests/test_main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "test_font_load.cpp"
3333
#include "test_drawlist.cpp"
3434
#include "test_backend.cpp"
35+
#include "test_backend_diagnostics.cpp"
3536
#include "test_shape_cache.cpp"
3637
#include "test_utf8.cpp"
3738
#include "test_stress.cpp"

tests/test_shape_cache_eviction.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ UTEST( shape_cache_eviction, cursor_pos_correct_after_eviction )
6767
float second_cursor_x = ctx.cache.cursor_pos.x;
6868

6969
// The cursor positions should match (same layout reproduced)
70-
EXPECT_NEAR( first_cursor_x, second_cursor_x, 0.1f );
70+
EXPECT_TRUE( std::fabs( first_cursor_x - second_cursor_x ) <= 0.1f );
7171
}
7272

7373
UTEST( shape_cache_eviction, next_cache_idx_wraps )
@@ -103,4 +103,4 @@ UTEST( shape_cache_eviction, next_cache_idx_wraps )
103103

104104
// Verify final state is still within bounds
105105
EXPECT_LE( ctx.cache.shape_cache.state.cache.size(), static_cast< size_t >( VE_FONTCACHE_SHAPECACHE_SIZE ) );
106-
}
106+
}

0 commit comments

Comments
 (0)