mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Allow the default background color to be changed (flutter/engine#54575)
Fixes https://github.com/flutter/flutter/issues/149920
This commit is contained in:
parent
11288f546d
commit
2bbc3b4b41
@ -195,6 +195,9 @@ static void render_with_textures(FlRenderer* self, int width, int height) {
|
||||
GLint saved_array_buffer_binding;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(priv->program);
|
||||
|
||||
for (guint i = 0; i < priv->framebuffers->len; i++) {
|
||||
@ -236,6 +239,8 @@ static void render_with_textures(FlRenderer* self, int width, int height) {
|
||||
glDeleteBuffers(1, &vertex_buffer);
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
|
||||
glBindVertexArray(saved_vao_binding);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding);
|
||||
@ -443,13 +448,17 @@ void fl_renderer_setup(FlRenderer* self) {
|
||||
}
|
||||
}
|
||||
|
||||
void fl_renderer_render(FlRenderer* self, int width, int height) {
|
||||
void fl_renderer_render(FlRenderer* self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkRGBA* background_color) {
|
||||
FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
|
||||
fl_renderer_get_instance_private(self));
|
||||
|
||||
g_return_if_fail(FL_IS_RENDERER(self));
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClearColor(background_color->red, background_color->green,
|
||||
background_color->blue, background_color->alpha);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (priv->has_gl_framebuffer_blit) {
|
||||
|
||||
@ -209,10 +209,14 @@ void fl_renderer_setup(FlRenderer* renderer);
|
||||
* @renderer: an #FlRenderer.
|
||||
* @width: width of the window in pixels.
|
||||
* @height: height of the window in pixels.
|
||||
* @background_color: color to use for background.
|
||||
*
|
||||
* Performs OpenGL commands to render current Flutter view.
|
||||
*/
|
||||
void fl_renderer_render(FlRenderer* renderer, int width, int height);
|
||||
void fl_renderer_render(FlRenderer* renderer,
|
||||
int width,
|
||||
int height,
|
||||
const GdkRGBA* background_color);
|
||||
|
||||
/**
|
||||
* fl_renderer_cleanup:
|
||||
|
||||
@ -12,6 +12,36 @@
|
||||
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
TEST(FlRendererTest, BackgroundColor) {
|
||||
::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
|
||||
|
||||
ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
|
||||
EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
|
||||
ON_CALL(epoxy, glGetString(GL_VENDOR))
|
||||
.WillByDefault(
|
||||
::testing::Return(reinterpret_cast<const GLubyte*>("Intel")));
|
||||
EXPECT_CALL(epoxy, glClearColor(0.2, 0.3, 0.4, 0.5));
|
||||
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
.struct_size = sizeof(FlutterBackingStoreConfig),
|
||||
.size = {.width = 1024, .height = 1024}};
|
||||
FlutterBackingStore backing_store;
|
||||
fl_renderer_create_backing_store(FL_RENDERER(renderer), &config,
|
||||
&backing_store);
|
||||
const FlutterLayer layer0 = {.struct_size = sizeof(FlutterLayer),
|
||||
.type = kFlutterLayerContentTypeBackingStore,
|
||||
.backing_store = &backing_store,
|
||||
.size = {.width = 1024, .height = 1024}};
|
||||
const FlutterLayer* layers[] = {&layer0};
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
|
||||
GdkRGBA background_color = {
|
||||
.red = 0.2, .green = 0.3, .blue = 0.4, .alpha = 0.5};
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024, &background_color);
|
||||
}
|
||||
|
||||
TEST(FlRendererTest, RestoresGLState) {
|
||||
::testing::NiceMock<flutter::testing::MockEpoxy> epoxy;
|
||||
|
||||
@ -44,7 +74,9 @@ TEST(FlRendererTest, RestoresGLState) {
|
||||
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers.data(),
|
||||
layers.size());
|
||||
fl_renderer_render(FL_RENDERER(renderer), kWidth, kHeight);
|
||||
GdkRGBA background_color = {
|
||||
.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||
fl_renderer_render(FL_RENDERER(renderer), kWidth, kHeight, &background_color);
|
||||
|
||||
GLuint texture_2d_binding;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D,
|
||||
@ -82,8 +114,7 @@ TEST(FlRendererTest, BlitFramebuffer) {
|
||||
|
||||
EXPECT_CALL(epoxy, glBlitFramebuffer);
|
||||
|
||||
g_autoptr(FlMockRenderer) renderer =
|
||||
fl_mock_renderer_new(&renderer_get_refresh_rate);
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
@ -98,7 +129,9 @@ TEST(FlRendererTest, BlitFramebuffer) {
|
||||
.size = {.width = 1024, .height = 1024}};
|
||||
const FlutterLayer* layers[] = {&layer0};
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024);
|
||||
GdkRGBA background_color = {
|
||||
.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024, &background_color);
|
||||
}
|
||||
|
||||
TEST(FlRendererTest, BlitFramebufferExtension) {
|
||||
@ -116,8 +149,7 @@ TEST(FlRendererTest, BlitFramebufferExtension) {
|
||||
|
||||
EXPECT_CALL(epoxy, glBlitFramebuffer);
|
||||
|
||||
g_autoptr(FlMockRenderer) renderer =
|
||||
fl_mock_renderer_new(&renderer_get_refresh_rate);
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
@ -132,7 +164,9 @@ TEST(FlRendererTest, BlitFramebufferExtension) {
|
||||
.size = {.width = 1024, .height = 1024}};
|
||||
const FlutterLayer* layers[] = {&layer0};
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024);
|
||||
GdkRGBA background_color = {
|
||||
.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024, &background_color);
|
||||
}
|
||||
|
||||
TEST(FlRendererTest, NoBlitFramebuffer) {
|
||||
@ -145,8 +179,7 @@ TEST(FlRendererTest, NoBlitFramebuffer) {
|
||||
ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
|
||||
EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20));
|
||||
|
||||
g_autoptr(FlMockRenderer) renderer =
|
||||
fl_mock_renderer_new(&renderer_get_refresh_rate);
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
@ -161,7 +194,9 @@ TEST(FlRendererTest, NoBlitFramebuffer) {
|
||||
.size = {.width = 1024, .height = 1024}};
|
||||
const FlutterLayer* layers[] = {&layer0};
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024);
|
||||
GdkRGBA background_color = {
|
||||
.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024, &background_color);
|
||||
}
|
||||
|
||||
TEST(FlRendererTest, BlitFramebufferNvidia) {
|
||||
@ -175,8 +210,7 @@ TEST(FlRendererTest, BlitFramebufferNvidia) {
|
||||
ON_CALL(epoxy, epoxy_is_desktop_gl).WillByDefault(::testing::Return(true));
|
||||
EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30));
|
||||
|
||||
g_autoptr(FlMockRenderer) renderer =
|
||||
fl_mock_renderer_new(&renderer_get_refresh_rate);
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
@ -191,5 +225,7 @@ TEST(FlRendererTest, BlitFramebufferNvidia) {
|
||||
.size = {.width = 1024, .height = 1024}};
|
||||
const FlutterLayer* layers[] = {&layer0};
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1);
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024);
|
||||
GdkRGBA background_color = {
|
||||
.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||
fl_renderer_render(FL_RENDERER(renderer), 1024, 1024, &background_color);
|
||||
}
|
||||
|
||||
@ -46,6 +46,9 @@ struct _FlView {
|
||||
// Rendering output.
|
||||
FlRendererGdk* renderer;
|
||||
|
||||
// Background color.
|
||||
GdkRGBA* background_color;
|
||||
|
||||
// Pointer button state recorded for sending status updates.
|
||||
int64_t button_state;
|
||||
|
||||
@ -607,7 +610,7 @@ static gboolean render_cb(FlView* self, GdkGLContext* context) {
|
||||
int height = gtk_widget_get_allocated_height(GTK_WIDGET(self->gl_area));
|
||||
gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self->gl_area));
|
||||
fl_renderer_render(FL_RENDERER(self->renderer), width * scale_factor,
|
||||
height * scale_factor);
|
||||
height * scale_factor, self->background_color);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -654,6 +657,7 @@ static void fl_view_dispose(GObject* object) {
|
||||
|
||||
g_clear_object(&self->engine);
|
||||
g_clear_object(&self->renderer);
|
||||
g_clear_pointer(&self->background_color, gdk_rgba_free);
|
||||
g_clear_object(&self->window_state_monitor);
|
||||
g_clear_object(&self->scrolling_manager);
|
||||
g_clear_object(&self->keyboard_handler);
|
||||
@ -706,6 +710,10 @@ static void fl_view_init(FlView* self) {
|
||||
// https://github.com/flutter/flutter/issues/138178
|
||||
self->view_id = flutter::kFlutterImplicitViewId;
|
||||
|
||||
GdkRGBA default_background = {
|
||||
.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||
self->background_color = gdk_rgba_copy(&default_background);
|
||||
|
||||
self->event_box = gtk_event_box_new();
|
||||
gtk_widget_set_hexpand(self->event_box, TRUE);
|
||||
gtk_widget_set_vexpand(self->event_box, TRUE);
|
||||
@ -743,6 +751,7 @@ static void fl_view_init(FlView* self) {
|
||||
self);
|
||||
|
||||
self->gl_area = GTK_GL_AREA(gtk_gl_area_new());
|
||||
gtk_gl_area_set_has_alpha(self->gl_area, TRUE);
|
||||
gtk_widget_show(GTK_WIDGET(self->gl_area));
|
||||
gtk_container_add(GTK_CONTAINER(self->event_box), GTK_WIDGET(self->gl_area));
|
||||
|
||||
@ -785,6 +794,13 @@ G_MODULE_EXPORT FlEngine* fl_view_get_engine(FlView* self) {
|
||||
return self->engine;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void fl_view_set_background_color(FlView* self,
|
||||
const GdkRGBA* color) {
|
||||
g_return_if_fail(FL_IS_VIEW(self));
|
||||
gdk_rgba_free(self->background_color);
|
||||
self->background_color = gdk_rgba_copy(color);
|
||||
}
|
||||
|
||||
void fl_view_redraw(FlView* self) {
|
||||
g_return_if_fail(FL_IS_VIEW(self));
|
||||
gtk_widget_queue_draw(GTK_WIDGET(self->gl_area));
|
||||
|
||||
@ -69,6 +69,15 @@ FlView* fl_view_new_for_engine(FlEngine* engine);
|
||||
*/
|
||||
FlEngine* fl_view_get_engine(FlView* view);
|
||||
|
||||
/**
|
||||
* fl_view_set_background_color:
|
||||
* @view: an #FlView.
|
||||
* @color: a background color.
|
||||
*
|
||||
* Set the background color for Flutter (defaults to black).
|
||||
*/
|
||||
void fl_view_set_background_color(FlView* view, const GdkRGBA* color);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_PUBLIC_FLUTTER_LINUX_FL_VIEW_H_
|
||||
|
||||
@ -382,6 +382,10 @@ GLuint _glCreateProgram() {
|
||||
|
||||
void _glCompileShader(GLuint shader) {}
|
||||
|
||||
void _glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||
mock->glClearColor(r, g, b, a);
|
||||
}
|
||||
|
||||
GLuint _glCreateShader(GLenum shaderType) {
|
||||
return 0;
|
||||
}
|
||||
@ -594,6 +598,7 @@ static void library_init() {
|
||||
epoxy_glBindTexture = _glBindTexture;
|
||||
epoxy_glBlitFramebuffer = _glBlitFramebuffer;
|
||||
epoxy_glCompileShader = _glCompileShader;
|
||||
epoxy_glClearColor = _glClearColor;
|
||||
epoxy_glCreateProgram = _glCreateProgram;
|
||||
epoxy_glCreateShader = _glCreateShader;
|
||||
epoxy_glDeleteFramebuffers = _glDeleteFramebuffers;
|
||||
|
||||
@ -20,6 +20,7 @@ class MockEpoxy {
|
||||
MOCK_METHOD(bool, epoxy_has_gl_extension, (const char* extension));
|
||||
MOCK_METHOD(bool, epoxy_is_desktop_gl, ());
|
||||
MOCK_METHOD(int, epoxy_gl_version, ());
|
||||
MOCK_METHOD(void, glClearColor, (GLfloat r, GLfloat g, GLfloat b, GLfloat a));
|
||||
MOCK_METHOD(void,
|
||||
glBlitFramebuffer,
|
||||
(GLint srcX0,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user