forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfl_framebuffer.cc
112 lines (85 loc) · 3.33 KB
/
fl_framebuffer.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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 "fl_framebuffer.h"
#include <epoxy/gl.h>
struct _FlFramebuffer {
GObject parent_instance;
// Width of framebuffer in pixels.
size_t width;
// Height of framebuffer in pixels.
size_t height;
// Framebuffer ID.
GLuint framebuffer_id;
// Texture backing framebuffer.
GLuint texture_id;
};
G_DEFINE_TYPE(FlFramebuffer, fl_framebuffer, G_TYPE_OBJECT)
static void fl_framebuffer_dispose(GObject* object) {
FlFramebuffer* self = FL_FRAMEBUFFER(object);
glDeleteFramebuffers(1, &self->framebuffer_id);
glDeleteTextures(1, &self->texture_id);
G_OBJECT_CLASS(fl_framebuffer_parent_class)->dispose(object);
}
static void fl_framebuffer_class_init(FlFramebufferClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_framebuffer_dispose;
}
static void fl_framebuffer_init(FlFramebuffer* self) {}
FlFramebuffer* fl_framebuffer_new(size_t width, size_t height) {
FlFramebuffer* provider =
FL_FRAMEBUFFER(g_object_new(fl_framebuffer_get_type(), nullptr));
provider->width = width;
provider->height = height;
glGenTextures(1, &provider->texture_id);
glGenFramebuffers(1, &provider->framebuffer_id);
glBindFramebuffer(GL_FRAMEBUFFER, provider->framebuffer_id);
glBindTexture(GL_TEXTURE_2D, provider->texture_id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, provider->texture_id, 0);
return provider;
}
GLuint fl_framebuffer_get_id(FlFramebuffer* self) {
return self->framebuffer_id;
}
GLuint fl_framebuffer_get_texture_id(FlFramebuffer* self) {
return self->texture_id;
}
GLenum fl_framebuffer_get_target(FlFramebuffer* self) {
return GL_TEXTURE_2D;
}
GLenum fl_framebuffer_get_format(FlFramebuffer* self) {
// Flutter defines SK_R32_SHIFT=16, so SK_PMCOLOR_BYTE_ORDER should be BGRA.
// In Linux kN32_SkColorType is assumed to be kBGRA_8888_SkColorType.
// So we must choose a valid gl format to be compatible with surface format
// BGRA8.
// Following logic is copied from Skia GrGLCaps.cpp:
// https://github.com/google/skia/blob/4738ed711e03212aceec3cd502a4adb545f38e63/src/gpu/ganesh/gl/GrGLCaps.cpp#L1963-L2116
if (epoxy_is_desktop_gl()) {
// For OpenGL.
if (epoxy_gl_version() >= 12 || epoxy_has_gl_extension("GL_EXT_bgra")) {
return GL_RGBA8;
}
} else {
// For OpenGL ES.
if (epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888") ||
(epoxy_has_gl_extension("GL_APPLE_texture_format_BGRA8888") &&
epoxy_gl_version() >= 30)) {
return GL_BGRA8_EXT;
}
}
g_critical("Failed to determine valid GL format for Flutter rendering");
return GL_RGBA8;
}
size_t fl_framebuffer_get_width(FlFramebuffer* self) {
return self->width;
}
size_t fl_framebuffer_get_height(FlFramebuffer* self) {
return self->height;
}