From b4dafee566939a8784b80d7c6fee8c103c601c5f Mon Sep 17 00:00:00 2001 From: MuHong Byun Date: Mon, 12 Jul 2021 14:41:14 +0900 Subject: [PATCH 1/3] Add flutter_tizen_texture_registrar unittest Signed-off-by: MuHong Byun --- shell/platform/tizen/BUILD.gn | 3 + .../tizen/external_texture_pixel_gl.cc | 4 + .../tizen/external_texture_pixel_gl_stub.cc | 77 +++++++++++ .../tizen/external_texture_surface_gl.cc | 7 +- .../tizen/external_texture_surface_gl_stub.cc | 53 ++++++++ shell/platform/tizen/flutter_tizen_engine.h | 2 + .../tizen/flutter_tizen_texture_registrar.cc | 7 - ...utter_tizen_texture_registrar_unittests.cc | 126 ++++++++++++++++++ .../platform/tizen/testing/engine_modifier.h | 28 ++++ 9 files changed, 299 insertions(+), 8 deletions(-) create mode 100644 shell/platform/tizen/external_texture_pixel_gl_stub.cc create mode 100644 shell/platform/tizen/external_texture_surface_gl_stub.cc create mode 100644 shell/platform/tizen/flutter_tizen_texture_registrar_unittests.cc create mode 100644 shell/platform/tizen/testing/engine_modifier.h 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..a7fe458a6ab78 --- /dev/null +++ b/shell/platform/tizen/external_texture_pixel_gl_stub.cc @@ -0,0 +1,77 @@ +// 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" + +#ifdef TIZEN_RENDERER_EVAS_GL +#undef EFL_BETA_API_SUPPORT +#include "tizen_evas_gl_helper.h" +extern Evas_GL* g_evas_gl; +EVAS_GL_GLOBAL_GLES3_DECLARE(); +#else +#include +#include +#include +#include +#endif + +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) { + if (!CopyPixelBuffer(width, height)) { + return false; + } + + // Populate the texture object used by the engine. + opengl_texture->target = GL_TEXTURE_2D; + opengl_texture->name = state_->gl_texture; + opengl_texture->format = GL_RGBA8; + opengl_texture->destruction_callback = nullptr; + opengl_texture->user_data = nullptr; + opengl_texture->width = width; + opengl_texture->height = height; + return true; +} + +bool ExternalTexturePixelGL::CopyPixelBuffer(size_t& width, size_t& height) { + if (!texture_callback_) { + return false; + } + + const FlutterDesktopPixelBuffer* pixel_buffer = + texture_callback_(width, height, user_data_); + + if (!pixel_buffer || !pixel_buffer->buffer) { + return false; + } + + width = pixel_buffer->width; + height = pixel_buffer->height; + + if (state_->gl_texture == 0) { + glGenTextures(1, &state_->gl_texture); + glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width, + pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixel_buffer->buffer); + return true; +} +} // 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..ea32bd986463d --- /dev/null +++ b/shell/platform/tizen/external_texture_surface_gl_stub.cc @@ -0,0 +1,53 @@ +// 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" + +#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/tizen/tizen_log.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_) { + return false; + } + + const FlutterDesktopGpuBuffer* gpu_buffer = + texture_callback_(width, height, user_data_); + if (!gpu_buffer) { + FT_LOGI("[texture id:%ld] gpu_buffer is null", texture_id_); + return false; + } + if (!gpu_buffer->buffer) { + FT_LOGI("[texture id:%ld] tbm_surface_ is null", texture_id_); + return false; + } + FT_UNIMPLEMENTED(); + 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..476670815fec4 --- /dev/null +++ b/shell/platform/tizen/testing/engine_modifier.h @@ -0,0 +1,28 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Copyright 2013 The Flutter Authors. All rights reserved. + +#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 From 438a819272d4cac99866f205156cff9f4fdf5941 Mon Sep 17 00:00:00 2001 From: MuHong Byun Date: Tue, 13 Jul 2021 12:36:46 +0900 Subject: [PATCH 2/3] Apply review's comment * Remove redundant code Signed-off-by: MuHong Byun --- .../tizen/external_texture_pixel_gl_stub.cc | 44 ++----------------- .../tizen/external_texture_surface_gl_stub.cc | 16 +------ 2 files changed, 6 insertions(+), 54 deletions(-) diff --git a/shell/platform/tizen/external_texture_pixel_gl_stub.cc b/shell/platform/tizen/external_texture_pixel_gl_stub.cc index a7fe458a6ab78..28535176a3b42 100644 --- a/shell/platform/tizen/external_texture_pixel_gl_stub.cc +++ b/shell/platform/tizen/external_texture_pixel_gl_stub.cc @@ -29,49 +29,13 @@ bool ExternalTexturePixelGL::PopulateTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { - if (!CopyPixelBuffer(width, height)) { - return false; - } - - // Populate the texture object used by the engine. - opengl_texture->target = GL_TEXTURE_2D; - opengl_texture->name = state_->gl_texture; - opengl_texture->format = GL_RGBA8; - opengl_texture->destruction_callback = nullptr; - opengl_texture->user_data = nullptr; - opengl_texture->width = width; - opengl_texture->height = height; - return true; + return CopyPixelBuffer(width, height); } bool ExternalTexturePixelGL::CopyPixelBuffer(size_t& width, size_t& height) { - if (!texture_callback_) { - return false; - } - - const FlutterDesktopPixelBuffer* pixel_buffer = - texture_callback_(width, height, user_data_); - - if (!pixel_buffer || !pixel_buffer->buffer) { - return false; - } - - width = pixel_buffer->width; - height = pixel_buffer->height; - - if (state_->gl_texture == 0) { - glGenTextures(1, &state_->gl_texture); - glBindTexture(GL_TEXTURE_2D, state_->gl_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + if (texture_callback_ && user_data_) { + return true; } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width, - pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, - pixel_buffer->buffer); - return true; + return false; } } // namespace flutter diff --git a/shell/platform/tizen/external_texture_surface_gl_stub.cc b/shell/platform/tizen/external_texture_surface_gl_stub.cc index ea32bd986463d..d73d10ac5c905 100644 --- a/shell/platform/tizen/external_texture_surface_gl_stub.cc +++ b/shell/platform/tizen/external_texture_surface_gl_stub.cc @@ -26,21 +26,9 @@ bool ExternalTextureSurfaceGL::PopulateTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { - if (!texture_callback_) { - return false; + if (texture_callback_ && destruction_callback_ && user_data_) { + return true; } - - const FlutterDesktopGpuBuffer* gpu_buffer = - texture_callback_(width, height, user_data_); - if (!gpu_buffer) { - FT_LOGI("[texture id:%ld] gpu_buffer is null", texture_id_); - return false; - } - if (!gpu_buffer->buffer) { - FT_LOGI("[texture id:%ld] tbm_surface_ is null", texture_id_); - return false; - } - FT_UNIMPLEMENTED(); return false; } From bd2df7917cf4c2ec39c01134bdad07d8c7866646 Mon Sep 17 00:00:00 2001 From: MuHong Byun Date: Wed, 14 Jul 2021 13:34:41 +0900 Subject: [PATCH 3/3] Apply review's comment #2 Signed-off-by: MuHong Byun --- .../platform/tizen/external_texture_pixel_gl_stub.cc | 12 ------------ .../tizen/external_texture_surface_gl_stub.cc | 3 --- shell/platform/tizen/testing/engine_modifier.h | 2 ++ 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/shell/platform/tizen/external_texture_pixel_gl_stub.cc b/shell/platform/tizen/external_texture_pixel_gl_stub.cc index 28535176a3b42..f6a1ae0a1a5cc 100644 --- a/shell/platform/tizen/external_texture_pixel_gl_stub.cc +++ b/shell/platform/tizen/external_texture_pixel_gl_stub.cc @@ -4,18 +4,6 @@ #include "flutter/shell/platform/tizen/external_texture_pixel_gl.h" -#ifdef TIZEN_RENDERER_EVAS_GL -#undef EFL_BETA_API_SUPPORT -#include "tizen_evas_gl_helper.h" -extern Evas_GL* g_evas_gl; -EVAS_GL_GLOBAL_GLES3_DECLARE(); -#else -#include -#include -#include -#include -#endif - namespace flutter { ExternalTexturePixelGL::ExternalTexturePixelGL( diff --git a/shell/platform/tizen/external_texture_surface_gl_stub.cc b/shell/platform/tizen/external_texture_surface_gl_stub.cc index d73d10ac5c905..07f21e8673ae6 100644 --- a/shell/platform/tizen/external_texture_surface_gl_stub.cc +++ b/shell/platform/tizen/external_texture_surface_gl_stub.cc @@ -4,9 +4,6 @@ #include "external_texture_surface_gl.h" -#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" -#include "flutter/shell/platform/tizen/tizen_log.h" - namespace flutter { ExternalTextureSurfaceGL::ExternalTextureSurfaceGL( diff --git a/shell/platform/tizen/testing/engine_modifier.h b/shell/platform/tizen/testing/engine_modifier.h index 476670815fec4..4075ff77abbd8 100644 --- a/shell/platform/tizen/testing/engine_modifier.h +++ b/shell/platform/tizen/testing/engine_modifier.h @@ -1,5 +1,7 @@ // 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"