// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "flutter/common/graphics/texture.h" #include #include "flutter/flow/testing/mock_texture.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace flutter { namespace testing { namespace { using int_closure = std::function; struct TestContextListener : public ContextListener { TestContextListener(uintptr_t p_id, int_closure p_create, int_closure p_destroy) : id(p_id), create(std::move(p_create)), destroy(std::move(p_destroy)) {} virtual ~TestContextListener() = default; const uintptr_t id; int_closure create; int_closure destroy; void OnGrContextCreated() override { create(id); } void OnGrContextDestroyed() override { destroy(id); } }; } // namespace TEST(TextureRegistryTest, UnregisterTextureCallbackTriggered) { TextureRegistry registry; auto mock_texture1 = std::make_shared(0); auto mock_texture2 = std::make_shared(1); registry.RegisterTexture(mock_texture1); registry.RegisterTexture(mock_texture2); ASSERT_EQ(registry.GetTexture(0), mock_texture1); ASSERT_EQ(registry.GetTexture(1), mock_texture2); ASSERT_FALSE(mock_texture1->unregistered()); ASSERT_FALSE(mock_texture2->unregistered()); registry.UnregisterTexture(0); ASSERT_EQ(registry.GetTexture(0), nullptr); ASSERT_TRUE(mock_texture1->unregistered()); ASSERT_FALSE(mock_texture2->unregistered()); registry.UnregisterTexture(1); ASSERT_EQ(registry.GetTexture(1), nullptr); ASSERT_TRUE(mock_texture1->unregistered()); ASSERT_TRUE(mock_texture2->unregistered()); } TEST(TextureRegistryTest, GrContextCallbackTriggered) { TextureRegistry registry; auto mock_texture1 = std::make_shared(0); auto mock_texture2 = std::make_shared(1); registry.RegisterTexture(mock_texture1); registry.RegisterTexture(mock_texture2); ASSERT_FALSE(mock_texture1->gr_context_created()); ASSERT_FALSE(mock_texture2->gr_context_created()); ASSERT_FALSE(mock_texture1->gr_context_destroyed()); ASSERT_FALSE(mock_texture2->gr_context_destroyed()); registry.OnGrContextCreated(); ASSERT_TRUE(mock_texture1->gr_context_created()); ASSERT_TRUE(mock_texture2->gr_context_created()); registry.UnregisterTexture(0); registry.OnGrContextDestroyed(); ASSERT_FALSE(mock_texture1->gr_context_destroyed()); ASSERT_TRUE(mock_texture2->gr_context_created()); } TEST(TextureRegistryTest, RegisterTextureTwice) { TextureRegistry registry; auto mock_texture1 = std::make_shared(0); auto mock_texture2 = std::make_shared(0); registry.RegisterTexture(mock_texture1); ASSERT_EQ(registry.GetTexture(0), mock_texture1); registry.RegisterTexture(mock_texture2); ASSERT_EQ(registry.GetTexture(0), mock_texture2); ASSERT_FALSE(mock_texture1->unregistered()); ASSERT_FALSE(mock_texture2->unregistered()); registry.UnregisterTexture(0); ASSERT_EQ(registry.GetTexture(0), nullptr); ASSERT_FALSE(mock_texture1->unregistered()); ASSERT_TRUE(mock_texture2->unregistered()); } TEST(TextureRegistryTest, ReuseSameTextureSlot) { TextureRegistry registry; auto mock_texture1 = std::make_shared(0); auto mock_texture2 = std::make_shared(0); registry.RegisterTexture(mock_texture1); ASSERT_EQ(registry.GetTexture(0), mock_texture1); registry.UnregisterTexture(0); ASSERT_EQ(registry.GetTexture(0), nullptr); ASSERT_TRUE(mock_texture1->unregistered()); ASSERT_FALSE(mock_texture2->unregistered()); registry.RegisterTexture(mock_texture2); ASSERT_EQ(registry.GetTexture(0), mock_texture2); registry.UnregisterTexture(0); ASSERT_EQ(registry.GetTexture(0), nullptr); ASSERT_TRUE(mock_texture1->unregistered()); ASSERT_TRUE(mock_texture2->unregistered()); } TEST(TextureRegistryTest, CallsOnGrContextCreatedInInsertionOrder) { TextureRegistry registry; std::vector create_order; std::vector destroy_order; auto create = [&](int id) { create_order.push_back(id); }; auto destroy = [&](int id) { destroy_order.push_back(id); }; auto a = std::make_shared(5, create, destroy); auto b = std::make_shared(4, create, destroy); auto c = std::make_shared(3, create, destroy); registry.RegisterContextListener(a->id, a); registry.RegisterContextListener(b->id, b); registry.RegisterContextListener(c->id, c); registry.OnGrContextDestroyed(); registry.OnGrContextCreated(); EXPECT_THAT(create_order, ::testing::ElementsAre(5, 4, 3)); EXPECT_THAT(destroy_order, ::testing::ElementsAre(5, 4, 3)); } } // namespace testing } // namespace flutter