mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Save and restore OpenGL bindings that are changed by fl_renderer_render (flutter/engine#51887)
fl_renderer_render uses the raster thread GL context that is also used by Skia. Skia expects that its bindings have not been changed elsewhere.
This commit is contained in:
parent
b1030afadd
commit
e5d0cae6cd
@ -41986,6 +41986,7 @@ ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer_gdk.cc + ../../../flut
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer_gdk.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer_headless.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer_headless.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer_test.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager_test.cc + ../../../flutter/LICENSE
|
||||
@ -44897,6 +44898,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_renderer_gdk.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_renderer_gdk.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_renderer_headless.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_renderer_headless.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_renderer_test.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager_test.cc
|
||||
|
||||
@ -213,6 +213,7 @@ executable("flutter_linux_unittests") {
|
||||
"fl_pixel_buffer_texture_test.cc",
|
||||
"fl_platform_plugin_test.cc",
|
||||
"fl_plugin_registrar_test.cc",
|
||||
"fl_renderer_test.cc",
|
||||
"fl_scrolling_manager_test.cc",
|
||||
"fl_settings_plugin_test.cc",
|
||||
"fl_settings_portal_test.cc",
|
||||
|
||||
@ -314,6 +314,16 @@ void fl_renderer_render(FlRenderer* self, int width, int height) {
|
||||
|
||||
g_return_if_fail(FL_IS_RENDERER(self));
|
||||
|
||||
// Save bindings that are set by this function. All bindings must be restored
|
||||
// to their original values because Skia expects that its bindings have not
|
||||
// been altered.
|
||||
GLint saved_texture_binding;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
|
||||
GLint saved_vao_binding;
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &saved_vao_binding);
|
||||
GLint saved_array_buffer_binding;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
@ -364,6 +374,10 @@ void fl_renderer_render(FlRenderer* self, int width, int height) {
|
||||
}
|
||||
|
||||
glFlush();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
|
||||
glBindVertexArray(saved_vao_binding);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding);
|
||||
}
|
||||
|
||||
void fl_renderer_cleanup(FlRenderer* self) {
|
||||
|
||||
53
engine/src/flutter/shell/platform/linux/fl_renderer_test.cc
Normal file
53
engine/src/flutter/shell/platform/linux/fl_renderer_test.cc
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "flutter/shell/platform/linux/fl_backing_store_provider.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_test_gtk_logs.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_renderer.h"
|
||||
|
||||
TEST(FlRendererTest, RestoresGLState) {
|
||||
constexpr int kWidth = 100;
|
||||
constexpr int kHeight = 100;
|
||||
|
||||
flutter::testing::fl_ensure_gtk_init();
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
g_autoptr(FlView) view = fl_view_new(project);
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
g_autoptr(FlBackingStoreProvider) backing_store_provider =
|
||||
fl_backing_store_provider_new(kWidth, kHeight);
|
||||
|
||||
fl_renderer_start(FL_RENDERER(renderer), view);
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), kWidth, kHeight);
|
||||
|
||||
FlutterBackingStore backing_store;
|
||||
backing_store.type = kFlutterBackingStoreTypeOpenGL;
|
||||
backing_store.open_gl.framebuffer.user_data = backing_store_provider;
|
||||
|
||||
FlutterLayer layer;
|
||||
layer.type = kFlutterLayerContentTypeBackingStore;
|
||||
layer.backing_store = &backing_store;
|
||||
layer.offset = {0, 0};
|
||||
layer.size = {kWidth, kHeight};
|
||||
|
||||
std::array<const FlutterLayer*, 1> layers = {&layer};
|
||||
|
||||
constexpr GLuint kFakeTextureName = 123;
|
||||
glBindTexture(GL_TEXTURE_2D, kFakeTextureName);
|
||||
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), layers.data(),
|
||||
layers.size());
|
||||
fl_renderer_render(FL_RENDERER(renderer), kWidth, kHeight);
|
||||
|
||||
GLuint texture_2d_binding;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D,
|
||||
reinterpret_cast<GLint*>(&texture_2d_binding));
|
||||
EXPECT_EQ(texture_2d_binding, kFakeTextureName);
|
||||
|
||||
g_object_ref_sink(view);
|
||||
}
|
||||
@ -325,6 +325,16 @@ EGLBoolean _eglMakeCurrent(EGLDisplay dpy,
|
||||
|
||||
return bool_success();
|
||||
}
|
||||
EGLBoolean _eglQueryContext(EGLDisplay display,
|
||||
EGLContext context,
|
||||
EGLint attribute,
|
||||
EGLint* value) {
|
||||
if (attribute == EGL_CONTEXT_CLIENT_TYPE) {
|
||||
*value = EGL_OPENGL_API;
|
||||
return EGL_TRUE;
|
||||
}
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
EGLBoolean _eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
|
||||
if (!check_display(dpy) || !check_initialized(dpy)) {
|
||||
@ -334,9 +344,15 @@ EGLBoolean _eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
|
||||
return bool_success();
|
||||
}
|
||||
|
||||
static GLuint bound_texture_2d;
|
||||
|
||||
static void _glBindFramebuffer(GLenum target, GLuint framebuffer) {}
|
||||
|
||||
static void _glBindTexture(GLenum target, GLuint texture) {}
|
||||
static void _glBindTexture(GLenum target, GLuint texture) {
|
||||
if (target == GL_TEXTURE_2D) {
|
||||
bound_texture_2d = texture;
|
||||
}
|
||||
}
|
||||
|
||||
void _glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {}
|
||||
|
||||
@ -360,6 +376,12 @@ static void _glGenFramebuffers(GLsizei n, GLuint* framebuffers) {
|
||||
}
|
||||
}
|
||||
|
||||
static void _glGetIntegerv(GLenum pname, GLint* data) {
|
||||
if (pname == GL_TEXTURE_BINDING_2D) {
|
||||
*data = bound_texture_2d;
|
||||
}
|
||||
}
|
||||
|
||||
static void _glTexParameterf(GLenum target, GLenum pname, GLfloat param) {}
|
||||
|
||||
static void _glTexParameteri(GLenum target, GLenum pname, GLint param) {}
|
||||
@ -477,6 +499,7 @@ static void library_init() {
|
||||
epoxy_eglGetProcAddress = _eglGetProcAddress;
|
||||
epoxy_eglInitialize = _eglInitialize;
|
||||
epoxy_eglMakeCurrent = _eglMakeCurrent;
|
||||
epoxy_eglQueryContext = _eglQueryContext;
|
||||
epoxy_eglSwapBuffers = _eglSwapBuffers;
|
||||
|
||||
epoxy_glBindFramebuffer = _glBindFramebuffer;
|
||||
@ -486,6 +509,7 @@ static void library_init() {
|
||||
epoxy_glFramebufferTexture2D = _glFramebufferTexture2D;
|
||||
epoxy_glGenFramebuffers = _glGenFramebuffers;
|
||||
epoxy_glGenTextures = _glGenTextures;
|
||||
epoxy_glGetIntegerv = _glGetIntegerv;
|
||||
epoxy_glTexParameterf = _glTexParameterf;
|
||||
epoxy_glTexParameteri = _glTexParameteri;
|
||||
epoxy_glTexImage2D = _glTexImage2D;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user