mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Use the X visual from the EGL configuration when making an FlView. (#19438)
This commit is contained in:
parent
f8bbcc396b
commit
acd026ed3f
@ -23,9 +23,9 @@ TEST(EGLUtils, ErrorToStringNegative) {
|
||||
|
||||
TEST(EGLUtils, ConfigToString) {
|
||||
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
eglInitialize(display, nullptr, nullptr);
|
||||
EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
|
||||
EGLConfig config;
|
||||
eglChooseConfig(display, nullptr, &config, 1, nullptr);
|
||||
EXPECT_TRUE(eglChooseConfig(display, nullptr, &config, 1, nullptr));
|
||||
g_autofree gchar* config_string = egl_config_to_string(display, config);
|
||||
EXPECT_STREQ(
|
||||
config_string,
|
||||
@ -46,9 +46,9 @@ TEST(EGLUtils, ConfigToString) {
|
||||
|
||||
TEST(EGLUtils, ConfigToStringNullptr) {
|
||||
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
eglInitialize(display, nullptr, nullptr);
|
||||
EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
|
||||
EGLConfig config;
|
||||
eglChooseConfig(display, nullptr, &config, 1, nullptr);
|
||||
EXPECT_TRUE(eglChooseConfig(display, nullptr, &config, 1, nullptr));
|
||||
g_autofree gchar* config_string1 = egl_config_to_string(nullptr, config);
|
||||
EXPECT_STREQ(config_string1, "");
|
||||
g_autofree gchar* config_string2 = egl_config_to_string(display, nullptr);
|
||||
|
||||
@ -15,10 +15,13 @@
|
||||
static FlEngine* make_mock_engine() {
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
g_autoptr(GError) renderer_error = nullptr;
|
||||
EXPECT_TRUE(fl_renderer_setup(FL_RENDERER(renderer), &renderer_error));
|
||||
EXPECT_EQ(renderer_error, nullptr);
|
||||
g_autoptr(FlEngine) engine = fl_engine_new(project, FL_RENDERER(renderer));
|
||||
g_autoptr(GError) error = nullptr;
|
||||
EXPECT_TRUE(fl_engine_start(engine, &error));
|
||||
EXPECT_EQ(error, nullptr);
|
||||
g_autoptr(GError) engine_error = nullptr;
|
||||
EXPECT_TRUE(fl_engine_start(engine, &engine_error));
|
||||
EXPECT_EQ(engine_error, nullptr);
|
||||
|
||||
return static_cast<FlEngine*>(g_object_ref(engine));
|
||||
}
|
||||
|
||||
@ -14,10 +14,13 @@
|
||||
static FlEngine* make_mock_engine() {
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
g_autoptr(GError) renderer_error = nullptr;
|
||||
EXPECT_TRUE(fl_renderer_setup(FL_RENDERER(renderer), &renderer_error));
|
||||
EXPECT_EQ(renderer_error, nullptr);
|
||||
g_autoptr(FlEngine) engine = fl_engine_new(project, FL_RENDERER(renderer));
|
||||
g_autoptr(GError) error = nullptr;
|
||||
EXPECT_TRUE(fl_engine_start(engine, &error));
|
||||
EXPECT_EQ(error, nullptr);
|
||||
g_autoptr(GError) engine_error = nullptr;
|
||||
EXPECT_TRUE(fl_engine_start(engine, &engine_error));
|
||||
EXPECT_EQ(engine_error, nullptr);
|
||||
|
||||
return static_cast<FlEngine*>(g_object_ref(engine));
|
||||
}
|
||||
|
||||
@ -17,10 +17,13 @@
|
||||
static FlEngine* make_mock_engine() {
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
g_autoptr(GError) renderer_error = nullptr;
|
||||
EXPECT_TRUE(fl_renderer_setup(FL_RENDERER(renderer), &renderer_error));
|
||||
EXPECT_EQ(renderer_error, nullptr);
|
||||
g_autoptr(FlEngine) engine = fl_engine_new(project, FL_RENDERER(renderer));
|
||||
g_autoptr(GError) error = nullptr;
|
||||
EXPECT_TRUE(fl_engine_start(engine, &error));
|
||||
EXPECT_EQ(error, nullptr);
|
||||
g_autoptr(GError) engine_error = nullptr;
|
||||
EXPECT_TRUE(fl_engine_start(engine, &engine_error));
|
||||
EXPECT_EQ(engine_error, nullptr);
|
||||
|
||||
return static_cast<FlEngine*>(g_object_ref(engine));
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ G_DEFINE_QUARK(fl_renderer_error_quark, fl_renderer_error)
|
||||
|
||||
typedef struct {
|
||||
EGLDisplay egl_display;
|
||||
EGLConfig egl_config;
|
||||
EGLSurface egl_surface;
|
||||
EGLContext egl_context;
|
||||
|
||||
@ -30,7 +31,7 @@ static void create_resource_surface(FlRenderer* self, EGLConfig config) {
|
||||
EGL_NONE};
|
||||
priv->resource_surface = eglCreatePbufferSurface(priv->egl_display, config,
|
||||
resource_context_attribs);
|
||||
if (priv->resource_surface == nullptr) {
|
||||
if (priv->resource_surface == EGL_NO_SURFACE) {
|
||||
g_warning("Failed to create EGL resource surface: %s",
|
||||
egl_error_to_string(eglGetError()));
|
||||
return;
|
||||
@ -38,14 +39,16 @@ static void create_resource_surface(FlRenderer* self, EGLConfig config) {
|
||||
|
||||
priv->resource_context = eglCreateContext(
|
||||
priv->egl_display, config, priv->egl_context, context_attributes);
|
||||
if (priv->resource_context == nullptr)
|
||||
if (priv->resource_context == EGL_NO_CONTEXT)
|
||||
g_warning("Failed to create EGL resource context: %s",
|
||||
egl_error_to_string(eglGetError()));
|
||||
}
|
||||
|
||||
// Default implementation for the start virtual method.
|
||||
// Provided so subclasses can chain up to here.
|
||||
static gboolean fl_renderer_real_start(FlRenderer* self, GError** error) {
|
||||
static void fl_renderer_class_init(FlRendererClass* klass) {}
|
||||
|
||||
static void fl_renderer_init(FlRenderer* self) {}
|
||||
|
||||
gboolean fl_renderer_setup(FlRenderer* self, GError** error) {
|
||||
FlRendererPrivate* priv =
|
||||
static_cast<FlRendererPrivate*>(fl_renderer_get_instance_private(self));
|
||||
|
||||
@ -73,71 +76,91 @@ static gboolean fl_renderer_real_start(FlRenderer* self, GError** error) {
|
||||
EGL_ALPHA_SIZE,
|
||||
8,
|
||||
EGL_NONE};
|
||||
EGLConfig egl_config;
|
||||
EGLint n_config;
|
||||
if (!eglChooseConfig(priv->egl_display, attributes, &egl_config, 1,
|
||||
if (!eglChooseConfig(priv->egl_display, attributes, &priv->egl_config, 1,
|
||||
&n_config)) {
|
||||
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
||||
"Failed to choose EGL config: %s",
|
||||
egl_error_to_string(eglGetError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (n_config == 0) {
|
||||
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
||||
"Failed to find appropriate EGL config: %s",
|
||||
egl_error_to_string(eglGetError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!eglBindAPI(EGL_OPENGL_ES_API)) {
|
||||
g_autofree gchar* config_string =
|
||||
egl_config_to_string(priv->egl_display, egl_config);
|
||||
egl_config_to_string(priv->egl_display, priv->egl_config);
|
||||
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
||||
"Failed to bind EGL OpenGL ES API using configuration (%s): %s",
|
||||
config_string, egl_error_to_string(eglGetError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GdkVisual* fl_renderer_get_visual(FlRenderer* self,
|
||||
GdkScreen* screen,
|
||||
GError** error) {
|
||||
FlRendererPrivate* priv =
|
||||
static_cast<FlRendererPrivate*>(fl_renderer_get_instance_private(self));
|
||||
|
||||
EGLint visual_id;
|
||||
if (!eglGetConfigAttrib(priv->egl_display, priv->egl_config,
|
||||
EGL_NATIVE_VISUAL_ID, &visual_id)) {
|
||||
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
||||
"Failed to determine EGL configuration visual");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GdkVisual* visual =
|
||||
FL_RENDERER_GET_CLASS(self)->get_visual(self, screen, visual_id);
|
||||
if (visual == nullptr) {
|
||||
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
||||
"Failed to find visual 0x%x", visual_id);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return visual;
|
||||
}
|
||||
|
||||
gboolean fl_renderer_start(FlRenderer* self, GError** error) {
|
||||
FlRendererPrivate* priv =
|
||||
static_cast<FlRendererPrivate*>(fl_renderer_get_instance_private(self));
|
||||
|
||||
priv->egl_surface = FL_RENDERER_GET_CLASS(self)->create_surface(
|
||||
self, priv->egl_display, egl_config);
|
||||
if (priv->egl_surface == nullptr) {
|
||||
self, priv->egl_display, priv->egl_config);
|
||||
if (priv->egl_surface == EGL_NO_SURFACE) {
|
||||
g_autofree gchar* config_string =
|
||||
egl_config_to_string(priv->egl_display, egl_config);
|
||||
egl_config_to_string(priv->egl_display, priv->egl_config);
|
||||
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
||||
"Failed to create EGL surface using configuration (%s): %s",
|
||||
config_string, egl_error_to_string(eglGetError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EGLint context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
|
||||
priv->egl_context = eglCreateContext(priv->egl_display, egl_config,
|
||||
priv->egl_context = eglCreateContext(priv->egl_display, priv->egl_config,
|
||||
EGL_NO_CONTEXT, context_attributes);
|
||||
if (priv->egl_context == nullptr) {
|
||||
if (priv->egl_context == EGL_NO_CONTEXT) {
|
||||
g_autofree gchar* config_string =
|
||||
egl_config_to_string(priv->egl_display, egl_config);
|
||||
egl_config_to_string(priv->egl_display, priv->egl_config);
|
||||
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
||||
"Failed to create EGL context using configuration (%s): %s",
|
||||
config_string, egl_error_to_string(eglGetError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
create_resource_surface(self, egl_config);
|
||||
|
||||
EGLint value;
|
||||
eglQueryContext(priv->egl_display, priv->egl_context,
|
||||
EGL_CONTEXT_CLIENT_VERSION, &value);
|
||||
create_resource_surface(self, priv->egl_config);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void fl_renderer_class_init(FlRendererClass* klass) {
|
||||
klass->start = fl_renderer_real_start;
|
||||
}
|
||||
|
||||
static void fl_renderer_init(FlRenderer* self) {}
|
||||
|
||||
gboolean fl_renderer_start(FlRenderer* self, GError** error) {
|
||||
return FL_RENDERER_GET_CLASS(self)->start(self, error);
|
||||
}
|
||||
|
||||
void* fl_renderer_get_proc_address(FlRenderer* self, const char* name) {
|
||||
return reinterpret_cast<void*>(eglGetProcAddress(name));
|
||||
}
|
||||
@ -161,7 +184,8 @@ gboolean fl_renderer_make_resource_current(FlRenderer* self, GError** error) {
|
||||
FlRendererPrivate* priv =
|
||||
static_cast<FlRendererPrivate*>(fl_renderer_get_instance_private(self));
|
||||
|
||||
if (priv->resource_surface == nullptr || priv->resource_context == nullptr)
|
||||
if (priv->resource_surface == EGL_NO_SURFACE ||
|
||||
priv->resource_context == EGL_NO_CONTEXT)
|
||||
return FALSE;
|
||||
|
||||
if (!eglMakeCurrent(priv->egl_display, priv->resource_surface,
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
|
||||
|
||||
@ -35,23 +35,51 @@ G_DECLARE_DERIVABLE_TYPE(FlRenderer, fl_renderer, FL, RENDERER, GObject)
|
||||
struct _FlRendererClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
// Virtual method called when Flutter has set up EGL and is ready for the
|
||||
// renderer to start.
|
||||
gboolean (*start)(FlRenderer* renderer, GError** error);
|
||||
// Virtual method called to get the visual that matches the given ID.
|
||||
GdkVisual* (*get_visual)(FlRenderer* renderer,
|
||||
GdkScreen* screen,
|
||||
EGLint visual_id);
|
||||
|
||||
// Virtual method called when flutter needs a surface to render to.
|
||||
// Virtual method called when Flutter needs a surface to render to.
|
||||
EGLSurface (*create_surface)(FlRenderer* renderer,
|
||||
EGLDisplay display,
|
||||
EGLConfig config);
|
||||
};
|
||||
|
||||
/**
|
||||
* fl_renderer_setup:
|
||||
* @renderer: an #FlRenderer.
|
||||
* @error: (allow-none): #GError location to store the error occurring, or %NULL
|
||||
* to ignore.
|
||||
*
|
||||
* Set up the renderer.
|
||||
*
|
||||
* Returns: %TRUE if successfully setup.
|
||||
*/
|
||||
gboolean fl_renderer_setup(FlRenderer* self, GError** error);
|
||||
|
||||
/**
|
||||
* fl_renderer_get_visual:
|
||||
* @renderer: an #FlRenderer.
|
||||
* @screen: the screen being rendered on.
|
||||
* @error: (allow-none): #GError location to store the error occurring, or %NULL
|
||||
* to ignore.
|
||||
*
|
||||
* Gets the visual required to render on.
|
||||
*
|
||||
* Returns: a #GdkVisual.
|
||||
*/
|
||||
GdkVisual* fl_renderer_get_visual(FlRenderer* self,
|
||||
GdkScreen* screen,
|
||||
GError** error);
|
||||
|
||||
/**
|
||||
* fl_renderer_start:
|
||||
* @renderer: an #FlRenderer.
|
||||
* @error: (allow-none): #GError location to store the error occurring, or %NULL
|
||||
* to ignore.
|
||||
*
|
||||
* Start the renderer. EGL must be set up before this call.
|
||||
* Start the renderer.
|
||||
*
|
||||
* Returns: %TRUE if successfully started.
|
||||
*/
|
||||
|
||||
@ -7,19 +7,38 @@
|
||||
struct _FlRendererX11 {
|
||||
FlRenderer parent_instance;
|
||||
|
||||
Window xid;
|
||||
GdkX11Window* window;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlRendererX11, fl_renderer_x11, fl_renderer_get_type())
|
||||
|
||||
static void fl_renderer_x11_dispose(GObject* object) {
|
||||
FlRendererX11* self = FL_RENDERER_X11(object);
|
||||
|
||||
g_clear_object(&self->window);
|
||||
|
||||
G_OBJECT_CLASS(fl_renderer_x11_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
// Implments FlRenderer::get_visual.
|
||||
static GdkVisual* fl_renderer_x11_get_visual(FlRenderer* renderer,
|
||||
GdkScreen* screen,
|
||||
EGLint visual_id) {
|
||||
return gdk_x11_screen_lookup_visual(GDK_X11_SCREEN(screen), visual_id);
|
||||
}
|
||||
|
||||
// Implments FlRenderer::create_surface.
|
||||
static EGLSurface fl_renderer_x11_create_surface(FlRenderer* renderer,
|
||||
EGLDisplay display,
|
||||
EGLConfig config) {
|
||||
FlRendererX11* self = FL_RENDERER_X11(renderer);
|
||||
return eglCreateWindowSurface(display, config, self->xid, nullptr);
|
||||
return eglCreateWindowSurface(display, config,
|
||||
gdk_x11_window_get_xid(self->window), nullptr);
|
||||
}
|
||||
|
||||
static void fl_renderer_x11_class_init(FlRendererX11Class* klass) {
|
||||
G_OBJECT_CLASS(klass)->dispose = fl_renderer_x11_dispose;
|
||||
FL_RENDERER_CLASS(klass)->get_visual = fl_renderer_x11_get_visual;
|
||||
FL_RENDERER_CLASS(klass)->create_surface = fl_renderer_x11_create_surface;
|
||||
}
|
||||
|
||||
@ -29,7 +48,7 @@ FlRendererX11* fl_renderer_x11_new() {
|
||||
return FL_RENDERER_X11(g_object_new(fl_renderer_x11_get_type(), nullptr));
|
||||
}
|
||||
|
||||
void fl_renderer_x11_set_xid(FlRendererX11* self, Window xid) {
|
||||
void fl_renderer_x11_set_window(FlRendererX11* self, GdkX11Window* window) {
|
||||
g_return_if_fail(FL_IS_RENDERER_X11(self));
|
||||
self->xid = xid;
|
||||
self->window = GDK_X11_WINDOW(g_object_ref(window));
|
||||
}
|
||||
|
||||
@ -34,13 +34,13 @@ G_DECLARE_FINAL_TYPE(FlRendererX11,
|
||||
FlRendererX11* fl_renderer_x11_new();
|
||||
|
||||
/**
|
||||
* fl_renderer_x11_set_xid:
|
||||
* fl_renderer_x11_set_window:
|
||||
* @renderer: an #FlRendererX11.
|
||||
* @xid: The X window being rendered to.
|
||||
* @window: the X window being rendered to.
|
||||
*
|
||||
* Sets the X11 window that is being rendered to.
|
||||
*/
|
||||
void fl_renderer_x11_set_xid(FlRendererX11* renderer, Window xid);
|
||||
void fl_renderer_x11_set_window(FlRendererX11* renderer, GdkX11Window* window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@ -202,6 +202,10 @@ static void fl_view_realize(GtkWidget* widget) {
|
||||
|
||||
gtk_widget_set_realized(widget, TRUE);
|
||||
|
||||
g_autoptr(GError) error = nullptr;
|
||||
if (!fl_renderer_setup(FL_RENDERER(self->renderer), &error))
|
||||
g_warning("Failed to setup renderer: %s", error->message);
|
||||
|
||||
GtkAllocation allocation;
|
||||
gtk_widget_get_allocation(widget, &allocation);
|
||||
|
||||
@ -212,7 +216,8 @@ static void fl_view_realize(GtkWidget* widget) {
|
||||
window_attributes.width = allocation.width;
|
||||
window_attributes.height = allocation.height;
|
||||
window_attributes.wclass = GDK_INPUT_OUTPUT;
|
||||
window_attributes.visual = gtk_widget_get_visual(widget);
|
||||
window_attributes.visual = fl_renderer_get_visual(
|
||||
FL_RENDERER(self->renderer), gtk_widget_get_screen(widget), nullptr);
|
||||
window_attributes.event_mask =
|
||||
gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK |
|
||||
GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK |
|
||||
@ -227,10 +232,9 @@ static void fl_view_realize(GtkWidget* widget) {
|
||||
gtk_widget_register_window(widget, window);
|
||||
gtk_widget_set_window(widget, window);
|
||||
|
||||
Window xid = gdk_x11_window_get_xid(gtk_widget_get_window(GTK_WIDGET(self)));
|
||||
fl_renderer_x11_set_xid(self->renderer, xid);
|
||||
fl_renderer_x11_set_window(
|
||||
self->renderer, GDK_X11_WINDOW(gtk_widget_get_window(GTK_WIDGET(self))));
|
||||
|
||||
g_autoptr(GError) error = nullptr;
|
||||
if (!fl_engine_start(self->engine, &error))
|
||||
g_warning("Failed to start Flutter engine: %s", error->message);
|
||||
}
|
||||
|
||||
@ -35,11 +35,19 @@ typedef struct {
|
||||
} MockConfig;
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
MockConfig config;
|
||||
} MockDisplay;
|
||||
|
||||
typedef struct {
|
||||
} MockContext;
|
||||
|
||||
typedef struct {
|
||||
} MockSurface;
|
||||
|
||||
static bool display_initialized = false;
|
||||
static MockDisplay mock_display;
|
||||
static MockConfig mock_config;
|
||||
static MockContext mock_context;
|
||||
static MockSurface mock_surface;
|
||||
|
||||
static EGLint mock_error = EGL_SUCCESS;
|
||||
|
||||
@ -49,8 +57,11 @@ static bool check_display(EGLDisplay dpy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MockDisplay* display = static_cast<MockDisplay*>(dpy);
|
||||
if (!display->initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_initialized(EGLDisplay dpy) {
|
||||
if (!display_initialized) {
|
||||
mock_error = EGL_NOT_INITIALIZED;
|
||||
return false;
|
||||
}
|
||||
@ -86,7 +97,8 @@ EGLBoolean eglChooseConfig(EGLDisplay dpy,
|
||||
EGLConfig* configs,
|
||||
EGLint config_size,
|
||||
EGLint* num_config) {
|
||||
MockDisplay* display = static_cast<MockDisplay*>(dpy);
|
||||
if (!check_display(dpy) || !check_initialized(dpy))
|
||||
return EGL_FALSE;
|
||||
|
||||
if (configs == nullptr) {
|
||||
if (num_config != nullptr)
|
||||
@ -96,7 +108,8 @@ EGLBoolean eglChooseConfig(EGLDisplay dpy,
|
||||
|
||||
EGLint n_returned = 0;
|
||||
if (config_size >= 1) {
|
||||
configs[0] = &display->config;
|
||||
configs[0] = &mock_config;
|
||||
n_returned++;
|
||||
}
|
||||
|
||||
if (num_config != nullptr)
|
||||
@ -109,39 +122,39 @@ EGLContext eglCreateContext(EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
EGLContext share_context,
|
||||
const EGLint* attrib_list) {
|
||||
if (!check_display(dpy) || !check_config(config))
|
||||
if (!check_display(dpy) || !check_initialized(dpy) || !check_config(config))
|
||||
return EGL_NO_CONTEXT;
|
||||
|
||||
mock_error = EGL_SUCCESS;
|
||||
return EGL_NO_CONTEXT;
|
||||
return &mock_context;
|
||||
}
|
||||
|
||||
EGLSurface eglCreatePbufferSurface(EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
const EGLint* attrib_list) {
|
||||
if (!check_display(dpy) || !check_config(config))
|
||||
if (!check_display(dpy) || !check_initialized(dpy) || !check_config(config))
|
||||
return EGL_NO_SURFACE;
|
||||
|
||||
mock_error = EGL_SUCCESS;
|
||||
return EGL_NO_SURFACE;
|
||||
return &mock_surface;
|
||||
}
|
||||
|
||||
EGLSurface eglCreateWindowSurface(EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
EGLNativeWindowType win,
|
||||
const EGLint* attrib_list) {
|
||||
if (!check_display(dpy) || !check_config(config))
|
||||
if (!check_display(dpy) || !check_initialized(dpy) || !check_config(config))
|
||||
return EGL_NO_SURFACE;
|
||||
|
||||
mock_error = EGL_SUCCESS;
|
||||
return EGL_NO_SURFACE;
|
||||
return &mock_surface;
|
||||
}
|
||||
|
||||
EGLBoolean eglGetConfigAttrib(EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
EGLint attribute,
|
||||
EGLint* value) {
|
||||
if (!check_display(dpy) || !check_config(config))
|
||||
if (!check_display(dpy) || !check_initialized(dpy) || !check_config(config))
|
||||
return EGL_FALSE;
|
||||
|
||||
MockConfig* c = static_cast<MockConfig*>(config);
|
||||
@ -248,38 +261,38 @@ void (*eglGetProcAddress(const char* procname))(void) {
|
||||
}
|
||||
|
||||
EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) {
|
||||
MockDisplay* display = static_cast<MockDisplay*>(dpy);
|
||||
if (!check_display(dpy))
|
||||
return EGL_FALSE;
|
||||
|
||||
if (!display->initialized) {
|
||||
MockConfig* c = &display->config;
|
||||
c->config_id = 1;
|
||||
c->buffer_size = 32;
|
||||
c->color_buffer_type = EGL_RGB_BUFFER;
|
||||
c->transparent_type = EGL_NONE;
|
||||
c->level = 1;
|
||||
c->red_size = 8;
|
||||
c->green_size = 8;
|
||||
c->blue_size = 8;
|
||||
c->alpha_size = 0;
|
||||
c->depth_size = 0;
|
||||
c->stencil_size = 0;
|
||||
c->samples = 0;
|
||||
c->sample_buffers = 0;
|
||||
c->native_visual_id = 1;
|
||||
c->native_visual_type = 0;
|
||||
c->native_renderable = EGL_TRUE;
|
||||
c->config_caveat = EGL_NONE;
|
||||
c->bind_to_texture_rgb = EGL_TRUE;
|
||||
c->bind_to_texture_rgba = EGL_FALSE;
|
||||
c->renderable_type = EGL_OPENGL_ES2_BIT;
|
||||
c->conformant = EGL_OPENGL_ES2_BIT;
|
||||
c->surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
|
||||
c->max_pbuffer_width = 1024;
|
||||
c->max_pbuffer_height = 1024;
|
||||
c->max_pbuffer_pixels = 1024 * 1024;
|
||||
c->min_swap_interval = 0;
|
||||
c->max_swap_interval = 1000;
|
||||
display->initialized = true;
|
||||
if (!display_initialized) {
|
||||
mock_config.config_id = 1;
|
||||
mock_config.buffer_size = 32;
|
||||
mock_config.color_buffer_type = EGL_RGB_BUFFER;
|
||||
mock_config.transparent_type = EGL_NONE;
|
||||
mock_config.level = 1;
|
||||
mock_config.red_size = 8;
|
||||
mock_config.green_size = 8;
|
||||
mock_config.blue_size = 8;
|
||||
mock_config.alpha_size = 0;
|
||||
mock_config.depth_size = 0;
|
||||
mock_config.stencil_size = 0;
|
||||
mock_config.samples = 0;
|
||||
mock_config.sample_buffers = 0;
|
||||
mock_config.native_visual_id = 1;
|
||||
mock_config.native_visual_type = 0;
|
||||
mock_config.native_renderable = EGL_TRUE;
|
||||
mock_config.config_caveat = EGL_NONE;
|
||||
mock_config.bind_to_texture_rgb = EGL_TRUE;
|
||||
mock_config.bind_to_texture_rgba = EGL_FALSE;
|
||||
mock_config.renderable_type = EGL_OPENGL_ES2_BIT;
|
||||
mock_config.conformant = EGL_OPENGL_ES2_BIT;
|
||||
mock_config.surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
|
||||
mock_config.max_pbuffer_width = 1024;
|
||||
mock_config.max_pbuffer_height = 1024;
|
||||
mock_config.max_pbuffer_pixels = 1024 * 1024;
|
||||
mock_config.min_swap_interval = 0;
|
||||
mock_config.max_swap_interval = 1000;
|
||||
display_initialized = true;
|
||||
}
|
||||
|
||||
if (major != nullptr)
|
||||
@ -294,24 +307,14 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy,
|
||||
EGLSurface draw,
|
||||
EGLSurface read,
|
||||
EGLContext ctx) {
|
||||
if (!check_display(dpy))
|
||||
return EGL_FALSE;
|
||||
|
||||
return bool_success();
|
||||
}
|
||||
|
||||
EGLBoolean eglQueryContext(EGLDisplay dpy,
|
||||
EGLContext ctx,
|
||||
EGLint attribute,
|
||||
EGLint* value) {
|
||||
if (!check_display(dpy))
|
||||
if (!check_display(dpy) || !check_initialized(dpy))
|
||||
return EGL_FALSE;
|
||||
|
||||
return bool_success();
|
||||
}
|
||||
|
||||
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
|
||||
if (!check_display(dpy))
|
||||
if (!check_display(dpy) || !check_initialized(dpy))
|
||||
return EGL_FALSE;
|
||||
|
||||
return bool_success();
|
||||
|
||||
@ -10,13 +10,23 @@ struct _FlMockRenderer {
|
||||
|
||||
G_DEFINE_TYPE(FlMockRenderer, fl_mock_renderer, fl_renderer_get_type())
|
||||
|
||||
// Implements FlRenderer::start
|
||||
static gboolean fl_mock_renderer_start(FlRenderer* renderer, GError** error) {
|
||||
return TRUE;
|
||||
// Implements FlRenderer::get_visual.
|
||||
static GdkVisual* fl_mock_renderer_get_visual(FlRenderer* renderer,
|
||||
GdkScreen* screen,
|
||||
EGLint visual_id) {
|
||||
return static_cast<GdkVisual*>(g_object_new(GDK_TYPE_VISUAL, nullptr));
|
||||
}
|
||||
|
||||
// Implements FlRenderer::create_surface.
|
||||
static EGLSurface fl_mock_renderer_create_surface(FlRenderer* renderer,
|
||||
EGLDisplay display,
|
||||
EGLConfig config) {
|
||||
return eglCreateWindowSurface(display, config, 0, nullptr);
|
||||
}
|
||||
|
||||
static void fl_mock_renderer_class_init(FlMockRendererClass* klass) {
|
||||
FL_RENDERER_CLASS(klass)->start = fl_mock_renderer_start;
|
||||
FL_RENDERER_CLASS(klass)->get_visual = fl_mock_renderer_get_visual;
|
||||
FL_RENDERER_CLASS(klass)->create_surface = fl_mock_renderer_create_surface;
|
||||
}
|
||||
|
||||
static void fl_mock_renderer_init(FlMockRenderer* self) {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user