Skip to content

Commit

Permalink
Change api of external texture
Browse files Browse the repository at this point in the history
* Add interface for media_packet_h

Signed-off-by: MuHong Byun <mh.byun@samsung.com>
  • Loading branch information
bwikbs committed May 10, 2021
1 parent ad1fd5b commit 8b98607
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 79 deletions.
2 changes: 2 additions & 0 deletions shell/platform/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ config("tizen_rootstrap_include_dirs") {
"$custom_sysroot/usr/include/emile-1",
"$custom_sysroot/usr/include/eo-1",
"$custom_sysroot/usr/include/evas-1",
"$custom_sysroot/usr/include/media",
"$custom_sysroot/usr/include/system",
"$custom_sysroot/usr/include/wayland-extension",
# For Evas_GL.
Expand Down Expand Up @@ -106,6 +107,7 @@ template("embedder_for_profile") {
libs = [
"base-utils-i18n",
"capi-appfw-application",
"capi-media-tool",
"capi-system-info",
"capi-system-system-settings",
"dlog",
Expand Down
190 changes: 123 additions & 67 deletions shell/platform/tizen/external_texture_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,89 +30,36 @@ struct ExternalTextureGLState {

static std::atomic_long nextTextureId = {1};

static void MarkTbmSurfaceToUse(void* surface) {
#ifndef WEARABLE_PROFILE
static void UnmarkTbmSurfaceToUse(void* surface) {
FT_ASSERT(surface);
tbm_surface_h tbm_surface = (tbm_surface_h)surface;
tbm_surface_internal_ref(tbm_surface);
#endif
tbm_surface_destroy(tbm_surface);
}

static void UnmarkTbmSurfaceToUse(void* surface) {
static void UnmarkMediaPacketToUse(void* surface) {
FT_ASSERT(surface);
tbm_surface_h tbm_surface = (tbm_surface_h)surface;
#ifndef WEARABLE_PROFILE
tbm_surface_internal_unref(tbm_surface);
#else
tbm_surface_destroy(tbm_surface);
#endif
media_packet_destroy((media_packet_h)surface);
}

ExternalTextureGL::ExternalTextureGL()
: state_(std::make_unique<ExternalTextureGLState>()),
available_tbm_surface_(nullptr),
texture_id_(nextTextureId++) {}

ExternalTextureGL::~ExternalTextureGL() {
if (state_->gl_texture != 0) {
glDeleteTextures(1, &state_->gl_texture);
}

// If there is a available_tbm_surface_ that is not populated, remove it
if (available_tbm_surface_) {
UnmarkTbmSurfaceToUse(available_tbm_surface_);
}

state_.release();
}

bool ExternalTextureGL::OnFrameAvailable(tbm_surface_h tbm_surface) {
if (!tbm_surface) {
FT_LOGE("[texture id:%ld] tbm_surface is null", texture_id_);
return false;
}

if (available_tbm_surface_) {
FT_LOGD(
"[texture id:%ld] Discard! an available tbm surface that has not yet "
"been used exists",
texture_id_);
return false;
}

tbm_surface_info_s info;
if (tbm_surface_get_info(tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) {
FT_LOGD("[texture id:%ld] tbm_surface not valid, pass", texture_id_);
return false;
}

available_tbm_surface_ = tbm_surface;
MarkTbmSurfaceToUse(available_tbm_surface_);

return true;
}

bool ExternalTextureGL::PopulateTextureWithIdentifier(
size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) {
if (!available_tbm_surface_) {
FT_LOGD("[texture id:%ld] available_tbm_surface_ is null", texture_id_);
return false;
}
tbm_surface_info_s info;
if (tbm_surface_get_info(available_tbm_surface_, &info) !=
TBM_SURFACE_ERROR_NONE) {
FT_LOGD("[texture id:%ld] tbm_surface is invalid", texture_id_);
UnmarkTbmSurfaceToUse(available_tbm_surface_);
available_tbm_surface_ = nullptr;
return false;
}

bool ExternalTextureGL::MakeTextureFromExternalImage(
tbm_surface_h surface, void* external_image, size_t width, size_t height,
FlutterOpenGLTexture* opengl_texture, VoidCallback destruction_callback) {
#ifdef TIZEN_RENDERER_EVAS_GL
int attribs[] = {EVAS_GL_IMAGE_PRESERVED, GL_TRUE, 0};
EvasGLImage egl_src_image = evasglCreateImageForContext(
g_evas_gl, evas_gl_current_context_get(g_evas_gl),
EVAS_GL_NATIVE_SURFACE_TIZEN, (void*)(intptr_t)available_tbm_surface_,
attribs);
EVAS_GL_NATIVE_SURFACE_TIZEN, (void*)(intptr_t)surface, attribs);
if (!egl_src_image) {
return false;
}
Expand Down Expand Up @@ -141,7 +88,7 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier(
EGL_NONE};
EGLImageKHR egl_src_image = n_eglCreateImageKHR(
eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN,
(EGLClientBuffer)available_tbm_surface_, attribs);
(EGLClientBuffer)surface, attribs);

if (!egl_src_image) {
FT_LOGE("[texture id:%ld] egl_src_image create fail!!, errorcode == %d",
Expand Down Expand Up @@ -176,13 +123,122 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier(
opengl_texture->target = GL_TEXTURE_EXTERNAL_OES;
opengl_texture->name = state_->gl_texture;
opengl_texture->format = GL_RGBA8;
opengl_texture->destruction_callback = (VoidCallback)UnmarkTbmSurfaceToUse;
opengl_texture->destruction_callback = destruction_callback;
opengl_texture->user_data = external_image;
opengl_texture->width = width;
opengl_texture->height = height;

return true;
}

ExternalTextureTbm::ExternalTextureTbm()
: ExternalTextureGL(), available_tbm_surface_(nullptr) {}

// Abandon ownership of tbm_surface
opengl_texture->user_data = available_tbm_surface_;
ExternalTextureTbm::~ExternalTextureTbm() {
if (available_tbm_surface_) {
UnmarkTbmSurfaceToUse(available_tbm_surface_);
}
}

bool ExternalTextureTbm::OnFrameAvailable(void* external_image) {
if (!external_image) {
FT_LOGE("[texture id:%ld] tbm_surface is null", (long)TextureId());
return false;
}
tbm_surface_h tbm_surface = (tbm_surface_h)external_image;

if (available_tbm_surface_) {
FT_LOGD(
"[texture id:%ld] Discard! an available tbm surface that has not yet "
"been used exists",
(long)TextureId());
return false;
}

tbm_surface_info_s info;
if (tbm_surface_get_info(tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) {
FT_LOGD("[texture id:%ld] tbm_surface not valid, pass", (long)TextureId());
return false;
}
available_tbm_surface_ = tbm_surface;

return true;
}

bool ExternalTextureTbm::PopulateTextureWithIdentifier(
size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) {
if (!available_tbm_surface_) {
FT_LOGD("[texture id:%ld] available_tbm_surface_ is null",
(long)TextureId());
return false;
}
tbm_surface_info_s info;
if (tbm_surface_get_info(available_tbm_surface_, &info) !=
TBM_SURFACE_ERROR_NONE) {
FT_LOGD("[texture id:%ld] tbm_surface is invalid", (long)TextureId());
UnmarkTbmSurfaceToUse(available_tbm_surface_);
available_tbm_surface_ = nullptr;
return false;
}
MakeTextureFromExternalImage(
available_tbm_surface_, (void*)available_tbm_surface_, width, height,
opengl_texture, (VoidCallback)UnmarkTbmSurfaceToUse);
available_tbm_surface_ = nullptr;
return true;
}

opengl_texture->width = width;
opengl_texture->height = height;
ExternalTextureMediaPacket::ExternalTextureMediaPacket()
: ExternalTextureGL(), available_media_packet_(nullptr) {}

ExternalTextureMediaPacket::~ExternalTextureMediaPacket() {
if (available_media_packet_) {
UnmarkTbmSurfaceToUse(available_media_packet_);
}
}

bool ExternalTextureMediaPacket::OnFrameAvailable(void* external_image) {
if (!external_image) {
FT_LOGE("[texture id:%ld] media_packet is null", (long)TextureId());
return false;
}

if (available_media_packet_) {
FT_LOGD(
"[texture id:%ld] Discard! an available media_packet that has not yet "
"been used exists",
(long)TextureId());
// If not ready, discard media_packet.
UnmarkMediaPacketToUse(external_image);
return false;
}

available_media_packet_ = (media_packet_h)external_image;
return true;
}

bool ExternalTextureMediaPacket::PopulateTextureWithIdentifier(
size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) {
if (!available_media_packet_) {
FT_LOGD("[texture id:%ld] available_media_packet_ is null",
(long)TextureId());
return false;
}

tbm_surface_h tbm_surface;
if (media_packet_get_tbm_surface(available_media_packet_, &tbm_surface) !=
0) {
FT_LOGD("[texture id:%ld] fail to get tbm_surface from media_packet",
(long)TextureId());
return false;
}
tbm_surface_info_s info;
if (tbm_surface_get_info(tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) {
FT_LOGD("[texture id:%ld] tbm_surface is invalid", (long)TextureId());
return false;
}
MakeTextureFromExternalImage(tbm_surface, available_media_packet_, width,
height, opengl_texture,
(VoidCallback)UnmarkMediaPacketToUse);
available_media_packet_ = nullptr;
return true;
}
48 changes: 42 additions & 6 deletions shell/platform/tizen/external_texture_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_
#define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_

#include <media_packet.h>
#include <stdint.h>
#include <tbm_bufmgr.h>
#include <tbm_drm_helper.h>
Expand All @@ -22,7 +23,6 @@ typedef struct ExternalTextureGLState ExternalTextureGLState;
class ExternalTextureGL {
public:
ExternalTextureGL();

virtual ~ExternalTextureGL();

/**
Expand All @@ -38,15 +38,51 @@ class ExternalTextureGL {
* texture object.
* Returns true on success, false on failure.
*/
bool PopulateTextureWithIdentifier(size_t width, size_t height,
FlutterOpenGLTexture* opengl_texture);
bool OnFrameAvailable(tbm_surface_h tbm_surface);
virtual bool PopulateTextureWithIdentifier(
size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) {
// assert;
return false;
}
virtual bool OnFrameAvailable(void* external_image) {
// assert;
return false;
}

private:
protected:
bool MakeTextureFromExternalImage(tbm_surface_h surface, void* external_image, size_t width,
size_t height,
FlutterOpenGLTexture* opengl_texture,
VoidCallback destruction_callback);
private:
std::unique_ptr<ExternalTextureGLState> state_;
std::mutex mutex_;
tbm_surface_h available_tbm_surface_{nullptr};
const long texture_id_{0};
};

class ExternalTextureTbm : public ExternalTextureGL {
public:
ExternalTextureTbm();
~ExternalTextureTbm();
virtual bool PopulateTextureWithIdentifier(
size_t width, size_t height,
FlutterOpenGLTexture* opengl_texture) override;
virtual bool OnFrameAvailable(void* external_image) override;

private:
tbm_surface_h available_tbm_surface_{nullptr};
};

class ExternalTextureMediaPacket : public ExternalTextureGL {
public:
ExternalTextureMediaPacket();
~ExternalTextureMediaPacket();
virtual bool PopulateTextureWithIdentifier(
size_t width, size_t height,
FlutterOpenGLTexture* opengl_texture) override;
virtual bool OnFrameAvailable(void* external_image) override;

private:
media_packet_h available_media_packet_{nullptr};
};

#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_
15 changes: 10 additions & 5 deletions shell/platform/tizen/flutter_tizen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,16 @@ void FlutterNotifyLowMemoryWarning(FlutterWindowControllerRef controller) {
}

int64_t FlutterRegisterExternalTexture(
FlutterTextureRegistrarRef texture_registrar) {
FlutterTextureRegistrarRef texture_registrar,
TizenTextureType textureType) {
FT_LOGD("FlutterDesktopRegisterExternalTexture");
std::lock_guard<std::mutex> lock(texture_registrar->mutex);
auto texture_gl = std::make_unique<ExternalTextureGL>();
std::unique_ptr<ExternalTextureGL> texture_gl;
if (textureType == TbmSurface) {
texture_gl = std::make_unique<ExternalTextureTbm>();
} else {
texture_gl = std::make_unique<ExternalTextureMediaPacket>();
}
int64_t texture_id = texture_gl->TextureId();
texture_registrar->textures[texture_id] = std::move(texture_gl);
if (FlutterEngineRegisterExternalTexture(texture_registrar->flutter_engine,
Expand All @@ -205,15 +211,14 @@ bool FlutterUnregisterExternalTexture(

bool FlutterMarkExternalTextureFrameAvailable(
FlutterTextureRegistrarRef texture_registrar, int64_t texture_id,
void* tbm_surface) {
void* frame) {
std::lock_guard<std::mutex> lock(texture_registrar->mutex);
auto it = texture_registrar->textures.find(texture_id);
if (it == texture_registrar->textures.end()) {
FT_LOGE("can't find texture texture_id = %" PRId64, texture_id);
return false;
}
if (!texture_registrar->textures[texture_id]->OnFrameAvailable(
(tbm_surface_h)tbm_surface)) {
if (!texture_registrar->textures[texture_id]->OnFrameAvailable(frame)) {
// If a texture that has not been used already exists, it can fail
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
extern "C" {
#endif

enum TizenTextureType { TbmSurface = 0, MediaPacket };

// Opaque reference to a texture registrar.
typedef struct FlutterTextureRegistrar* FlutterTextureRegistrarRef;

Expand All @@ -23,7 +25,8 @@ FlutterPluginRegistrarGetTexture(FlutterDesktopPluginRegistrarRef registrar);

// Registers a new texture with the Flutter engine and returns the texture ID,
FLUTTER_EXPORT int64_t
FlutterRegisterExternalTexture(FlutterTextureRegistrarRef texture_registrar);
FlutterRegisterExternalTexture(FlutterTextureRegistrarRef texture_registrar,
TizenTextureType textureType = TbmSurface);

// Unregisters an existing texture from the Flutter engine for a |texture_id|.
// Returns true on success, false on failure.
Expand Down

0 comments on commit 8b98607

Please sign in to comment.