You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							198 lines
						
					
					
						
							5.7 KiB
						
					
					
				
			
		
		
	
	
							198 lines
						
					
					
						
							5.7 KiB
						
					
					
				#include "include/embedder_texture/embedder_texture_plugin.h" | 
						|
#include "include/fl_my_texture_gl.h" | 
						|
 | 
						|
#include <flutter_linux/flutter_linux.h> | 
						|
#include <flutter_linux/fl_view.h> | 
						|
#include <gtk/gtk.h> | 
						|
#include <gdk/gdkx.h> | 
						|
#include <sys/utsname.h> | 
						|
#include <glib.h> | 
						|
#include <GL/glew.h> | 
						|
 | 
						|
#include <thread> | 
						|
#include <chrono> | 
						|
#include <vector> | 
						|
 | 
						|
#include "embedder_texture_plugin_private.h" | 
						|
 | 
						|
#define EMBEDDER_TEXTURE_PLUGIN(obj)                                     \ | 
						|
  (G_TYPE_CHECK_INSTANCE_CAST((obj), embedder_texture_plugin_get_type(), \ | 
						|
                              LinuxOpenglPlugin)) | 
						|
 | 
						|
struct _LinuxOpenglPlugin | 
						|
{ | 
						|
  GObject parent_instance; | 
						|
 | 
						|
  unsigned int width = 0; | 
						|
  unsigned int height = 0; | 
						|
  unsigned int texture_id = 0; | 
						|
 | 
						|
  FlTexture *texture = nullptr; | 
						|
  FlTextureRegistrar *texture_registrar = nullptr; | 
						|
 | 
						|
  GdkGLContext *context = nullptr; | 
						|
  GdkWindow *window = nullptr; | 
						|
  FlMyTextureGL *myTexture = nullptr; | 
						|
  FlView *fl_view = nullptr; | 
						|
}; | 
						|
 | 
						|
G_DEFINE_TYPE(LinuxOpenglPlugin, embedder_texture_plugin, g_object_get_type()) | 
						|
 | 
						|
// Called when a method call is received from Flutter. | 
						|
static void embedder_texture_plugin_handle_method_call( | 
						|
    LinuxOpenglPlugin *self, | 
						|
    FlMethodCall *method_call) | 
						|
{ | 
						|
 | 
						|
  g_autoptr(FlMethodResponse) response = nullptr; | 
						|
 | 
						|
  const gchar *method = fl_method_call_get_name(method_call); | 
						|
 | 
						|
  if (strcmp(method, "create") == 0) | 
						|
  { | 
						|
    response = create(self, method_call); | 
						|
  } | 
						|
  else if (strcmp(method, "remove") == 0) | 
						|
  { | 
						|
    response = remove(self, method_call); | 
						|
  } | 
						|
  else | 
						|
  { | 
						|
    response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); | 
						|
  } | 
						|
 | 
						|
  fl_method_call_respond(method_call, response, nullptr); | 
						|
} | 
						|
 | 
						|
void set_color(LinuxOpenglPlugin *self) | 
						|
{ | 
						|
    gdk_gl_context_make_current(self->context); | 
						|
 | 
						|
    static GLfloat pixels[] = | 
						|
        { | 
						|
            1, 0, 0, | 
						|
            0, 1, 0, | 
						|
            0, 0, 1, | 
						|
            1, 1, 1 | 
						|
        }; | 
						|
 | 
						|
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels); | 
						|
 | 
						|
    fl_texture_registrar_mark_texture_frame_available(self->texture_registrar, self->texture); | 
						|
} | 
						|
 | 
						|
FlMethodResponse *create( | 
						|
    LinuxOpenglPlugin *self, | 
						|
    FlMethodCall *method_call) | 
						|
{ | 
						|
    GError *error = NULL; | 
						|
    FlValue *args = fl_method_call_get_args(method_call); | 
						|
    FlValue *w = fl_value_lookup_string(args, "width"); | 
						|
    FlValue *h = fl_value_lookup_string(args, "height"); | 
						|
 | 
						|
    if (w != nullptr) | 
						|
    { | 
						|
        self->width = fl_value_get_float(w); | 
						|
    } | 
						|
 | 
						|
    if (h != nullptr) | 
						|
    { | 
						|
        self->height = fl_value_get_float(h); | 
						|
    } | 
						|
 | 
						|
    if (self->width != 0 && self->height != 0) | 
						|
    { | 
						|
        self->window = gtk_widget_get_parent_window(GTK_WIDGET(self->fl_view)); | 
						|
        self->context = gdk_window_create_gl_context(self->window, &error); | 
						|
 | 
						|
        gdk_gl_context_make_current(self->context); | 
						|
 | 
						|
        glGenTextures(1, &self->texture_id); | 
						|
        glBindTexture(GL_TEXTURE_2D, self->texture_id); | 
						|
 | 
						|
        // drawing on the texture | 
						|
        set_color(self); | 
						|
 | 
						|
        self->myTexture = fl_my_texture_gl_new(GL_TEXTURE_2D, self->texture_id, self->width, self->height); | 
						|
        self->texture = FL_TEXTURE(self->myTexture); | 
						|
 | 
						|
        fl_texture_registrar_register_texture(self->texture_registrar, self->texture); | 
						|
        gdk_gl_context_clear_current(); | 
						|
 | 
						|
        g_autoptr(FlValue) result = fl_value_new_int(reinterpret_cast<int64_t>(self->texture)); | 
						|
        return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); | 
						|
    } | 
						|
 | 
						|
    return FL_METHOD_RESPONSE(fl_method_error_response_new( | 
						|
      "500", | 
						|
      "Method create() called without passing width or height parameters!", | 
						|
      nullptr)); | 
						|
} | 
						|
 | 
						|
FlMethodResponse *remove( | 
						|
    LinuxOpenglPlugin *self, | 
						|
    FlMethodCall *method_call) | 
						|
{ | 
						|
    FlValue *args = fl_method_call_get_args(method_call); | 
						|
    FlValue *id = fl_value_lookup_string(args, "textureId"); | 
						|
 | 
						|
    if (id != nullptr) | 
						|
    { | 
						|
        int textureId = fl_value_get_int(id); | 
						|
        fl_texture_registrar_unregister_texture(self->texture_registrar, self->texture); | 
						|
        g_autoptr(FlValue) result = fl_value_new_null(); | 
						|
        return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); | 
						|
    } | 
						|
 | 
						|
    return FL_METHOD_RESPONSE(fl_method_error_response_new( | 
						|
      "500", | 
						|
      "Method remove() called without passing textureId parameters!", | 
						|
      nullptr)); | 
						|
} | 
						|
 | 
						|
static void embedder_texture_plugin_dispose(GObject *object) | 
						|
{ | 
						|
  G_OBJECT_CLASS(embedder_texture_plugin_parent_class)->dispose(object); | 
						|
} | 
						|
 | 
						|
static void embedder_texture_plugin_class_init(LinuxOpenglPluginClass *klass) | 
						|
{ | 
						|
  G_OBJECT_CLASS(klass)->dispose = embedder_texture_plugin_dispose; | 
						|
} | 
						|
 | 
						|
static void embedder_texture_plugin_init(LinuxOpenglPlugin *self) {} | 
						|
 | 
						|
static void method_call_cb(FlMethodChannel *channel, FlMethodCall *method_call, | 
						|
                           gpointer user_data) | 
						|
{ | 
						|
  LinuxOpenglPlugin *plugin = EMBEDDER_TEXTURE_PLUGIN(user_data); | 
						|
  embedder_texture_plugin_handle_method_call(plugin, method_call); | 
						|
} | 
						|
 | 
						|
void embedder_texture_plugin_register_with_registrar(FlPluginRegistrar *registrar) | 
						|
{ | 
						|
  LinuxOpenglPlugin *plugin = EMBEDDER_TEXTURE_PLUGIN( | 
						|
      g_object_new(embedder_texture_plugin_get_type(), nullptr)); | 
						|
 | 
						|
  plugin->fl_view = fl_plugin_registrar_get_view(registrar); | 
						|
  plugin->texture_registrar = fl_plugin_registrar_get_texture_registrar(registrar); | 
						|
 | 
						|
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); | 
						|
  g_autoptr(FlMethodChannel) channel = | 
						|
      fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), | 
						|
                            "embedder_texture", | 
						|
                            FL_METHOD_CODEC(codec)); | 
						|
  fl_method_channel_set_method_call_handler(channel, method_call_cb, | 
						|
                                            g_object_ref(plugin), | 
						|
                                            g_object_unref); | 
						|
 | 
						|
  GLenum err = glewInit(); | 
						|
  if (GLEW_OK != err) | 
						|
  { | 
						|
    printf("%s", "Error!"); | 
						|
    printf("%s", glewGetErrorString(err)); | 
						|
    return; | 
						|
  } | 
						|
 | 
						|
  g_object_unref(plugin); | 
						|
}
 | 
						|
 |