diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index ea2fbf946f90e..d6001c839ee4d 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -245,6 +245,8 @@ template("embedder_executable") { "channels/localization_channel_stub.cc", "channels/platform_channel_stub.cc", "channels/settings_channel_stub.cc", + "external_texture_pixel_gl_stub.cc", + "external_texture_surface_gl_stub.cc", "tizen_log_stub.cc", "tizen_renderer_evas_gl.cc", ] @@ -303,6 +305,7 @@ embedder_executable("flutter_tizen_unittests") { sources = [ "flutter_tizen_engine_unittest.cc", + "flutter_tizen_texture_registrar_unittests.cc", "testing/mock_engine.cc", ] diff --git a/shell/platform/tizen/external_texture_pixel_gl.cc b/shell/platform/tizen/external_texture_pixel_gl.cc index 846bdb0737422..085a2f19e408d 100644 --- a/shell/platform/tizen/external_texture_pixel_gl.cc +++ b/shell/platform/tizen/external_texture_pixel_gl.cc @@ -45,6 +45,10 @@ ExternalTexturePixelGL::ExternalTexturePixelGL( user_data_(user_data) {} bool ExternalTexturePixelGL::CopyPixelBuffer(size_t& width, size_t& height) { + if (!texture_callback_) { + return false; + } + const FlutterDesktopPixelBuffer* pixel_buffer = texture_callback_(width, height, user_data_); diff --git a/shell/platform/tizen/external_texture_pixel_gl_stub.cc b/shell/platform/tizen/external_texture_pixel_gl_stub.cc new file mode 100644 index 0000000000000..f6a1ae0a1a5cc --- /dev/null +++ b/shell/platform/tizen/external_texture_pixel_gl_stub.cc @@ -0,0 +1,29 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. 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/shell/platform/tizen/external_texture_pixel_gl.h" + +namespace flutter { + +ExternalTexturePixelGL::ExternalTexturePixelGL( + FlutterDesktopPixelBufferTextureCallback texture_callback, + void* user_data) + : ExternalTexture(), + texture_callback_(texture_callback), + user_data_(user_data) {} + +bool ExternalTexturePixelGL::PopulateTexture( + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + return CopyPixelBuffer(width, height); +} + +bool ExternalTexturePixelGL::CopyPixelBuffer(size_t& width, size_t& height) { + if (texture_callback_ && user_data_) { + return true; + } + return false; +} +} // namespace flutter diff --git a/shell/platform/tizen/external_texture_surface_gl.cc b/shell/platform/tizen/external_texture_surface_gl.cc index cba8bdf277eac..b748c40c66221 100644 --- a/shell/platform/tizen/external_texture_surface_gl.cc +++ b/shell/platform/tizen/external_texture_surface_gl.cc @@ -54,6 +54,9 @@ bool ExternalTextureSurfaceGL::PopulateTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { + if (!texture_callback_) { + return false; + } const FlutterDesktopGpuBuffer* gpu_buffer = texture_callback_(width, height, user_data_); if (!gpu_buffer) { @@ -153,7 +156,9 @@ bool ExternalTextureSurfaceGL::PopulateTexture( } void ExternalTextureSurfaceGL::OnDestruction() { - destruction_callback_(user_data_); + if (destruction_callback_) { + destruction_callback_(user_data_); + } } } // namespace flutter diff --git a/shell/platform/tizen/external_texture_surface_gl_stub.cc b/shell/platform/tizen/external_texture_surface_gl_stub.cc new file mode 100644 index 0000000000000..07f21e8673ae6 --- /dev/null +++ b/shell/platform/tizen/external_texture_surface_gl_stub.cc @@ -0,0 +1,38 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "external_texture_surface_gl.h" + +namespace flutter { + +ExternalTextureSurfaceGL::ExternalTextureSurfaceGL( + FlutterDesktopGpuBufferTextureCallback texture_callback, + FlutterDesktopGpuBufferDestructionCallback destruction_callback, + void* user_data) + : ExternalTexture(), + texture_callback_(texture_callback), + destruction_callback_(destruction_callback), + user_data_(user_data) {} + +ExternalTextureSurfaceGL::~ExternalTextureSurfaceGL() { + state_.release(); +} + +bool ExternalTextureSurfaceGL::PopulateTexture( + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + if (texture_callback_ && destruction_callback_ && user_data_) { + return true; + } + return false; +} + +void ExternalTextureSurfaceGL::OnDestruction() { + if (destruction_callback_) { + destruction_callback_(user_data_); + } +} + +} // namespace flutter diff --git a/shell/platform/tizen/flutter_tizen_engine.h b/shell/platform/tizen/flutter_tizen_engine.h index fad50e4278b65..163f2a99d20f5 100644 --- a/shell/platform/tizen/flutter_tizen_engine.h +++ b/shell/platform/tizen/flutter_tizen_engine.h @@ -142,6 +142,8 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { std::unique_ptr platform_view_channel; private: + friend class EngineModifier; + // Whether the engine is running in headed or headless mode. bool IsHeaded() { return renderer != nullptr; } diff --git a/shell/platform/tizen/flutter_tizen_texture_registrar.cc b/shell/platform/tizen/flutter_tizen_texture_registrar.cc index e84cd4d68a49d..817ff5401f2ae 100644 --- a/shell/platform/tizen/flutter_tizen_texture_registrar.cc +++ b/shell/platform/tizen/flutter_tizen_texture_registrar.cc @@ -7,10 +7,8 @@ #include #include -#ifndef __X64_SHELL__ #include "flutter/shell/platform/tizen/external_texture_pixel_gl.h" #include "flutter/shell/platform/tizen/external_texture_surface_gl.h" -#endif #include "flutter/shell/platform/tizen/flutter_tizen_engine.h" #include "flutter/shell/platform/tizen/tizen_log.h" @@ -90,10 +88,6 @@ bool FlutterTizenTextureRegistrar::PopulateTexture( std::unique_ptr FlutterTizenTextureRegistrar::CreateExternalTexture( const FlutterDesktopTextureInfo* texture_info) { -#ifdef __X64_SHELL__ - FT_UNIMPLEMENTED(); - return nullptr; -#else switch (texture_info->type) { case kFlutterDesktopPixelBufferTexture: return std::make_unique( @@ -110,7 +104,6 @@ FlutterTizenTextureRegistrar::CreateExternalTexture( FT_LOGE("Invalid texture type."); return nullptr; } -#endif } } // namespace flutter diff --git a/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc b/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc new file mode 100644 index 0000000000000..1ec19707c5433 --- /dev/null +++ b/shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc @@ -0,0 +1,126 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h" +#include "flutter/shell/platform/tizen/flutter_tizen_engine.h" +#include "flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h" +#include "flutter/shell/platform/tizen/testing/engine_modifier.h" +#include "gtest/gtest.h" + +namespace flutter { +namespace testing { + +class FlutterTizenTextureRegistrarTest : public ::testing::Test { + public: + FlutterTizenTextureRegistrarTest() { + ecore_init(); + elm_init(0, nullptr); + } + + protected: + void SetUp() { + FlutterDesktopEngineProperties engine_prop = {}; + engine_prop.assets_path = "foo/flutter_assets"; + engine_prop.icu_data_path = "foo/icudtl.dat"; + engine_prop.aot_library_path = "foo/libapp.so"; + + FlutterProjectBundle project(engine_prop); + auto engine = std::make_unique(project); + engine_ = engine.release(); + } + + void TearDown() { + if (engine_) { + delete engine_; + } + engine_ = nullptr; + } + + FlutterTizenEngine* engine_; +}; + +TEST_F(FlutterTizenTextureRegistrarTest, CreateDestroy) { + FlutterTizenTextureRegistrar registrar(engine_); + + EXPECT_TRUE(true); +} + +TEST_F(FlutterTizenTextureRegistrarTest, RegisterUnregisterTexture) { + EngineModifier modifier(engine_); + + FlutterTizenTextureRegistrar registrar(engine_); + + FlutterDesktopTextureInfo texture_info = {}; + texture_info.type = kFlutterDesktopPixelBufferTexture; + texture_info.pixel_buffer_config.callback = + [](size_t width, size_t height, + void* user_data) -> const FlutterDesktopPixelBuffer* { + return nullptr; + }; + + int64_t registered_texture_id = 0; + bool register_called = false; + modifier.embedder_api().RegisterExternalTexture = MOCK_ENGINE_PROC( + RegisterExternalTexture, ([®ister_called, ®istered_texture_id]( + auto engine, auto texture_id) { + register_called = true; + registered_texture_id = texture_id; + return kSuccess; + })); + + bool unregister_called = false; + modifier.embedder_api().UnregisterExternalTexture = MOCK_ENGINE_PROC( + UnregisterExternalTexture, ([&unregister_called, ®istered_texture_id]( + auto engine, auto texture_id) { + unregister_called = true; + EXPECT_EQ(registered_texture_id, texture_id); + return kSuccess; + })); + + bool mark_frame_available_called = false; + modifier.embedder_api().MarkExternalTextureFrameAvailable = + MOCK_ENGINE_PROC(MarkExternalTextureFrameAvailable, + ([&mark_frame_available_called, ®istered_texture_id]( + auto engine, auto texture_id) { + mark_frame_available_called = true; + EXPECT_EQ(registered_texture_id, texture_id); + return kSuccess; + })); + + auto texture_id = registrar.RegisterTexture(&texture_info); + EXPECT_TRUE(register_called); + EXPECT_NE(texture_id, -1); + EXPECT_EQ(texture_id, registered_texture_id); + + EXPECT_TRUE(registrar.MarkTextureFrameAvailable(texture_id)); + EXPECT_TRUE(mark_frame_available_called); + + EXPECT_TRUE(registrar.UnregisterTexture(texture_id)); + EXPECT_TRUE(unregister_called); +} + +TEST_F(FlutterTizenTextureRegistrarTest, RegisterUnknownTextureType) { + EngineModifier modifier(engine_); + + FlutterTizenTextureRegistrar registrar(engine_); + + FlutterDesktopTextureInfo texture_info = {}; + texture_info.type = static_cast(1234); + + auto texture_id = registrar.RegisterTexture(&texture_info); + + EXPECT_EQ(texture_id, -1); +} + +TEST_F(FlutterTizenTextureRegistrarTest, PopulateInvalidTexture) { + FlutterTizenTextureRegistrar registrar(engine_); + + auto result = registrar.PopulateTexture(1, 640, 480, nullptr); + EXPECT_FALSE(result); +} + +} // namespace testing +} // namespace flutter diff --git a/shell/platform/tizen/testing/engine_modifier.h b/shell/platform/tizen/testing/engine_modifier.h new file mode 100644 index 0000000000000..4075ff77abbd8 --- /dev/null +++ b/shell/platform/tizen/testing/engine_modifier.h @@ -0,0 +1,30 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// 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/shell/platform/tizen/flutter_tizen_engine.h" + +namespace flutter { + +// A test utility class providing the ability to access and alter various +// private fields in an Engine instance. +// +// This simply provides a way to access the normally-private embedder proc +// table, so the lifetime of any changes made to the proc table is that of the +// engine object, not this helper. +class EngineModifier { + public: + explicit EngineModifier(FlutterTizenEngine* engine) : engine_(engine) {} + + // Returns the engine's embedder API proc table, allowing for modification. + // + // Modifications are to the engine, and will last for the lifetime of the + // engine unless overwritten again. + FlutterEngineProcTable& embedder_api() { return engine_->embedder_api_; } + + private: + FlutterTizenEngine* engine_; +}; + +} // namespace flutter