Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 49 additions & 35 deletions shell/platform/tizen/external_texture_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,41 @@ struct ExternalTextureGLState {

static std::atomic_long nextTextureId = {1};

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

static void UnmarkTbmSurfaceToUse(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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why destroy tbm surface here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It reflects the current implementation that does not use ref/unref.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementaion does not work tho.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swift-kim You are right.
@swift-kim @xuelian-bai
if the cost of using map/unmap is high, I think using ref/unref is fine until find an alternative.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can use the method to get the function pointer from libtbm.so.1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xuelian-bai

I didn't get it. You use media_packet instead of tbm surface, but how to generate texture by using media_packet?

Basically, we have to do same work which is performed by video or camera plug-in.. Code at #80 is just to show how change of interface will be... but the explanation seems to be insufficient.
I'll make a PR , so let's discuss whether it applies or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xuelian-bai
My suggestion is in number #82.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bwikbs, @xuelian-bai
This PR fixes a crash and allows to use external textures in profiles other than wearable.
So, how about that we go to #82 for the discussion on how to create an external texture?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you merge this PR, if there is no issue other than things related to #82

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea. Shall we go to #82 for discussion regarding this?

#endif
}

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

ExternalTextureGL::~ExternalTextureGL() {
mutex_.lock();
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();
DestructionTbmSurface();
mutex_.unlock();
}

Expand All @@ -52,35 +75,42 @@ bool ExternalTextureGL::OnFrameAvailable(tbm_surface_h tbm_surface) {
mutex_.unlock();
return false;
}
if (texture_tbm_surface_) {
FT_LOGD("texture_tbm_surface_ does not destruction, discard");

if (available_tbm_surface_) {
FT_LOGD(
"Discard! an available tbm surface that has not yet been used exists");
mutex_.unlock();
return false;
}

tbm_surface_info_s info;
if (tbm_surface_get_info(tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) {
FT_LOGD("tbm_surface not valid, pass");
mutex_.unlock();
return false;
}
texture_tbm_surface_ = tbm_surface;

available_tbm_surface_ = tbm_surface;
MarkTbmSurfaceToUse(available_tbm_surface_);

mutex_.unlock();
return true;
}

bool ExternalTextureGL::PopulateTextureWithIdentifier(
size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) {
mutex_.lock();
if (!texture_tbm_surface_) {
FT_LOGD("texture_tbm_surface_ is NULL");
if (!available_tbm_surface_) {
FT_LOGD("available_tbm_surface_ is null");
mutex_.unlock();
return false;
}
tbm_surface_info_s info;
if (tbm_surface_get_info(texture_tbm_surface_, &info) !=
if (tbm_surface_get_info(available_tbm_surface_, &info) !=
TBM_SURFACE_ERROR_NONE) {
FT_LOGD("tbm_surface not valid");
DestructionTbmSurface();
FT_LOGD("tbm_surface is invalid");
UnmarkTbmSurfaceToUse(available_tbm_surface_);
available_tbm_surface_ = nullptr;
mutex_.unlock();
return false;
}
Expand All @@ -89,7 +119,7 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier(
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)texture_tbm_surface_,
EVAS_GL_NATIVE_SURFACE_TIZEN, (void*)(intptr_t)available_tbm_surface_,
attribs);
if (!egl_src_image) {
mutex_.unlock();
Expand Down Expand Up @@ -120,7 +150,8 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier(
EGL_NONE};
EGLImageKHR egl_src_image = n_eglCreateImageKHR(
eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN,
(EGLClientBuffer)texture_tbm_surface_, attribs);
(EGLClientBuffer)available_tbm_surface_, attribs);

if (!egl_src_image) {
FT_LOGE("egl_src_image create fail!!, errorcode == %d", eglGetError());
mutex_.unlock();
Expand Down Expand Up @@ -154,31 +185,14 @@ 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)DestructionCallback;
opengl_texture->user_data = static_cast<void*>(this);
opengl_texture->destruction_callback = (VoidCallback)UnmarkTbmSurfaceToUse;

// Abandon ownership of tmb_surface
opengl_texture->user_data = available_tbm_surface_;
available_tbm_surface_ = nullptr;

opengl_texture->width = width;
opengl_texture->height = height;
mutex_.unlock();
return true;
}

void ExternalTextureGL::DestructionTbmSurfaceWithLock() {
mutex_.lock();
DestructionTbmSurface();
mutex_.unlock();
}

void ExternalTextureGL::DestructionTbmSurface() {
if (!texture_tbm_surface_) {
FT_LOGE("tbm_surface_h is NULL");
return;
}
tbm_surface_destroy(texture_tbm_surface_);
texture_tbm_surface_ = NULL;
}

void ExternalTextureGL::DestructionCallback(void* user_data) {
ExternalTextureGL* externalTextureGL =
reinterpret_cast<ExternalTextureGL*>(user_data);
externalTextureGL->DestructionTbmSurfaceWithLock();
}
7 changes: 2 additions & 5 deletions shell/platform/tizen/external_texture_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,12 @@ class ExternalTextureGL {
bool PopulateTextureWithIdentifier(size_t width, size_t height,
FlutterOpenGLTexture* opengl_texture);
bool OnFrameAvailable(tbm_surface_h tbm_surface);
void DestructionTbmSurface();
void DestructionTbmSurfaceWithLock();

private:
std::unique_ptr<ExternalTextureGLState> state_;
std::mutex mutex_;
tbm_surface_h texture_tbm_surface_;
static void DestructionCallback(void* user_data);
const long texture_id_;
tbm_surface_h available_tbm_surface_{nullptr};
const long texture_id_{0};
};

#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_