#include #include #include #include #include #include namespace aethera::web::media::detail { namespace { std::shared_ptr solid_frame( std::uint64_t sequence, std::uint32_t width, std::uint32_t height, std::byte value) { auto pixels = std::make_shared>( static_cast(width) * height * 4U); for (std::size_t offset = 0; offset < pixels->size(); offset += 4U) { (*pixels)[offset] = value; (*pixels)[offset + 3U] = std::byte{255}; } return std::make_shared(Plot_Pixel_Frame{ std::move(pixels), Plot_Pixel_Layout::rgba8, {}, sequence, sequence, sequence, sequence, width, height}); } std::shared_ptr completion_frame( std::uint64_t sequence, std::uint64_t rendered_sequence, std::uint32_t width, std::uint32_t height) { return std::make_shared(Plot_Pixel_Frame{ {}, Plot_Pixel_Layout::rgba8, {}, sequence, sequence, rendered_sequence, rendered_sequence, width, height}); } } TEST(Gallery_Frame_Atlas, Composes_Stable_Layout_And_Retains_Static_Image) { Gallery_Frame_Atlas atlas(2, 2, 2, {"alpha", "beta", "gamma"}); const auto description = atlas.describe(); ASSERT_EQ(description.columns, 2U); ASSERT_EQ(description.rows, 2U); ASSERT_EQ(description.width, 4U); ASSERT_EQ(description.height, 4U); ASSERT_EQ(atlas.accept_frame( 0, solid_frame(1, 2, 2, std::byte{17})), Gallery_Frame_Atlas::Accept_Frame_Result::accepted); const auto first = atlas.compose(); EXPECT_EQ(first.fresh_tile_count, 1U); EXPECT_EQ(first.pixels[0], std::byte{17}); const auto repeated = atlas.compose(); EXPECT_EQ(repeated.fresh_tile_count, 0U); EXPECT_EQ(repeated.pixels[0], std::byte{17}); } TEST(Gallery_Frame_Atlas, Completion_Progress_Does_Not_Replace_The_Authoritative_Pixels) { Gallery_Frame_Atlas atlas(2, 2, 1, {"alpha"}); ASSERT_EQ(atlas.accept_frame( 0, solid_frame(1, 2, 2, std::byte{23})), Gallery_Frame_Atlas::Accept_Frame_Result::accepted); static_cast(atlas.compose()); ASSERT_EQ(atlas.accept_frame( 0, completion_frame(2, 1, 2, 2)), Gallery_Frame_Atlas::Accept_Frame_Result::accepted); const auto composition = atlas.compose(); ASSERT_EQ(composition.sources.size(), 1U); EXPECT_EQ(composition.fresh_tile_count, 0U); EXPECT_EQ(composition.missing_tile_count, 0U); EXPECT_EQ(composition.pixels[0], std::byte{23}); EXPECT_EQ(composition.sources[0].completion_sequence, 2U); EXPECT_EQ(composition.sources[0].rendered_sequence, 1U); EXPECT_EQ(composition.sources[0].completion_count, 2U); EXPECT_EQ(composition.sources[0].rendered_frame_count, 1U); } TEST(Gallery_Frame_Atlas, Applies_Out_Of_Order_Completions_In_Arrival_Order) { Gallery_Frame_Atlas atlas(2, 2, 1, {"alpha"}); ASSERT_EQ(atlas.accept_frame( 0, solid_frame(2, 2, 2, std::byte{31})), Gallery_Frame_Atlas::Accept_Frame_Result::accepted); static_cast(atlas.compose()); ASSERT_EQ(atlas.accept_frame( 0, solid_frame(1, 2, 2, std::byte{47})), Gallery_Frame_Atlas::Accept_Frame_Result::accepted); const auto composition = atlas.compose(); ASSERT_EQ(composition.sources.size(), 1U); EXPECT_EQ(composition.rejected_frame_count, 0U); EXPECT_EQ(composition.sources[0].completion_sequence, 1U); EXPECT_EQ(composition.sources[0].completion_count, 2U); EXPECT_EQ(composition.pixels[0], std::byte{47}); } }