@@ -30,69 +30,90 @@ struct ExternalTextureGLState {
3030
3131static std::atomic_long nextTextureId = {1 };
3232
33+ static void MarkTbmSurfaceToUse (void * surface) {
34+ #ifndef WEARABLE_PROFILE
35+ FT_ASSERT (surface);
36+ tbm_surface_h tbm_surface = (tbm_surface_h)surface;
37+ tbm_surface_internal_ref (tbm_surface);
38+ #endif
39+ }
40+
41+ static void UnmarkTbmSurfaceToUse (void * surface) {
42+ FT_ASSERT (surface);
43+ tbm_surface_h tbm_surface = (tbm_surface_h)surface;
44+ #ifndef WEARABLE_PROFILE
45+ tbm_surface_internal_unref (tbm_surface);
46+ #else
47+ tbm_surface_destroy (tbm_surface);
48+ #endif
49+ }
50+
3351ExternalTextureGL::ExternalTextureGL ()
3452 : state_(std::make_unique<ExternalTextureGLState>()),
35- texture_tbm_surface_( NULL ),
53+ available_tbm_surface_( nullptr ),
3654 texture_id_(nextTextureId++) {}
3755
3856ExternalTextureGL::~ExternalTextureGL () {
39- mutex_.lock ();
4057 if (state_->gl_texture != 0 ) {
4158 glDeleteTextures (1 , &state_->gl_texture );
4259 }
60+
61+ // If there is a available_tbm_surface_ that is not populated, remove it
62+ if (available_tbm_surface_) {
63+ UnmarkTbmSurfaceToUse (available_tbm_surface_);
64+ }
65+
4366 state_.release ();
44- DestructionTbmSurface ();
45- mutex_.unlock ();
4667}
4768
4869bool ExternalTextureGL::OnFrameAvailable (tbm_surface_h tbm_surface) {
49- mutex_.lock ();
5070 if (!tbm_surface) {
51- FT_LOGE (" tbm_surface is null" );
52- mutex_.unlock ();
71+ FT_LOGE (" [texture id:%ld] tbm_surface is null" , texture_id_);
5372 return false ;
5473 }
55- if (texture_tbm_surface_) {
56- FT_LOGD (" texture_tbm_surface_ does not destruction, discard" );
57- mutex_.unlock ();
74+
75+ if (available_tbm_surface_) {
76+ FT_LOGD (
77+ " [texture id:%ld] Discard! an available tbm surface that has not yet "
78+ " been used exists" ,
79+ texture_id_);
5880 return false ;
5981 }
82+
6083 tbm_surface_info_s info;
6184 if (tbm_surface_get_info (tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) {
62- FT_LOGD (" tbm_surface not valid, pass" );
63- mutex_.unlock ();
85+ FT_LOGD (" [texture id:%ld] tbm_surface not valid, pass" , texture_id_);
6486 return false ;
6587 }
66- texture_tbm_surface_ = tbm_surface;
67- mutex_.unlock ();
88+
89+ available_tbm_surface_ = tbm_surface;
90+ MarkTbmSurfaceToUse (available_tbm_surface_);
91+
6892 return true ;
6993}
7094
7195bool ExternalTextureGL::PopulateTextureWithIdentifier (
7296 size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) {
73- mutex_.lock ();
74- if (!texture_tbm_surface_) {
75- FT_LOGD (" texture_tbm_surface_ is NULL" );
76- mutex_.unlock ();
97+ if (!available_tbm_surface_) {
98+ FT_LOGD (" [texture id:%ld] available_tbm_surface_ is null" , texture_id_);
7799 return false ;
78100 }
79101 tbm_surface_info_s info;
80- if (tbm_surface_get_info (texture_tbm_surface_ , &info) !=
102+ if (tbm_surface_get_info (available_tbm_surface_ , &info) !=
81103 TBM_SURFACE_ERROR_NONE) {
82- FT_LOGD (" tbm_surface not valid " );
83- DestructionTbmSurface ( );
84- mutex_. unlock () ;
104+ FT_LOGD (" [texture id:%ld] tbm_surface is invalid " , texture_id_ );
105+ UnmarkTbmSurfaceToUse (available_tbm_surface_ );
106+ available_tbm_surface_ = nullptr ;
85107 return false ;
86108 }
87109
88110#ifdef TIZEN_RENDERER_EVAS_GL
89111 int attribs[] = {EVAS_GL_IMAGE_PRESERVED, GL_TRUE, 0 };
90112 EvasGLImage egl_src_image = evasglCreateImageForContext (
91113 g_evas_gl, evas_gl_current_context_get (g_evas_gl),
92- EVAS_GL_NATIVE_SURFACE_TIZEN, (void *)(intptr_t )texture_tbm_surface_ ,
114+ EVAS_GL_NATIVE_SURFACE_TIZEN, (void *)(intptr_t )available_tbm_surface_ ,
93115 attribs);
94116 if (!egl_src_image) {
95- mutex_.unlock ();
96117 return false ;
97118 }
98119 if (state_->gl_texture == 0 ) {
@@ -120,10 +141,11 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier(
120141 EGL_NONE};
121142 EGLImageKHR egl_src_image = n_eglCreateImageKHR (
122143 eglGetCurrentDisplay (), EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN,
123- (EGLClientBuffer)texture_tbm_surface_, attribs);
144+ (EGLClientBuffer)available_tbm_surface_, attribs);
145+
124146 if (!egl_src_image) {
125- FT_LOGE (" egl_src_image create fail!!, errorcode == %d" , eglGetError ());
126- mutex_. unlock ( );
147+ FT_LOGE (" [texture id:%ld] egl_src_image create fail!!, errorcode == %d" ,
148+ texture_id_, eglGetError () );
127149 return false ;
128150 }
129151 if (state_->gl_texture == 0 ) {
@@ -154,31 +176,13 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier(
154176 opengl_texture->target = GL_TEXTURE_EXTERNAL_OES;
155177 opengl_texture->name = state_->gl_texture ;
156178 opengl_texture->format = GL_RGBA8;
157- opengl_texture->destruction_callback = (VoidCallback)DestructionCallback;
158- opengl_texture->user_data = static_cast <void *>(this );
179+ opengl_texture->destruction_callback = (VoidCallback)UnmarkTbmSurfaceToUse;
180+
181+ // Abandon ownership of tbm_surface
182+ opengl_texture->user_data = available_tbm_surface_;
183+ available_tbm_surface_ = nullptr ;
184+
159185 opengl_texture->width = width;
160186 opengl_texture->height = height;
161- mutex_.unlock ();
162187 return true ;
163188}
164-
165- void ExternalTextureGL::DestructionTbmSurfaceWithLock () {
166- mutex_.lock ();
167- DestructionTbmSurface ();
168- mutex_.unlock ();
169- }
170-
171- void ExternalTextureGL::DestructionTbmSurface () {
172- if (!texture_tbm_surface_) {
173- FT_LOGE (" tbm_surface_h is NULL" );
174- return ;
175- }
176- tbm_surface_destroy (texture_tbm_surface_);
177- texture_tbm_surface_ = NULL ;
178- }
179-
180- void ExternalTextureGL::DestructionCallback (void * user_data) {
181- ExternalTextureGL* externalTextureGL =
182- reinterpret_cast <ExternalTextureGL*>(user_data);
183- externalTextureGL->DestructionTbmSurfaceWithLock ();
184- }
0 commit comments